Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=dc559f7cd5d6d11a99b6c29402b31fbb3f3a1db0
Commit:     dc559f7cd5d6d11a99b6c29402b31fbb3f3a1db0
Parent:     e5d8d54db25790524da34b0143f4e0176fb7677b
Author:     Olof Johansson <[EMAIL PROTECTED]>
AuthorDate: Wed Aug 22 12:26:43 2007 +1000
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Wed Aug 22 15:37:11 2007 +1000

    [POWERPC] Rework SMP timebase handoff for pasemi
    
    Rework timebase handoff to play nice with configurations with more than
    2 cores, as well as with CPU hotplug.
    
    Previous scheme just pushed out the current timebase from the giving
    core to all cores without caring if they wanted it or not, nor checking
    if they'd taken it. The taking side didn't make sure the giving side
    had provided a value yet either. In other words, it was completely broken.
    
    Signed-off-by: Olof Johansson <[EMAIL PROTECTED]>
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/platforms/pasemi/setup.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pasemi/setup.c 
b/arch/powerpc/platforms/pasemi/setup.c
index ffe6528..05def62 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)
 
 #ifdef CONFIG_SMP
 static DEFINE_SPINLOCK(timebase_lock);
+static unsigned long timebase;
 
 static void __devinit pas_give_timebase(void)
 {
-       unsigned long tb;
-
        spin_lock(&timebase_lock);
        mtspr(SPRN_TBCTL, TBCTL_FREEZE);
-       tb = mftb();
-       mtspr(SPRN_TBCTL, TBCTL_UPDATE_LOWER | (tb & 0xffffffff));
-       mtspr(SPRN_TBCTL, TBCTL_UPDATE_UPPER | (tb >> 32));
-       mtspr(SPRN_TBCTL, TBCTL_RESTART);
+       isync();
+       timebase = get_tb();
        spin_unlock(&timebase_lock);
-       pr_debug("pas_give_timebase: cpu %d gave tb %lx\n",
-                smp_processor_id(), tb);
+
+       while (timebase)
+               barrier();
+       mtspr(SPRN_TBCTL, TBCTL_RESTART);
 }
 
 static void __devinit pas_take_timebase(void)
 {
-       pr_debug("pas_take_timebase: cpu %d has tb %lx\n",
-                smp_processor_id(), mftb());
+       while (!timebase)
+               smp_rmb();
+
+       spin_lock(&timebase_lock);
+       set_tb(timebase >> 32, timebase & 0xffffffff);
+       timebase = 0;
+       spin_unlock(&timebase_lock);
 }
 
 struct smp_ops_t pas_smp_ops = {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to