Skip to content

Commit

Permalink
PCI: qcom: Fix error handling in runtime PM support
Browse files Browse the repository at this point in the history
The driver does not cope with the fact that probe can fail in a number
of cases after enabling runtime PM on the device; this results in
warnings about "Unbalanced pm_runtime_enable". Furthermore if probe
fails after invoking qcom_pcie_host_init() the power-domain will be left
referenced.

As it is not possible for the error handling in qcom_pcie_host_init() to
handle errors happening after returning from that function the
pm_runtime_get_sync() is moved to qcom_pcie_probe() as well.

Fixes: 854b69e ("PCI: qcom: add runtime pm support to pcie_port")
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
  • Loading branch information
andersson authored and Lorenzo Pieralisi committed Sep 18, 2018
1 parent 0ee2c1f commit 6e5da6f
Showing 1 changed file with 39 additions and 17 deletions.
56 changes: 39 additions & 17 deletions drivers/pci/controller/dwc/pcie-qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,6 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
struct qcom_pcie *pcie = to_qcom_pcie(pci);
int ret;

pm_runtime_get_sync(pci->dev);
qcom_ep_reset_assert(pcie);

ret = pcie->ops->init(pcie);
Expand Down Expand Up @@ -1126,7 +1125,6 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
phy_power_off(pcie->phy);
err_deinit:
pcie->ops->deinit(pcie);
pm_runtime_put(pci->dev);

return ret;
}
Expand Down Expand Up @@ -1216,6 +1214,12 @@ static int qcom_pcie_probe(struct platform_device *pdev)
return -ENOMEM;

pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_disable(dev);
return ret;
}

pci->dev = dev;
pci->ops = &dw_pcie_ops;
pp = &pci->pp;
Expand All @@ -1225,44 +1229,56 @@ static int qcom_pcie_probe(struct platform_device *pdev)
pcie->ops = of_device_get_match_data(dev);

pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
if (IS_ERR(pcie->reset))
return PTR_ERR(pcie->reset);
if (IS_ERR(pcie->reset)) {
ret = PTR_ERR(pcie->reset);
goto err_pm_runtime_put;
}

res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
pcie->parf = devm_ioremap_resource(dev, res);
if (IS_ERR(pcie->parf))
return PTR_ERR(pcie->parf);
if (IS_ERR(pcie->parf)) {
ret = PTR_ERR(pcie->parf);
goto err_pm_runtime_put;
}

res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
if (IS_ERR(pci->dbi_base)) {
ret = PTR_ERR(pci->dbi_base);
goto err_pm_runtime_put;
}

res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
pcie->elbi = devm_ioremap_resource(dev, res);
if (IS_ERR(pcie->elbi))
return PTR_ERR(pcie->elbi);
if (IS_ERR(pcie->elbi)) {
ret = PTR_ERR(pcie->elbi);
goto err_pm_runtime_put;
}

pcie->phy = devm_phy_optional_get(dev, "pciephy");
if (IS_ERR(pcie->phy))
return PTR_ERR(pcie->phy);
if (IS_ERR(pcie->phy)) {
ret = PTR_ERR(pcie->phy);
goto err_pm_runtime_put;
}

ret = pcie->ops->get_resources(pcie);
if (ret)
return ret;
goto err_pm_runtime_put;

pp->ops = &qcom_pcie_dw_ops;

if (IS_ENABLED(CONFIG_PCI_MSI)) {
pp->msi_irq = platform_get_irq_byname(pdev, "msi");
if (pp->msi_irq < 0)
return pp->msi_irq;
if (pp->msi_irq < 0) {
ret = pp->msi_irq;
goto err_pm_runtime_put;
}
}

ret = phy_init(pcie->phy);
if (ret) {
pm_runtime_disable(&pdev->dev);
return ret;
goto err_pm_runtime_put;
}

platform_set_drvdata(pdev, pcie);
Expand All @@ -1271,10 +1287,16 @@ static int qcom_pcie_probe(struct platform_device *pdev)
if (ret) {
dev_err(dev, "cannot initialize host\n");
pm_runtime_disable(&pdev->dev);
return ret;
goto err_pm_runtime_put;
}

return 0;

err_pm_runtime_put:
pm_runtime_put(dev);
pm_runtime_disable(dev);

return ret;
}

static const struct of_device_id qcom_pcie_match[] = {
Expand Down

0 comments on commit 6e5da6f

Please sign in to comment.