summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRohit Gupta <rohgup@codeaurora.org>2014-11-14 17:53:15 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:02:59 -0700
commitdb44d1e057ce4c3396668fd0e55cba71729ce71e (patch)
tree9f4374b51f0294f152ca91a16df2f48ac17e8729
parentdb35fc6d65c4e53ea31b7c599c5072367b450af0 (diff)
cpufreq: Add a notifer chain that governors can use to report information
Some modules can benefit from getting additional information cpufreq governors use to make frequency switch decisions. This change lays down a basic framework that the governors can use to report additional information (Eg: CPU's load) information to the clients that subscribe to cpufreq govinfo notifier chain. Change-Id: I511b4bdb7d12394a31ce5352ae47553861e49303 Signed-off-by: Rohit Gupta <rohgup@codeaurora.org> [imaund@codeaurora.org: resolved context conflicts] Signed-off-by: Ian Maund <imaund@codeaurora.org>
-rw-r--r--drivers/cpufreq/cpufreq.c21
-rw-r--r--include/linux/cpufreq.h14
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e49512718325..f897a7dec97d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -127,6 +127,7 @@ static void handle_update(struct work_struct *work);
*/
static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
static struct srcu_notifier_head cpufreq_transition_notifier_list;
+struct atomic_notifier_head cpufreq_govinfo_notifier_list;
static bool init_cpufreq_transition_notifier_list_called;
static int __init init_cpufreq_transition_notifier_list(void)
@@ -137,6 +138,15 @@ static int __init init_cpufreq_transition_notifier_list(void)
}
pure_initcall(init_cpufreq_transition_notifier_list);
+static bool init_cpufreq_govinfo_notifier_list_called;
+static int __init init_cpufreq_govinfo_notifier_list(void)
+{
+ ATOMIC_INIT_NOTIFIER_HEAD(&cpufreq_govinfo_notifier_list);
+ init_cpufreq_govinfo_notifier_list_called = true;
+ return 0;
+}
+pure_initcall(init_cpufreq_govinfo_notifier_list);
+
static int off __read_mostly;
static int cpufreq_disabled(void)
{
@@ -1703,7 +1713,8 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
if (cpufreq_disabled())
return -EINVAL;
- WARN_ON(!init_cpufreq_transition_notifier_list_called);
+ WARN_ON(!init_cpufreq_transition_notifier_list_called ||
+ !init_cpufreq_govinfo_notifier_list_called);
switch (list) {
case CPUFREQ_TRANSITION_NOTIFIER:
@@ -1714,6 +1725,10 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
ret = blocking_notifier_chain_register(
&cpufreq_policy_notifier_list, nb);
break;
+ case CPUFREQ_GOVINFO_NOTIFIER:
+ ret = atomic_notifier_chain_register(
+ &cpufreq_govinfo_notifier_list, nb);
+ break;
default:
ret = -EINVAL;
}
@@ -1748,6 +1763,10 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
ret = blocking_notifier_chain_unregister(
&cpufreq_policy_notifier_list, nb);
break;
+ case CPUFREQ_GOVINFO_NOTIFIER:
+ ret = atomic_notifier_chain_unregister(
+ &cpufreq_govinfo_notifier_list, nb);
+ break;
default:
ret = -EINVAL;
}
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3ac01621cd1f..af746a212e88 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -361,6 +361,7 @@ static inline void cpufreq_resume(void) {}
#define CPUFREQ_TRANSITION_NOTIFIER (0)
#define CPUFREQ_POLICY_NOTIFIER (1)
+#define CPUFREQ_GOVINFO_NOTIFIER (2)
/* Transition notifiers */
#define CPUFREQ_PRECHANGE (0)
@@ -373,6 +374,9 @@ static inline void cpufreq_resume(void) {}
#define CPUFREQ_CREATE_POLICY (3)
#define CPUFREQ_REMOVE_POLICY (4)
+/* Govinfo Notifiers */
+#define CPUFREQ_LOAD_CHANGE (0)
+
#ifdef CONFIG_CPU_FREQ
int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);
int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
@@ -381,6 +385,16 @@ void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
struct cpufreq_freqs *freqs);
void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
struct cpufreq_freqs *freqs, int transition_failed);
+/*
+ * Governor specific info that can be passed to modules that subscribe
+ * to CPUFREQ_GOVINFO_NOTIFIER
+ */
+struct cpufreq_govinfo {
+ unsigned int cpu;
+ unsigned int load;
+ unsigned int sampling_rate_us;
+};
+extern struct atomic_notifier_head cpufreq_govinfo_notifier_list;
#else /* CONFIG_CPU_FREQ */
static inline int cpufreq_register_notifier(struct notifier_block *nb,