@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
static const struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = {
.bus_shift = 16,
@@ -76,13 +77,50 @@ static const struct of_device_id gen_pci_of_match[] = {
};
MODULE_DEVICE_TABLE(of, gen_pci_of_match);
+static int gen_pcie_ecam_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret = 0;
+
+ if (!IS_ERR_OR_NULL(dev->pm_domain)) {
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0) {
+ dev_err(dev, "fail to enable pcie controller:%d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = pci_host_common_probe(pdev);
+ if (ret) {
+ dev_err(dev, "pci_host_common_probe() failed:%d\n", ret);
+ goto err;
+ }
+
+ return ret;
+err:
+ if (!IS_ERR_OR_NULL(dev->pm_domain))
+ pm_runtime_put_sync(dev);
+ return ret;
+}
+
+static void gen_pcie_ecam_remove(struct platform_device *pdev)
+{
+ pci_host_common_remove(pdev);
+ if (pdev->dev.pm_domain)
+ pm_runtime_put_sync(&pdev->dev);
+}
+
static struct platform_driver gen_pci_driver = {
.driver = {
.name = "pci-host-generic",
.of_match_table = gen_pci_of_match,
},
- .probe = pci_host_common_probe,
- .remove_new = pci_host_common_remove,
+ .probe = gen_pcie_ecam_probe,
+ .remove_new = gen_pcie_ecam_remove,
};
module_platform_driver(gen_pci_driver);
Add usage of power domain to control PCIe controller enumeration. This is needed to allow interaction with firmware to vote/unvote system resources, PCIe PHY and configuration of PCIe controller into ECAM mode. This feature support system suspend and resume to put PCIe into D3 cold and D0. Signed-off-by: Mayank Rana <quic_mrana@quicinc.com> --- drivers/pci/controller/pci-host-generic.c | 42 +++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)