Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1595f452f3d8daa066bfd3ba4120754bed3329e1
Commit:     1595f452f3d8daa066bfd3ba4120754bed3329e1
Parent:     b097976e8d6f6e6220161fa6b72b0798ce9f4f4c
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Sun Oct 14 22:57:45 2007 +0200
Committer:  Thomas Gleixner <[EMAIL PROTECTED]>
CommitDate: Sun Oct 14 22:57:45 2007 +0200

    clockevents: introduce force broadcast notifier
    
    The 64bit SMP bootup is slightly different to the 32bit one. It enables
    the boot CPU local APIC timer before all CPUs are brought up. Some AMD C1E
    systems have the C1E feature flag only set in the secondary CPU. Due to
    the early enable of the boot CPU local APIC timer the APIC timer is
    registered as a fully functional device. When we detect the wreckage during
    the bringup of the secondary CPU, we need to force the boot CPU into
    broadcast mode.
    
    Add a new notifier reason and implement the force broadcast in the clock
    events layer.
    
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 include/linux/clockchips.h   |    1 +
 kernel/time/tick-broadcast.c |   29 +++++++++++++++++++++++------
 kernel/time/tick-common.c    |    1 +
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index d2ddea9..c33b0dc 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -31,6 +31,7 @@ enum clock_event_nofitiers {
        CLOCK_EVT_NOTIFY_ADD,
        CLOCK_EVT_NOTIFY_BROADCAST_ON,
        CLOCK_EVT_NOTIFY_BROADCAST_OFF,
+       CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
        CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
        CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
        CLOCK_EVT_NOTIFY_SUSPEND,
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 298bc7c..fc3fc79 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -217,26 +217,43 @@ static void tick_do_broadcast_on_off(void *why)
        bc = tick_broadcast_device.evtdev;
 
        /*
-        * Is the device in broadcast mode forever or is it not
-        * affected by the powerstate ?
+        * Is the device not affected by the powerstate ?
         */
-       if (!dev || !tick_device_is_functional(dev) ||
-           !(dev->features & CLOCK_EVT_FEAT_C3STOP))
+       if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
                goto out;
 
-       if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_ON) {
+       /*
+        * Defect device ?
+        */
+       if (!tick_device_is_functional(dev)) {
+               /*
+                * AMD C1E wreckage fixup:
+                *
+                * Device was registered functional in the first
+                * place. Now the secondary CPU detected the C1E
+                * misfeature and notifies us to fix it up
+                */
+               if (*reason != CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
+                       goto out;
+       }
+
+       switch (*reason) {
+       case CLOCK_EVT_NOTIFY_BROADCAST_ON:
+       case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
                if (!cpu_isset(cpu, tick_broadcast_mask)) {
                        cpu_set(cpu, tick_broadcast_mask);
                        if (td->mode == TICKDEV_MODE_PERIODIC)
                                clockevents_set_mode(dev,
                                                     CLOCK_EVT_MODE_SHUTDOWN);
                }
-       } else {
+               break;
+       case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
                if (cpu_isset(cpu, tick_broadcast_mask)) {
                        cpu_clear(cpu, tick_broadcast_mask);
                        if (td->mode == TICKDEV_MODE_PERIODIC)
                                tick_setup_periodic(dev, 0);
                }
+               break;
        }
 
        if (cpus_empty(tick_broadcast_mask))
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 3f3ae39..1bea399 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -345,6 +345,7 @@ static int tick_notify(struct notifier_block *nb, unsigned 
long reason,
 
        case CLOCK_EVT_NOTIFY_BROADCAST_ON:
        case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
+       case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
                tick_broadcast_on_off(reason, dev);
                break;
 
-
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