From be00c1b2a2c38fb4c47c767cfbf87188a8764ba8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 14 Oct 2007 22:57:45 +0200 Subject: [PATCH] --- yaml --- r: 68759 b: refs/heads/master c: 1595f452f3d8daa066bfd3ba4120754bed3329e1 h: refs/heads/master i: 68757: 25f8a70d7339695243266ed8f00b1c712ce68937 68755: e82f6d1f85edc6ec63d1fb93286a1ae3b2c1b74d 68751: 4d868d8f2e45029991aef551f3164b6ee28d82e6 v: v3 --- [refs] | 2 +- trunk/include/linux/clockchips.h | 1 + trunk/kernel/time/tick-broadcast.c | 29 +++++++++++++++++++++++------ trunk/kernel/time/tick-common.c | 1 + 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index f7a87917f2e4..cc426c4a16dc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b097976e8d6f6e6220161fa6b72b0798ce9f4f4c +refs/heads/master: 1595f452f3d8daa066bfd3ba4120754bed3329e1 diff --git a/trunk/include/linux/clockchips.h b/trunk/include/linux/clockchips.h index d2ddea926895..c33b0dc28e4d 100644 --- a/trunk/include/linux/clockchips.h +++ b/trunk/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/trunk/kernel/time/tick-broadcast.c b/trunk/kernel/time/tick-broadcast.c index 298bc7c6f09f..fc3fc79b3d59 100644 --- a/trunk/kernel/time/tick-broadcast.c +++ b/trunk/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/trunk/kernel/time/tick-common.c b/trunk/kernel/time/tick-common.c index 3f3ae3907830..1bea399a9ef0 100644 --- a/trunk/kernel/time/tick-common.c +++ b/trunk/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;