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: c25c210f59 ("usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot")
Cc: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Acked-by: Andrew Halaney <ahalaney@redhat.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Link: https://lore.kernel.org/r/20231117173650.21161-4-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Johan Hovold 2023-11-17 18:36:50 +01:00 committed by Greg Kroah-Hartman
parent 9feefbf57d
commit 9cf87666fc

View File

@ -763,9 +763,9 @@ node_put:
return ret;
}
static struct platform_device *
dwc3_qcom_create_urs_usb_platdev(struct device *dev)
static struct platform_device *dwc3_qcom_create_urs_usb_platdev(struct device *dev)
{
struct platform_device *urs_usb = NULL;
struct fwnode_handle *fwh;
struct acpi_device *adev;
char name[8];
@ -785,9 +785,26 @@ dwc3_qcom_create_urs_usb_platdev(struct device *dev)
adev = to_acpi_device_node(fwh);
if (!adev)
return NULL;
goto err_put_handle;
return acpi_create_platform_device(adev, NULL);
urs_usb = acpi_create_platform_device(adev, NULL);
if (IS_ERR_OR_NULL(urs_usb))
goto err_put_handle;
return urs_usb;
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)
@ -871,13 +888,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_urs;
}
ret = dwc3_qcom_setup_irq(pdev);
if (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)
if (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);
@ -935,6 +952,9 @@ depopulate:
platform_device_del(qcom->dwc3);
}
platform_device_put(qcom->dwc3);
free_urs:
if (qcom->urs_usb)
dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb);
clk_disable:
for (i = qcom->num_clocks - 1; i >= 0; i--) {
clk_disable_unprepare(qcom->clks[i]);
@ -961,6 +981,9 @@ static void dwc3_qcom_remove(struct platform_device *pdev)
}
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--) {
clk_disable_unprepare(qcom->clks[i]);
clk_put(qcom->clks[i]);