aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pasemi/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pasemi/setup.c')
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index ffe6528048b5..05def6282f83 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -50,26 +50,30 @@ static void pas_restart(char *cmd)
50 50
51#ifdef CONFIG_SMP 51#ifdef CONFIG_SMP
52static DEFINE_SPINLOCK(timebase_lock); 52static DEFINE_SPINLOCK(timebase_lock);
53static unsigned long timebase;
53 54
54static void __devinit pas_give_timebase(void) 55static void __devinit pas_give_timebase(void)
55{ 56{
56 unsigned long tb;
57
58 spin_lock(&timebase_lock); 57 spin_lock(&timebase_lock);
59 mtspr(SPRN_TBCTL, TBCTL_FREEZE); 58 mtspr(SPRN_TBCTL, TBCTL_FREEZE);
60 tb = mftb(); 59 isync();
61 mtspr(SPRN_TBCTL, TBCTL_UPDATE_LOWER | (tb & 0xffffffff)); 60 timebase = get_tb();
62 mtspr(SPRN_TBCTL, TBCTL_UPDATE_UPPER | (tb >> 32));
63 mtspr(SPRN_TBCTL, TBCTL_RESTART);
64 spin_unlock(&timebase_lock); 61 spin_unlock(&timebase_lock);
65 pr_debug("pas_give_timebase: cpu %d gave tb %lx\n", 62
66 smp_processor_id(), tb); 63 while (timebase)
64 barrier();
65 mtspr(SPRN_TBCTL, TBCTL_RESTART);
67} 66}
68 67
69static void __devinit pas_take_timebase(void) 68static void __devinit pas_take_timebase(void)
70{ 69{
71 pr_debug("pas_take_timebase: cpu %d has tb %lx\n", 70 while (!timebase)
72 smp_processor_id(), mftb()); 71 smp_rmb();
72
73 spin_lock(&timebase_lock);
74 set_tb(timebase >> 32, timebase & 0xffffffff);
75 timebase = 0;
76 spin_unlock(&timebase_lock);
73} 77}
74 78
75struct smp_ops_t pas_smp_ops = { 79struct smp_ops_t pas_smp_ops = {