[PATCH] usb: dwc3: qcom: Fox some error handling path in dwc3_qcom_probe()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Replace some direct return with goto to the existing error handling path.
Also release 'parent_res', if needed.


In the remove function, handle the case where 'np' is set or not, to call
the right function as already done in the error handling path of the probe.

Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx>
---
The patch looks not complete and dwc3_qcom_create_urs_usb_platdev() (and
its acpi_create_platform_device() call) still need undone in the error
handling path, right?

This looks more tricky to me, so I just point it out and leave it to
anyone who cares.

The remove function is also likely incomplete (for example 'parent_res'
leaks if !np).

Even if not perfect, this patch makes code already "better" :)

Comments and follow-up by others welcomed.


Finally, I've not searched for Fixes tag because it is likely that these
issues have been added in several patches. I have the courage to dig into
this log history.
---
 drivers/usb/dwc3/dwc3-qcom.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
index c5e482f53e9d..1fe83fd51947 100644
--- a/drivers/usb/dwc3/dwc3-qcom.c
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -815,9 +815,10 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
 		parent_res = res;
 	} else {
 		parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL);
-		if (!parent_res)
-			return -ENOMEM;
-
+		if (!parent_res) {
+			ret = -ENOMEM;
+			goto clk_disable;
+		}
 		parent_res->start = res->start +
 			qcom->acpi_pdata->qscratch_base_offset;
 		parent_res->end = parent_res->start +
@@ -828,9 +829,10 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
 			if (IS_ERR_OR_NULL(qcom->urs_usb)) {
 				dev_err(dev, "failed to create URS USB platdev\n");
 				if (!qcom->urs_usb)
-					return -ENODEV;
+					ret = -ENODEV;
 				else
-					return PTR_ERR(qcom->urs_usb);
+					ret = PTR_ERR(qcom->urs_usb);
+				goto free_parent_res;
 			}
 		}
 	}
@@ -838,13 +840,13 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
 	qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
 	if (IS_ERR(qcom->qscratch_base)) {
 		ret = PTR_ERR(qcom->qscratch_base);
-		goto clk_disable;
+		goto free_parent_res;
 	}
 
 	ret = dwc3_qcom_setup_irq(pdev);
 	if (ret) {
 		dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
-		goto clk_disable;
+		goto free_parent_res;
 	}
 
 	/*
@@ -906,6 +908,9 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
 		of_platform_depopulate(&pdev->dev);
 	else
 		platform_device_put(pdev);
+free_parent_res:
+	if (!np)
+		kfree(parent_res);
 clk_disable:
 	for (i = qcom->num_clocks - 1; i >= 0; i--) {
 		clk_disable_unprepare(qcom->clks[i]);
@@ -920,11 +925,15 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
 static int dwc3_qcom_remove(struct platform_device *pdev)
 {
 	struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
+	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
 	int i;
 
 	device_remove_software_node(&qcom->dwc3->dev);
-	of_platform_depopulate(dev);
+	if (np)
+		of_platform_depopulate(&pdev->dev);
+	else
+		platform_device_put(pdev);
 
 	for (i = qcom->num_clocks - 1; i >= 0; i--) {
 		clk_disable_unprepare(qcom->clks[i]);
-- 
2.34.1




[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux