diff options
author | Graf Yang <graf.yang@analog.com> | 2010-01-28 05:46:55 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2011-03-18 04:01:03 -0400 |
commit | 6f546bc3ac9eedbf770bf3bcbc45ce2ea32c94ad (patch) | |
tree | 7089509d165a19156c3be21950f96160fb1f06a1 /arch/blackfin/mach-common | |
parent | 820b127dae869cbbd2133f066e8b8f32a90d46e5 (diff) |
Blackfin: SMP: implement cpu_freq support
Re-use some of the existing cpu hotplugging code in the process.
Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/cpufreq.c | 2 | ||||
-rw-r--r-- | arch/blackfin/mach-common/dpmc.c | 50 |
2 files changed, 48 insertions, 4 deletions
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index f4cf11d362e1..c33fb61b5082 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c | |||
@@ -16,8 +16,6 @@ | |||
16 | #include <asm/time.h> | 16 | #include <asm/time.h> |
17 | #include <asm/dpmc.h> | 17 | #include <asm/dpmc.h> |
18 | 18 | ||
19 | #define CPUFREQ_CPU 0 | ||
20 | |||
21 | /* this is the table of CCLK frequencies, in Hz */ | 19 | /* this is the table of CCLK frequencies, in Hz */ |
22 | /* .index is the entry in the auxillary dpm_state_table[] */ | 20 | /* .index is the entry in the auxillary dpm_state_table[] */ |
23 | static struct cpufreq_frequency_table bfin_freq_table[] = { | 21 | static struct cpufreq_frequency_table bfin_freq_table[] = { |
diff --git a/arch/blackfin/mach-common/dpmc.c b/arch/blackfin/mach-common/dpmc.c index 02c7efd1bcf4..382099fd5561 100644 --- a/arch/blackfin/mach-common/dpmc.c +++ b/arch/blackfin/mach-common/dpmc.c | |||
@@ -61,17 +61,63 @@ err_out: | |||
61 | } | 61 | } |
62 | 62 | ||
63 | #ifdef CONFIG_CPU_FREQ | 63 | #ifdef CONFIG_CPU_FREQ |
64 | # ifdef CONFIG_SMP | ||
65 | static void bfin_idle_this_cpu(void *info) | ||
66 | { | ||
67 | unsigned long flags = 0; | ||
68 | unsigned long iwr0, iwr1, iwr2; | ||
69 | unsigned int cpu = smp_processor_id(); | ||
70 | |||
71 | local_irq_save_hw(flags); | ||
72 | bfin_iwr_set_sup0(&iwr0, &iwr1, &iwr2); | ||
73 | |||
74 | platform_clear_ipi(cpu, IRQ_SUPPLE_0); | ||
75 | SSYNC(); | ||
76 | asm("IDLE;"); | ||
77 | bfin_iwr_restore(iwr0, iwr1, iwr2); | ||
78 | |||
79 | local_irq_restore_hw(flags); | ||
80 | } | ||
81 | |||
82 | static void bfin_idle_cpu(void) | ||
83 | { | ||
84 | smp_call_function(bfin_idle_this_cpu, NULL, 0); | ||
85 | } | ||
86 | |||
87 | static void bfin_wakeup_cpu(void) | ||
88 | { | ||
89 | unsigned int cpu; | ||
90 | unsigned int this_cpu = smp_processor_id(); | ||
91 | cpumask_t mask = cpu_online_map; | ||
92 | |||
93 | cpu_clear(this_cpu, mask); | ||
94 | for_each_cpu_mask(cpu, mask) | ||
95 | platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0); | ||
96 | } | ||
97 | |||
98 | # else | ||
99 | static void bfin_idle_cpu(void) {} | ||
100 | static void bfin_wakeup_cpu(void) {} | ||
101 | # endif | ||
102 | |||
64 | static int | 103 | static int |
65 | vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) | 104 | vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) |
66 | { | 105 | { |
67 | struct cpufreq_freqs *freq = data; | 106 | struct cpufreq_freqs *freq = data; |
68 | 107 | ||
108 | if (freq->cpu != CPUFREQ_CPU) | ||
109 | return 0; | ||
110 | |||
69 | if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) { | 111 | if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) { |
112 | bfin_idle_cpu(); | ||
70 | bfin_set_vlev(bfin_get_vlev(freq->new)); | 113 | bfin_set_vlev(bfin_get_vlev(freq->new)); |
71 | udelay(pdata->vr_settling_time); /* Wait until Volatge settled */ | 114 | udelay(pdata->vr_settling_time); /* Wait until Volatge settled */ |
72 | 115 | bfin_wakeup_cpu(); | |
73 | } else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) | 116 | } else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) { |
117 | bfin_idle_cpu(); | ||
74 | bfin_set_vlev(bfin_get_vlev(freq->new)); | 118 | bfin_set_vlev(bfin_get_vlev(freq->new)); |
119 | bfin_wakeup_cpu(); | ||
120 | } | ||
75 | 121 | ||
76 | return 0; | 122 | return 0; |
77 | } | 123 | } |