aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index aa4ffe6e5ecf..dea7a925c7e2 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -24,6 +24,7 @@
24#include <linux/percpu.h> 24#include <linux/percpu.h>
25#include <linux/clockchips.h> 25#include <linux/clockchips.h>
26#include <linux/completion.h> 26#include <linux/completion.h>
27#include <linux/cpufreq.h>
27 28
28#include <linux/atomic.h> 29#include <linux/atomic.h>
29#include <asm/smp.h> 30#include <asm/smp.h>
@@ -650,3 +651,56 @@ int setup_profiling_timer(unsigned int multiplier)
650{ 651{
651 return -EINVAL; 652 return -EINVAL;
652} 653}
654
655#ifdef CONFIG_CPU_FREQ
656
657static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
658static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq);
659static unsigned long global_l_p_j_ref;
660static unsigned long global_l_p_j_ref_freq;
661
662static int cpufreq_callback(struct notifier_block *nb,
663 unsigned long val, void *data)
664{
665 struct cpufreq_freqs *freq = data;
666 int cpu = freq->cpu;
667
668 if (freq->flags & CPUFREQ_CONST_LOOPS)
669 return NOTIFY_OK;
670
671 if (!per_cpu(l_p_j_ref, cpu)) {
672 per_cpu(l_p_j_ref, cpu) =
673 per_cpu(cpu_data, cpu).loops_per_jiffy;
674 per_cpu(l_p_j_ref_freq, cpu) = freq->old;
675 if (!global_l_p_j_ref) {
676 global_l_p_j_ref = loops_per_jiffy;
677 global_l_p_j_ref_freq = freq->old;
678 }
679 }
680
681 if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
682 (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
683 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
684 loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
685 global_l_p_j_ref_freq,
686 freq->new);
687 per_cpu(cpu_data, cpu).loops_per_jiffy =
688 cpufreq_scale(per_cpu(l_p_j_ref, cpu),
689 per_cpu(l_p_j_ref_freq, cpu),
690 freq->new);
691 }
692 return NOTIFY_OK;
693}
694
695static struct notifier_block cpufreq_notifier = {
696 .notifier_call = cpufreq_callback,
697};
698
699static int __init register_cpufreq_notifier(void)
700{
701 return cpufreq_register_notifier(&cpufreq_notifier,
702 CPUFREQ_TRANSITION_NOTIFIER);
703}
704core_initcall(register_cpufreq_notifier);
705
706#endif