summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/sccnxp.c
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2013-07-31 14:56:29 +0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-01 05:08:01 +0400
commite087ab74f3dd30105041e1c68db209f235b63042 (patch)
treeba3ba6f1460bea74f234b7b408e64192b917668c /drivers/tty/serial/sccnxp.c
parent3fc1eb5fe5318d3eff9938240c29cc6ce2d6ce4e (diff)
downloadlinux-e087ab74f3dd30105041e1c68db209f235b63042.tar.xz
serial: sccnxp: Disable regulator on error
The patch disables the regulator in case of errors, if we have it. In addition, the patch adds support for deferred regulator probe and makes error path are a bit clean. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/sccnxp.c')
-rw-r--r--drivers/tty/serial/sccnxp.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c
index 98555179fe10..12a5c265f43a 100644
--- a/drivers/tty/serial/sccnxp.c
+++ b/drivers/tty/serial/sccnxp.c
@@ -787,10 +787,9 @@ static int sccnxp_probe(struct platform_device *pdev)
struct sccnxp_port *s;
void __iomem *membase;
- if (!res) {
- dev_err(&pdev->dev, "Missing memory resource data\n");
- return -EADDRNOTAVAIL;
- }
+ membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(membase))
+ return PTR_ERR(membase);
s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL);
if (!s) {
@@ -885,10 +884,20 @@ static int sccnxp_probe(struct platform_device *pdev)
break;
default:
dev_err(&pdev->dev, "Unsupported chip type %i\n", chiptype);
- ret = -ENOTSUPP;
- goto err_out;
+ return -ENOTSUPP;
}
+ s->regulator = devm_regulator_get(&pdev->dev, "vcc");
+ if (!IS_ERR(s->regulator)) {
+ ret = regulator_enable(s->regulator);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed to enable regulator: %i\n", ret);
+ return ret;
+ }
+ } else if (PTR_ERR(s->regulator) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
if (!pdata) {
dev_warn(&pdev->dev,
"No platform data supplied, using defaults\n");
@@ -919,22 +928,6 @@ static int sccnxp_probe(struct platform_device *pdev)
goto err_out;
}
- s->regulator = devm_regulator_get(&pdev->dev, "VCC");
- if (!IS_ERR(s->regulator)) {
- ret = regulator_enable(s->regulator);
- if (ret) {
- dev_err(&pdev->dev,
- "Failed to enable regulator: %i\n", ret);
- return ret;
- }
- }
-
- membase = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(membase)) {
- ret = PTR_ERR(membase);
- goto err_out;
- }
-
s->uart.owner = THIS_MODULE;
s->uart.dev_name = "ttySC";
s->uart.major = SCCNXP_MAJOR;
@@ -997,6 +990,9 @@ static int sccnxp_probe(struct platform_device *pdev)
}
err_out:
+ if (!IS_ERR(s->regulator))
+ return regulator_disable(s->regulator);
+
return ret;
}