Commit 9cf87666 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: dwc3: qcom: fix ACPI platform device leak

Make sure to free the "urs" platform device, which is created for some
ACPI platforms, on probe errors and on driver unbind.

Compile-tested only.

Fixes: c25c210f ("usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot")
Cc: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Acked-by: default avatarAndrew Halaney <ahalaney@redhat.com>
Acked-by: default avatarShawn Guo <shawn.guo@linaro.org>
Link: https://lore.kernel.org/r/20231117173650.21161-4-johan+linaro@kernel.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9feefbf5
...@@ -763,9 +763,9 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) ...@@ -763,9 +763,9 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev)
return ret; return ret;
} }
static struct platform_device * static struct platform_device *dwc3_qcom_create_urs_usb_platdev(struct device *dev)
dwc3_qcom_create_urs_usb_platdev(struct device *dev)
{ {
struct platform_device *urs_usb = NULL;
struct fwnode_handle *fwh; struct fwnode_handle *fwh;
struct acpi_device *adev; struct acpi_device *adev;
char name[8]; char name[8];
...@@ -785,9 +785,26 @@ dwc3_qcom_create_urs_usb_platdev(struct device *dev) ...@@ -785,9 +785,26 @@ dwc3_qcom_create_urs_usb_platdev(struct device *dev)
adev = to_acpi_device_node(fwh); adev = to_acpi_device_node(fwh);
if (!adev) if (!adev)
return NULL; goto err_put_handle;
urs_usb = acpi_create_platform_device(adev, NULL);
if (IS_ERR_OR_NULL(urs_usb))
goto err_put_handle;
return urs_usb;
return acpi_create_platform_device(adev, NULL); err_put_handle:
fwnode_handle_put(fwh);
return urs_usb;
}
static void dwc3_qcom_destroy_urs_usb_platdev(struct platform_device *urs_usb)
{
struct fwnode_handle *fwh = urs_usb->dev.fwnode;
platform_device_unregister(urs_usb);
fwnode_handle_put(fwh);
} }
static int dwc3_qcom_probe(struct platform_device *pdev) static int dwc3_qcom_probe(struct platform_device *pdev)
...@@ -871,13 +888,13 @@ static int dwc3_qcom_probe(struct platform_device *pdev) ...@@ -871,13 +888,13 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
qcom->qscratch_base = devm_ioremap_resource(dev, parent_res); qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
if (IS_ERR(qcom->qscratch_base)) { if (IS_ERR(qcom->qscratch_base)) {
ret = PTR_ERR(qcom->qscratch_base); ret = PTR_ERR(qcom->qscratch_base);
goto clk_disable; goto free_urs;
} }
ret = dwc3_qcom_setup_irq(pdev); ret = dwc3_qcom_setup_irq(pdev);
if (ret) { if (ret) {
dev_err(dev, "failed to setup IRQs, err=%d\n", ret); dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
goto clk_disable; goto free_urs;
} }
/* /*
...@@ -896,7 +913,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev) ...@@ -896,7 +913,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret); dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
goto clk_disable; goto free_urs;
} }
ret = dwc3_qcom_interconnect_init(qcom); ret = dwc3_qcom_interconnect_init(qcom);
...@@ -935,6 +952,9 @@ static int dwc3_qcom_probe(struct platform_device *pdev) ...@@ -935,6 +952,9 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
platform_device_del(qcom->dwc3); platform_device_del(qcom->dwc3);
} }
platform_device_put(qcom->dwc3); platform_device_put(qcom->dwc3);
free_urs:
if (qcom->urs_usb)
dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb);
clk_disable: clk_disable:
for (i = qcom->num_clocks - 1; i >= 0; i--) { for (i = qcom->num_clocks - 1; i >= 0; i--) {
clk_disable_unprepare(qcom->clks[i]); clk_disable_unprepare(qcom->clks[i]);
...@@ -961,6 +981,9 @@ static void dwc3_qcom_remove(struct platform_device *pdev) ...@@ -961,6 +981,9 @@ static void dwc3_qcom_remove(struct platform_device *pdev)
} }
platform_device_put(qcom->dwc3); platform_device_put(qcom->dwc3);
if (qcom->urs_usb)
dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb);
for (i = qcom->num_clocks - 1; i >= 0; i--) { for (i = qcom->num_clocks - 1; i >= 0; i--) {
clk_disable_unprepare(qcom->clks[i]); clk_disable_unprepare(qcom->clks[i]);
clk_put(qcom->clks[i]); clk_put(qcom->clks[i]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment