On Tue, Nov 3, 2020 at 1:28 AM Qinglang Miao <miaoqinglang@xxxxxxxxxx> wrote: > > Fix the missing clk_disable_unprepare() before return > from v3_pci_probe() in the error handling case. > > Moving the clock enable later to avoid some fixes. > > Fixes: 6e0832fa432e (" PCI: Collect all native drivers under drivers/pci/controller/") I don't think this commit caused the problem. > Suggested-by: Rob Herring <robh@xxxxxxxxxx> > Signed-off-by: Qinglang Miao <miaoqinglang@xxxxxxxxxx> > --- > drivers/pci/controller/pci-v3-semi.c | 40 ++++++++++++++++------------ > 1 file changed, 23 insertions(+), 17 deletions(-) > > diff --git a/drivers/pci/controller/pci-v3-semi.c b/drivers/pci/controller/pci-v3-semi.c > index 154a53986..90520555b 100644 > --- a/drivers/pci/controller/pci-v3-semi.c > +++ b/drivers/pci/controller/pci-v3-semi.c > @@ -725,18 +725,6 @@ static int v3_pci_probe(struct platform_device *pdev) > host->sysdata = v3; > v3->dev = dev; > > - /* Get and enable host clock */ > - clk = devm_clk_get(dev, NULL); > - if (IS_ERR(clk)) { > - dev_err(dev, "clock not found\n"); > - return PTR_ERR(clk); > - } > - ret = clk_prepare_enable(clk); > - if (ret) { > - dev_err(dev, "unable to enable clock\n"); > - return ret; > - } > - > regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); > v3->base = devm_ioremap_resource(dev, regs); > if (IS_ERR(v3->base)) > @@ -761,17 +749,31 @@ static int v3_pci_probe(struct platform_device *pdev) > if (IS_ERR(v3->config_base)) > return PTR_ERR(v3->config_base); > > + /* Get and enable host clock */ > + clk = devm_clk_get(dev, NULL); > + if (IS_ERR(clk)) { > + dev_err(dev, "clock not found\n"); > + return PTR_ERR(clk); > + } > + ret = clk_prepare_enable(clk); > + if (ret) { > + dev_err(dev, "unable to enable clock\n"); > + return ret; > + } > + > /* Get and request error IRQ resource */ > irq = platform_get_irq(pdev, 0); > - if (irq < 0) > + if (irq < 0) { > + clk_disable_unprepare(clk); > return irq; > - > + } > ret = devm_request_irq(dev, irq, v3_irq, 0, > "PCIv3 error", v3); > if (ret < 0) { > dev_err(dev, > "unable to request PCIv3 error IRQ %d (%d)\n", > irq, ret); > + clk_disable_unprepare(clk); > return ret; > } > > @@ -814,13 +816,15 @@ static int v3_pci_probe(struct platform_device *pdev) > ret = v3_pci_setup_resource(v3, host, win); > if (ret) { > dev_err(dev, "error setting up resources\n"); > + clk_disable_unprepare(clk); > return ret; > } > } > ret = v3_pci_parse_map_dma_ranges(v3, np); > - if (ret) > + if (ret) { > + clk_disable_unprepare(clk); > return ret; > - > + } > /* > * Disable PCI to host IO cycles, enable I/O buffers @3.3V, > * set AD_LOW0 to 1 if one of the LB_MAP registers choose > @@ -862,8 +866,10 @@ static int v3_pci_probe(struct platform_device *pdev) > /* Special Integrator initialization */ > if (of_device_is_compatible(np, "arm,integrator-ap-pci")) { > ret = v3_integrator_init(v3); > - if (ret) > + if (ret) { > + clk_disable_unprepare(clk); You should make all these a goto and just have one clk_disable_unprepare() call. You are still missing error handling after pci_host_probe(). > return ret; > + } > } > > /* Post-init: enable PCI memory and invalidate (master already on) */ > -- > 2.23.0 >