summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKomal Seelam <kseelam@qti.qualcomm.com>2016-08-03 11:37:08 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-08-04 13:46:17 +0530
commit16a8d412bfbe409330b0c7fe9ebe4c246c524c49 (patch)
tree2a084aaa0ca5574073bb4d2ccb5d429a91e6e46a
parent17d949acf8401cbda1fc25bf9e8d97fe3b0e06b3 (diff)
qcacld-2.0: Interface to UserSpace to enable/disable Runtime PM
OEM requires to enable/disable runtime pm dynamically when driver is functional. Provide debugfs interface to support this requirement. Usage: echo 0 > /d/cnss_runtime_pm -> Disable Runtime PM echo 1 > /d/cnss_runtime_pm -> Enable Runtime PM On SSR, if user has vote to disable runtime pm, we disable runtime pm once SSR is complete. On Driver Reload, the driver comes back to reset state. User has to vote if needed to control runtime pm. CRs-Fixed: 1049662 Change-Id: I21756f4da251eb4a4a5e7c4ea0afc9c5a918d293
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c78
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h9
2 files changed, 82 insertions, 5 deletions
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index 17e99b14996a..60d0c4ffee10 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -878,6 +878,7 @@ static void hif_pci_pm_work(struct work_struct *work)
msg_callbacks->txResumeAllHandler(msg_callbacks->Context);
}
+#ifdef WLAN_OPEN_SOURCE
static int hif_pci_autopm_debugfs_show(struct seq_file *s, void *data)
{
#define HIF_PCI_AUTOPM_STATS(_s, _sc, _name) \
@@ -1126,6 +1127,52 @@ static ssize_t hif_pci_autopm_write(struct file *fp, const char __user *buf,
adf_os_mem_free(pattern);
return count;
}
+#else
+#define HIF_ENABLE_AUTO_PM 1
+#define HIF_DISABLE_AUTO_PM 0
+static bool dynamic_auto_pm_state = HIF_ENABLE_AUTO_PM;
+
+static ssize_t hif_pci_enable_disable_autopm(struct file *fp, const char __user
+ *buf, size_t count, loff_t *off)
+{
+ int enable_auto_pm;
+ struct seq_file *s;
+ struct hif_pci_softc *hif_sc;
+ int ret;
+ struct hif_pm_runtime_context *ctx;
+ struct ol_softc *sc;
+
+ s = (struct seq_file *)fp->private_data;
+ hif_sc = s->private;
+
+ if (!hif_sc)
+ return -EINVAL;
+
+ sscanf(buf, "%d", &enable_auto_pm);
+
+ if ((enable_auto_pm != HIF_ENABLE_AUTO_PM) && (enable_auto_pm !=
+ HIF_DISABLE_AUTO_PM)) {
+ pr_err("%s: I/P is invalid:%d Valid: Enable(1), Disable(0)\n",
+ __func__, enable_auto_pm);
+ return -EINVAL;
+ }
+
+ ctx = hif_sc->dynamic_ctx;
+ sc = hif_sc->ol_sc;
+
+ ret = enable_auto_pm ? hif_pm_runtime_allow_suspend(sc, ctx) :
+ hif_pm_runtime_prevent_suspend(sc, ctx);
+
+ if (ret)
+ return ret;
+
+ pr_info("%s: enable_auto_pm:%d ret:%d \n", __func__, enable_auto_pm,
+ ret);
+
+ dynamic_auto_pm_state = enable_auto_pm;
+
+ return count;
+}
#endif
static const struct file_operations hif_pci_autopm_fops = {
@@ -1136,8 +1183,11 @@ static const struct file_operations hif_pci_autopm_fops = {
.llseek = seq_lseek,
#ifdef FEATURE_RUNTIME_PM_UNIT_TEST
.write = hif_pci_autopm_write,
+#else
+ .write = hif_pci_enable_disable_autopm,
#endif
};
+#endif /*WLAN_OPEN_SOURCE*/
static int __hif_pci_runtime_suspend(struct pci_dev *pdev)
{
@@ -1323,14 +1373,38 @@ struct cnss_wlan_runtime_ops runtime_pm_ops = {
};
#ifdef WLAN_OPEN_SOURCE
+#ifdef FEATURE_RUNTIME_PM_UNIT_TEST
+static void hif_dynamic_auto_pm_init(struct hif_pci_softc *sc)
+{
+}
+static void hif_dynaic_auto_pm_deinit(struct hif_pci_softc *sc)
+{
+}
+#else /* else FEATURE_RUNTIME_PM_UNIT_TEST */
+static void hif_dynamic_auto_pm_init(struct hif_pci_softc *sc)
+{
+ sc->dynamic_ctx = hif_runtime_pm_prevent_suspend_init("dynamic_ctx");
+
+ if (!dynamic_auto_pm_state)
+ hif_pm_runtime_prevent_suspend(sc->ol_sc, sc->dynamic_ctx);
+}
+static void hif_dynaic_auto_pm_deinit(struct hif_pci_softc *sc)
+{
+ hif_runtime_pm_prevent_suspend_deinit(sc->dynamic_ctx);
+}
+#endif /* END FEATURE_RUNTIME_PM_UNIT_TEST */
+
static inline void hif_pci_pm_debugfs(struct hif_pci_softc *sc, bool init)
{
- if (init)
+ if (init) {
sc->pm_dentry = debugfs_create_file("cnss_runtime_pm",
S_IRUSR, NULL, sc,
&hif_pci_autopm_fops);
- else
+ hif_dynamic_auto_pm_init(sc);
+ } else {
+ hif_dynaic_auto_pm_deinit(sc);
debugfs_remove(sc->pm_dentry);
+ }
}
#else
static inline void hif_pci_pm_debugfs(struct hif_pci_softc *sc, bool init)
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h
index 3204f6101eb9..ffb4df95582f 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.h
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -131,8 +131,11 @@ struct hif_pci_softc {
unsigned long runtime_timer_expires;
#ifdef WLAN_OPEN_SOURCE
struct dentry *pm_dentry;
-#endif
-#endif
+#ifndef FEATURE_RUNTIME_PM_UNIT_TEST
+ struct hif_pm_runtime_context *dynamic_ctx;
+#endif /*FEATURE_RUNTIME_PM_UNIT_TEST*/
+#endif /*WLAN_OPEN_SOURCE*/
+#endif /*FEATURE_RUNTIME_PM*/
};
#define TARGID(sc) ((A_target_id_t)(&(sc)->mem))
#define TARGID_TO_HIF(targid) (((struct hif_pci_softc *)((char *)(targid) - (char *)&(((struct hif_pci_softc *)0)->mem)))->hif_device)