From aace9713d64765fdc7a8eb00ee2e5ea8e76d3685 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Wed, 5 Apr 2017 12:30:33 -0700 Subject: [PATCH] cnss2: Set PCIe to D3hot state before suspending PCIe link As per PCIe spec, PCIe link needs to be set to D3hot state before entering D3cold state. Change-Id: I68defc4cf29fe88262e92fe8fb934948ad13aef4 CRs-fixed: 2059087 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/pci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index f914f4352392..a17b72ce03ba 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -143,6 +143,12 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv) if (ret) goto out; + pci_disable_device(pci_priv->pci_dev); + + ret = pci_set_power_state(pci_priv->pci_dev, PCI_D3hot); + if (ret) + cnss_pr_err("Failed to set D3Hot, err = %d\n", ret); + ret = cnss_set_pci_link(pci_priv, PCI_LINK_DOWN); if (ret) goto out; @@ -172,10 +178,18 @@ int cnss_resume_pci_link(struct cnss_pci_data *pci_priv) pci_priv->pci_link_state = PCI_LINK_UP; + ret = pci_enable_device(pci_priv->pci_dev); + if (ret) { + cnss_pr_err("Failed to enable PCI device, err = %d\n", ret); + goto out; + } + ret = cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE); if (ret) goto out; + pci_set_master(pci_priv->pci_dev); + if (pci_priv->pci_link_down_ind) pci_priv->pci_link_down_ind = false; @@ -381,6 +395,12 @@ static int cnss_pci_suspend(struct device *dev) cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE); + pci_disable_device(pci_dev); + + ret = pci_set_power_state(pci_dev, PCI_D3hot); + if (ret) + cnss_pr_err("Failed to set D3Hot, err = %d\n", + ret); } } @@ -407,10 +427,18 @@ static int cnss_pci_resume(struct device *dev) driver_ops = plat_priv->driver_ops; if (driver_ops && driver_ops->resume && !pci_priv->pci_link_down_ind) { + ret = pci_enable_device(pci_dev); + if (ret) + cnss_pr_err("Failed to enable PCI device, err = %d\n", + ret); + if (pci_priv->saved_state) cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE); + + pci_set_master(pci_dev); cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME); + ret = driver_ops->resume(pci_dev); }