Make sure we turn off the clock on probe failure and device removal.
Fixes: de0a01f52966 ("PCI: xilinx-nwl: Enable the clock through CCF")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---
(no changes since v1)
drivers/pci/controller/pcie-xilinx-nwl.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
index c0a60cebdb2e..424cc5a1b4d1 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -779,6 +779,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
return -ENODEV;
pcie = pci_host_bridge_priv(bridge);
+ platform_set_drvdata(pdev, pcie);
pcie->dev = dev;
@@ -801,13 +802,13 @@ static int nwl_pcie_probe(struct platform_device *pdev)
err = nwl_pcie_bridge_init(pcie);
if (err) {
dev_err(dev, "HW Initialization failed\n");
- return err;
+ goto err_clk;
}
err = nwl_pcie_init_irq_domain(pcie);
if (err) {
dev_err(dev, "Failed creating IRQ Domain\n");
- return err;
+ goto err_clk;
}
bridge->sysdata = pcie;
@@ -817,11 +818,23 @@ static int nwl_pcie_probe(struct platform_device *pdev)
err = nwl_pcie_enable_msi(pcie);
if (err < 0) {
dev_err(dev, "failed to enable MSI support: %d\n", err);
- return err;
+ goto err_clk;
}
}
- return pci_host_probe(bridge);
+ err = pci_host_probe(bridge);
+
+err_clk:
+ if (err)
+ clk_disable_unprepare(pcie->clk);
+ return err;
+}
+
+static void nwl_pcie_remove(struct platform_device *pdev)
+{
+ struct nwl_pcie *pcie = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(pcie->clk);
}
static struct platform_driver nwl_pcie_driver = {
@@ -831,5 +844,6 @@ static struct platform_driver nwl_pcie_driver = {
.of_match_table = nwl_pcie_of_match,
},
.probe = nwl_pcie_probe,
+ .remove_new = nwl_pcie_remove,
};
builtin_platform_driver(nwl_pcie_driver);
--
2.35.1.1320.gc452695387.dirty
> Make sure we turn off the clock on probe failure and device removal.
…
> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
…
> @@ -817,11 +818,23 @@ static int nwl_pcie_probe(struct platform_device *pdev)
> err = nwl_pcie_enable_msi(pcie);
> if (err < 0) {
> dev_err(dev, "failed to enable MSI support: %d\n", err);
> - return err;
> + goto err_clk;
> }
> }
>
> - return pci_host_probe(bridge);
> + err = pci_host_probe(bridge);
> +
> +err_clk:
> + if (err)
> + clk_disable_unprepare(pcie->clk);
I suggest to use the label “disable_unprepare_clock” directly before this function call
(in the if branch) so that a duplicate check would be avoided after some error cases.
Regards,
Markus
On 5/23/24 15:18, Markus Elfring wrote:
>> Make sure we turn off the clock on probe failure and device removal.
> …
>> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> …
>> @@ -817,11 +818,23 @@ static int nwl_pcie_probe(struct platform_device *pdev)
>> err = nwl_pcie_enable_msi(pcie);
>> if (err < 0) {
>> dev_err(dev, "failed to enable MSI support: %d\n", err);
>> - return err;
>> + goto err_clk;
>> }
>> }
>>
>> - return pci_host_probe(bridge);
>> + err = pci_host_probe(bridge);
>> +
>> +err_clk:
>> + if (err)
>> + clk_disable_unprepare(pcie->clk);
>
> I suggest to use the label “disable_unprepare_clock” directly before this function call
> (in the if branch) so that a duplicate check would be avoided after some error cases.
Well if you want to avoid a check, we can just do
err = pci_host_probe(bridge);
if (!err)
return 0;
err_clk:
...
--Sean
>> …
>>> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
>> …
>>> @@ -817,11 +818,23 @@ static int nwl_pcie_probe(struct platform_device *pdev)
>>> err = nwl_pcie_enable_msi(pcie);
>>> if (err < 0) {
>>> dev_err(dev, "failed to enable MSI support: %d\n", err);
>>> - return err;
>>> + goto err_clk;
>>> }
>>> }
>>>
>>> - return pci_host_probe(bridge);
>>> + err = pci_host_probe(bridge);
>>> +
>>> +err_clk:
>>> + if (err)
>>> + clk_disable_unprepare(pcie->clk);
>>
>> I suggest to use the label “disable_unprepare_clock” directly before this function call
>> (in the if branch) so that a duplicate check would be avoided after some error cases.
>
> Well if you want to avoid a check, we can just do
>
> err = pci_host_probe(bridge);
> if (!err)
> return 0;
>
> err_clk:
> ...
This design variant can also be reasonable.
Do any preferences matter here for label name selections?
Regards,
Markus
On 5/23/24 16:11, Markus Elfring wrote:
>>> …
>>>> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
>>> …
>>>> @@ -817,11 +818,23 @@ static int nwl_pcie_probe(struct platform_device *pdev)
>>>> err = nwl_pcie_enable_msi(pcie);
>>>> if (err < 0) {
>>>> dev_err(dev, "failed to enable MSI support: %d\n", err);
>>>> - return err;
>>>> + goto err_clk;
>>>> }
>>>> }
>>>>
>>>> - return pci_host_probe(bridge);
>>>> + err = pci_host_probe(bridge);
>>>> +
>>>> +err_clk:
>>>> + if (err)
>>>> + clk_disable_unprepare(pcie->clk);
>>>
>>> I suggest to use the label “disable_unprepare_clock” directly before this function call
>>> (in the if branch) so that a duplicate check would be avoided after some error cases.
>>
>> Well if you want to avoid a check, we can just do
>>
>> err = pci_host_probe(bridge);
>> if (!err)
>> return 0;
>>
>> err_clk:
>> ...
>
> This design variant can also be reasonable.
>
> Do any preferences matter here for label name selections?
Personally, I prefer to use labels named after what they're cleaning up and not what they're doing.
--Sean
© 2016 - 2026 Red Hat, Inc.