Some Qualcomm platforms require to power up an external device before probing the PCI bus. E.g. on RB5 platform the QCA6390 WiFi/BT chip needs to be powered up before PCIe0 bus is probed. Add a quirk to the respective PCIe root bridge to attach to the power domain if one is required, so that the QCA chip is started before scanning the PCIe bus. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> --- drivers/pci/controller/dwc/pcie-qcom.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index ab21aa01c95d..eb73c8540d4d 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -20,6 +20,7 @@ #include <linux/of_device.h> #include <linux/of_gpio.h> #include <linux/pci.h> +#include <linux/pm_domain.h> #include <linux/pm_runtime.h> #include <linux/platform_device.h> #include <linux/phy/phy.h> @@ -1568,6 +1569,26 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0302, qcom_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1000, qcom_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1001, qcom_fixup_class); +static void qcom_fixup_power(struct pci_dev *dev) +{ + int ret; + struct pcie_port *pp = dev->bus->sysdata; + struct dw_pcie *pci; + + if (!pci_is_root_bus(dev->bus)) + return; + + ret = dev_pm_domain_attach(&dev->dev, true); + if (ret < 0 || !dev->dev.pm_domain) + return; + + pci = to_dw_pcie_from_pp(pp); + dev_info(&dev->dev, "Bus powered up, waiting for link to come up\n"); + + dw_pcie_wait_for_link(pci); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x010b, qcom_fixup_power); + static struct platform_driver qcom_pcie_driver = { .probe = qcom_pcie_probe, .driver = { -- 2.29.2