On Thu, Jan 28, 2021 at 11:52 AM Dmitry Baryshkov
<dmitry.baryshkov@xxxxxxxxxx> wrote:
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.
This is solving a generic problem in a specific driver. It needs to be
solved for any PCI host and any device.
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