serial: sccnxp: Disable regulator on error
authorAlexander Shiyan <shc_work@mail.ru>
Wed, 31 Jul 2013 10:56:29 +0000 (14:56 +0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Aug 2013 01:08:01 +0000 (18:08 -0700)
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>
drivers/tty/serial/sccnxp.c

index 98555179fe10df2ce2ea20b89c22295395a8f028..12a5c265f43af764138f43061f359a9a616d37e8 100644 (file)
@@ -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;
 }