list_for_each_entry(child, &bus->children, node)
pcie_bus_configure_settings(child);
+ pci_lock_rescan_remove();
pci_bus_add_devices(bus);
+ pci_unlock_rescan_remove();
+
+ /*
+ * Ensure pm_runtime_enable() is called for the controller drivers
+ * before calling pci_host_probe(). The PM framework expects that
+ * if the parent device supports runtime PM, it will be enabled
+ * before child runtime PM is enabled.
+ */
+ pm_runtime_set_active(&bridge->dev);
+ pm_runtime_no_callbacks(&bridge->dev);
+ devm_pm_runtime_enable(&bridge->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(pci_host_probe);
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
- #include <linux/pci-pwrctl.h>
-#include <linux/of.h>
+ #include <linux/pci-pwrctrl.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/pwrseq/consumer.h>
#include <linux/slab.h>
#include <linux/types.h>
struct pwrseq_desc *pwrseq;
};
- struct pci_pwrctl_pwrseq_pdata {
++struct pci_pwrctrl_pwrseq_pdata {
+ const char *target;
+ /*
+ * Called before doing anything else to perform device-specific
+ * verification between requesting the power sequencing handle.
+ */
+ int (*validate_device)(struct device *dev);
+};
+
- static int pci_pwrctl_pwrseq_qcm_wcn_validate_device(struct device *dev)
++static int pci_pwrctrl_pwrseq_qcm_wcn_validate_device(struct device *dev)
+{
+ /*
+ * Old device trees for some platforms already define wifi nodes for
+ * the WCN family of chips since before power sequencing was added
+ * upstream.
+ *
+ * These nodes don't consume the regulator outputs from the PMU, and
+ * if we allow this driver to bind to one of such "incomplete" nodes,
+ * we'll see a kernel log error about the indefinite probe deferral.
+ *
+ * Check the existence of the regulator supply that exists on all
+ * WCN models before moving forward.
+ */
+ if (!device_property_present(dev, "vddaon-supply"))
+ return -ENODEV;
+
+ return 0;
+}
+
- static const struct pci_pwrctl_pwrseq_pdata pci_pwrctl_pwrseq_qcom_wcn_pdata = {
++static const struct pci_pwrctrl_pwrseq_pdata pci_pwrctrl_pwrseq_qcom_wcn_pdata = {
+ .target = "wlan",
- .validate_device = pci_pwrctl_pwrseq_qcm_wcn_validate_device,
++ .validate_device = pci_pwrctrl_pwrseq_qcm_wcn_validate_device,
+};
+
- static void devm_pci_pwrctl_pwrseq_power_off(void *data)
+ static void devm_pci_pwrctrl_pwrseq_power_off(void *data)
{
struct pwrseq_desc *pwrseq = data;
pwrseq_power_off(pwrseq);
}
- static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev)
+ static int pci_pwrctrl_pwrseq_probe(struct platform_device *pdev)
{
- const struct pci_pwrctl_pwrseq_pdata *pdata;
- struct pci_pwrctl_pwrseq_data *data;
++ const struct pci_pwrctrl_pwrseq_pdata *pdata;
+ struct pci_pwrctrl_pwrseq_data *data;
struct device *dev = &pdev->dev;
int ret;
{
/* ATH11K in QCA6390 package. */
.compatible = "pci17cb,1101",
- .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
- .data = "wlan",
++ .data = &pci_pwrctrl_pwrseq_qcom_wcn_pdata,
},
{
/* ATH11K in WCN6855 package. */
.compatible = "pci17cb,1103",
- .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
- .data = "wlan",
++ .data = &pci_pwrctrl_pwrseq_qcom_wcn_pdata,
},
{
/* ATH12K in WCN7850 package. */
.compatible = "pci17cb,1107",
- .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
- .data = "wlan",
++ .data = &pci_pwrctrl_pwrseq_qcom_wcn_pdata,
},
{ }
};