diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-06-16 12:42:50 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-06-26 02:55:25 -0400 |
commit | c4007a2fbf5f82b7e694c22b5929c87e38415a56 (patch) | |
tree | 9f959ef72a62eea0638cd2b1ed85a6b2e7fb3a70 /arch/powerpc/platforms/chrp | |
parent | f97bb36f705da0a86b3ea77bfeee3415fee0b025 (diff) |
powerpc: Use one common impl. of RTAS timebase sync and use raw spinlock
Several platforms use their own copy of what is essentially the same code,
using RTAS to synchronize the timebases when bringing up new CPUs. This
moves it all into a single common implementation and additionally
turns the spinlock into a raw spinlock since the former can rely on
the timebase not being frozen when spinlock debugging is enabled, and finally
masks interrupts while the timebase is disabled.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/chrp')
-rw-r--r-- | arch/powerpc/platforms/chrp/smp.c | 33 |
1 files changed, 2 insertions, 31 deletions
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index 10a4a4d063b6..02cafecc90e3 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/prom.h> | 27 | #include <asm/prom.h> |
28 | #include <asm/smp.h> | 28 | #include <asm/smp.h> |
29 | #include <asm/time.h> | ||
30 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
31 | #include <asm/mpic.h> | 30 | #include <asm/mpic.h> |
32 | #include <asm/rtas.h> | 31 | #include <asm/rtas.h> |
@@ -42,40 +41,12 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr) | |||
42 | mpic_setup_this_cpu(); | 41 | mpic_setup_this_cpu(); |
43 | } | 42 | } |
44 | 43 | ||
45 | static DEFINE_SPINLOCK(timebase_lock); | ||
46 | static unsigned int timebase_upper = 0, timebase_lower = 0; | ||
47 | |||
48 | void __devinit smp_chrp_give_timebase(void) | ||
49 | { | ||
50 | spin_lock(&timebase_lock); | ||
51 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
52 | timebase_upper = get_tbu(); | ||
53 | timebase_lower = get_tbl(); | ||
54 | spin_unlock(&timebase_lock); | ||
55 | |||
56 | while (timebase_upper || timebase_lower) | ||
57 | barrier(); | ||
58 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
59 | } | ||
60 | |||
61 | void __devinit smp_chrp_take_timebase(void) | ||
62 | { | ||
63 | while (!(timebase_upper || timebase_lower)) | ||
64 | barrier(); | ||
65 | spin_lock(&timebase_lock); | ||
66 | set_tb(timebase_upper, timebase_lower); | ||
67 | timebase_upper = 0; | ||
68 | timebase_lower = 0; | ||
69 | spin_unlock(&timebase_lock); | ||
70 | printk("CPU %i taken timebase\n", smp_processor_id()); | ||
71 | } | ||
72 | |||
73 | /* CHRP with openpic */ | 44 | /* CHRP with openpic */ |
74 | struct smp_ops_t chrp_smp_ops = { | 45 | struct smp_ops_t chrp_smp_ops = { |
75 | .message_pass = smp_mpic_message_pass, | 46 | .message_pass = smp_mpic_message_pass, |
76 | .probe = smp_mpic_probe, | 47 | .probe = smp_mpic_probe, |
77 | .kick_cpu = smp_chrp_kick_cpu, | 48 | .kick_cpu = smp_chrp_kick_cpu, |
78 | .setup_cpu = smp_chrp_setup_cpu, | 49 | .setup_cpu = smp_chrp_setup_cpu, |
79 | .give_timebase = smp_chrp_give_timebase, | 50 | .give_timebase = rtas_give_timebase, |
80 | .take_timebase = smp_chrp_take_timebase, | 51 | .take_timebase = rtas_take_timebase, |
81 | }; | 52 | }; |