Commit deed8aec62dc ("PCI: qcom: Handle mixed PERST#/PHY DT configuration") fixed support for the "mixed" platforms which declare PERST# pin the RC node and the PHY in the RP node, however it also broke support for a majority of existing platforms, which declare both PERST# and PHY in the RC node, because now PERST# is first acquired in qcom_pcie_parse_ports(), which then returns -ENODEV (as there are no PHYs in the RP nodes). Later qcom_pcie_parse_legacy_binding() tries to acquire the PERST# GPIO again and fails with -EBUSY (as the GPIO has already been requested). Move parsing of RC's perst-gpios to qcom_pcie_probe(), making it obvious that it's shared for both cases and skip parsing it in both functions. Fixes: deed8aec62dc ("PCI: qcom: Handle mixed PERST#/PHY DT configuration") Closes: https://lore.kernel.org/r/gieaybsg2ckxpctvqj77nlwu7utama2yeyvebkonmexsxrra3v@v3fobqasxnmy/ Signed-off-by: Dmitry Baryshkov --- drivers/pci/controller/dwc/pcie-qcom.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 11fc60489892..7664c7c28c0e 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1907,15 +1907,6 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie) struct device *dev = pcie->pci->dev; int ret = -ENODEV; - if (of_find_property(dev->of_node, "perst-gpios", NULL)) { - pcie->reset = devm_gpiod_get_optional(dev, "perst", - GPIOD_OUT_HIGH); - if (IS_ERR(pcie->reset)) - return PTR_ERR(pcie->reset); - - dev_warn(dev, "Reusing PERST# from Root Complex node. DT needs to be fixed!\n"); - } - for_each_available_child_of_node_scoped(dev->of_node, of_port) { if (!of_node_is_type(of_port, "pci")) continue; @@ -1942,7 +1933,6 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie) struct device *dev = pcie->pci->dev; struct qcom_pcie_perst *perst; struct qcom_pcie_port *port; - struct gpio_desc *reset; struct phy *phy; int ret; @@ -1950,10 +1940,6 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie) if (IS_ERR(phy)) return PTR_ERR(phy); - reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH); - if (IS_ERR(reset)) - return PTR_ERR(reset); - ret = phy_init(phy); if (ret) return ret; @@ -1970,7 +1956,7 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie) INIT_LIST_HEAD(&port->list); list_add_tail(&port->list, &pcie->ports); - perst->desc = reset; + perst->desc = pcie->reset; INIT_LIST_HEAD(&port->perst); INIT_LIST_HEAD(&perst->list); list_add_tail(&perst->list, &port->perst); @@ -2107,6 +2093,15 @@ static int qcom_pcie_probe(struct platform_device *pdev) pp->ops = &qcom_pcie_dw_ops; + if (of_find_property(dev->of_node, "perst-gpios", NULL)) { + pcie->reset = devm_gpiod_get_optional(dev, "perst", + GPIOD_OUT_HIGH); + if (IS_ERR(pcie->reset)) + return PTR_ERR(pcie->reset); + + dev_warn(dev, "Reusing PERST# from Root Complex node. DT needs to be updated!\n"); + } + ret = qcom_pcie_parse_ports(pcie); if (ret) { if (ret != -ENODEV) { -- 2.47.3