Quoting Viresh Kumar (2014-09-29 01:54:51)
On 27 September 2014 15:44, Mike Turquette mike.turquette@linaro.org wrote:
I have another use case for exposing driver flags and I have created a similar patch to this locally in my git tree.
Basically some cpufreq drivers may block or sleep during their .set_target callback, and others will not. E.g. the former case is the common pattern to use the clock framework and the regulator framework, both of which hold mutexes and may have slow operations and the latter case is more like the Intel P-state driver with just some register writes.
For the energy-aware scheduling work it is desirable to know if the cpufreq driver can do a "fast" transition of it might sleep, since that affects whether we adjust the cpu frequency from the scheduler context of whether need to put new work on the workqueue (e.g. waking up a kthread dedicated to calling .set_target).
I wasn't against exposing the flags but using the same variable to store driver specific data.
For reference, here is a patch that I've had locally in my tree for a couples months. I'm using it while prototyping some ways to integrate CPUfreq with the scheduler. It is almost identical to Thomas's approach but it doesn't try to mask off some flags. Additionally it does NOT change the u8 return type, which is currently how struct cpufreq_driver->flags is defined today. This is probably not good and should be an unsigned int or unsigned long so that the api is a bit more forward-looking.
Thoughts?
Thanks, Mike
From 0053dfc6b09fa0c5923b7dcba23b67c1c005cb88 Mon Sep 17 00:00:00 2001 From: Mike Turquette mturquette@linaro.org Date: Sun, 3 Aug 2014 21:25:38 -0700 Subject: [PATCH] cpufreq: new function to query driver for flags
Signed-off-by: Mike Turquette mturquette@linaro.org --- drivers/cpufreq/cpufreq.c | 9 +++++++++ include/linux/cpufreq.h | 1 + 2 files changed, 10 insertions(+)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1abb44d..515e905 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2003,6 +2003,15 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_driver_target);
+u8 cpufreq_driver_get_flags(void) +{ + if (!cpufreq_driver) + return 0; + + return cpufreq_driver->flags; +} +EXPORT_SYMBOL_GPL(cpufreq_driver_get_flags); + /* * when "event" is CPUFREQ_GOV_LIMITS */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 221f0eb..5a97f5f 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -417,6 +417,7 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); +u8 cpufreq_driver_get_flags(void); int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor);