summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorYue Ma <yuem@codeaurora.org>2018-08-07 16:47:09 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2018-10-08 12:40:07 -0700
commitabbfad73a86c9adc74cdc554f062278a2815e8d7 (patch)
treeab924ad788ad64bee82c83a62fda0db90d6a1124 /drivers/net
parent3b8fc0b7a3fcc809378d82dbf66b417e186af205 (diff)
cnss2: Add force wake support
As part of PCIe power management for new WLAN devices, it requires asserting WAKE register before accessing any MMIO registers outside first 4K range. Add the support in CNSS driver and expose the APIs for WLAN host driver. Change-Id: I69688c229121c12575dde4938961d60bc067751f Signed-off-by: Yue Ma <yuem@codeaurora.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/cnss2/pci.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 1d4b5b9ea9c9..427b42c871f3 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -1297,6 +1297,94 @@ int cnss_pm_request_resume(struct cnss_pci_data *pci_priv)
return pm_request_resume(&pci_dev->dev);
}
+#ifdef CONFIG_CNSS_QCA6390
+int cnss_pci_force_wake_request(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct mhi_controller *mhi_ctrl;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ if (pci_priv->device_id != QCA6390_DEVICE_ID)
+ return 0;
+
+ mhi_ctrl = pci_priv->mhi_ctrl;
+ if (!mhi_ctrl)
+ return -EINVAL;
+
+ read_lock_bh(&mhi_ctrl->pm_lock);
+ mhi_ctrl->wake_get(mhi_ctrl, true);
+ read_unlock_bh(&mhi_ctrl->pm_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_request);
+
+int cnss_pci_is_device_awake(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct mhi_controller *mhi_ctrl;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ if (pci_priv->device_id != QCA6390_DEVICE_ID)
+ return true;
+
+ mhi_ctrl = pci_priv->mhi_ctrl;
+ if (!mhi_ctrl)
+ return -EINVAL;
+
+ return mhi_ctrl->dev_state == MHI_STATE_M0 ? true : false;
+}
+EXPORT_SYMBOL(cnss_pci_is_device_awake);
+
+int cnss_pci_force_wake_release(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct mhi_controller *mhi_ctrl;
+
+ if (!pci_priv)
+ return -ENODEV;
+
+ if (pci_priv->device_id != QCA6390_DEVICE_ID)
+ return 0;
+
+ mhi_ctrl = pci_priv->mhi_ctrl;
+ if (!mhi_ctrl)
+ return -EINVAL;
+
+ read_lock_bh(&mhi_ctrl->pm_lock);
+ mhi_ctrl->wake_put(mhi_ctrl, false);
+ read_unlock_bh(&mhi_ctrl->pm_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_release);
+#else
+int cnss_pci_force_wake_request(struct device *dev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_request);
+
+int cnss_pci_is_device_awake(struct device *dev)
+{
+ return true;
+}
+EXPORT_SYMBOL(cnss_pci_is_device_awake);
+
+int cnss_pci_force_wake_release(struct device *dev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(cnss_pci_force_wake_release);
+#endif
+
int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv)
{
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;