瀏覽代碼

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>
Alexander Shiyan 12 年之前
父節點
當前提交
e087ab74f3
共有 1 個文件被更改,包括 18 次插入22 次删除
  1. 18 22
      drivers/tty/serial/sccnxp.c

+ 18 - 22
drivers/tty/serial/sccnxp.c

@@ -787,10 +787,9 @@ static int sccnxp_probe(struct platform_device *pdev)
 	struct sccnxp_port *s;
 	struct sccnxp_port *s;
 	void __iomem *membase;
 	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);
 	s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL);
 	if (!s) {
 	if (!s) {
@@ -885,10 +884,20 @@ static int sccnxp_probe(struct platform_device *pdev)
 		break;
 		break;
 	default:
 	default:
 		dev_err(&pdev->dev, "Unsupported chip type %i\n", chiptype);
 		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) {
 	if (!pdata) {
 		dev_warn(&pdev->dev,
 		dev_warn(&pdev->dev,
 			 "No platform data supplied, using defaults\n");
 			 "No platform data supplied, using defaults\n");
@@ -919,22 +928,6 @@ static int sccnxp_probe(struct platform_device *pdev)
 		goto err_out;
 		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.owner		= THIS_MODULE;
 	s->uart.dev_name	= "ttySC";
 	s->uart.dev_name	= "ttySC";
 	s->uart.major		= SCCNXP_MAJOR;
 	s->uart.major		= SCCNXP_MAJOR;
@@ -997,6 +990,9 @@ static int sccnxp_probe(struct platform_device *pdev)
 	}
 	}
 
 
 err_out:
 err_out:
+	if (!IS_ERR(s->regulator))
+		return regulator_disable(s->regulator);
+
 	return ret;
 	return ret;
 }
 }