diff options
author | Nicolas Pitre <nicolas.pitre@linaro.org> | 2012-12-11 00:20:29 -0500 |
---|---|---|
committer | Andrey Konovalov <andrey.konovalov@linaro.org> | 2013-05-25 13:26:01 +0400 |
commit | 14444b5121a9856bfd90eb5ea7f94b1246d67364 (patch) | |
tree | a10c6fca575e89360dcf3dcb693ed666ccdca204 | |
parent | 5558228276d0791637041e1616e1071509741db9 (diff) |
cpufreq: arm_big_little: Unregister/register cpufreq driver with switcher notifiers
Cpufreq driver must be unregistered/registered on switcher on/off to get correct
freq tables for all cpus. This patch does it.
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
-rw-r--r-- | drivers/cpufreq/arm_big_little.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index eb771c213a2..a209cbfe1ab 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -31,9 +31,12 @@ #include "arm_big_little.h" #ifdef CONFIG_BL_SWITCHER -#define is_bL_switching_enabled() true +static bool bL_switching_enabled; +#define is_bL_switching_enabled() bL_switching_enabled +#define set_switching_enabled(x) (bL_switching_enabled = (x)) #else #define is_bL_switching_enabled() false +#define set_switching_enabled(x) do { } while (0) #endif #define A15_CLUSTER 0 @@ -457,6 +460,38 @@ static struct cpufreq_driver bL_cpufreq_driver = { .attr = bL_cpufreq_attr, }; +static int bL_cpufreq_switcher_notifier(struct notifier_block *nfb, + unsigned long action, void *_arg) +{ + pr_debug("%s: action: %ld\n", __func__, action); + + switch (action) { + case BL_NOTIFY_PRE_ENABLE: + case BL_NOTIFY_PRE_DISABLE: + cpufreq_unregister_driver(&bL_cpufreq_driver); + break; + + case BL_NOTIFY_POST_ENABLE: + set_switching_enabled(true); + cpufreq_register_driver(&bL_cpufreq_driver); + break; + + case BL_NOTIFY_POST_DISABLE: + set_switching_enabled(false); + cpufreq_register_driver(&bL_cpufreq_driver); + break; + + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block bL_switcher_notifier = { + .notifier_call = bL_cpufreq_switcher_notifier, +}; + int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) { int ret; @@ -474,16 +509,26 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) arm_bL_ops = ops; + ret = bL_switcher_get_enabled(); + set_switching_enabled(ret); + ret = cpufreq_register_driver(&bL_cpufreq_driver); if (ret) { pr_info("%s: Failed registering platform driver: %s, err: %d\n", __func__, ops->name, ret); arm_bL_ops = NULL; } else { - pr_info("%s: Registered platform driver: %s\n", __func__, - ops->name); + ret = bL_switcher_register_notifier(&bL_switcher_notifier); + if (ret) { + cpufreq_unregister_driver(&bL_cpufreq_driver); + arm_bL_ops = NULL; + } else { + pr_info("%s: Registered platform driver: %s\n", + __func__, ops->name); + } } + bL_switcher_put_enabled(); return ret; } EXPORT_SYMBOL_GPL(bL_cpufreq_register); @@ -495,7 +540,10 @@ void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops) __func__, arm_bL_ops->name); } + bL_switcher_get_enabled(); + bL_switcher_unregister_notifier(&bL_switcher_notifier); cpufreq_unregister_driver(&bL_cpufreq_driver); + bL_switcher_put_enabled(); pr_info("%s: Un-registered platform driver: %s\n", __func__, arm_bL_ops->name); arm_bL_ops = NULL; |