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

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.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9feefbf5
Loading
Loading
Loading
Loading
+30 −7
Original line number Diff line number Diff line
@@ -763,9 +763,9 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev)
	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;

	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;
}

	return acpi_create_platform_device(adev, NULL);
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 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
		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]);