diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-09-16 14:32:50 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-09-16 16:47:02 -0400 |
commit | 2344abbcbdb82140050e8be29d3d55e4f6fe860b (patch) | |
tree | 46c1842fc2a47aa4d7ee0c2c558f54bc50772b69 /kernel/time/tick-common.c | |
parent | f1926ce63b996b42772b39e4b47bb4ef4ba748b4 (diff) |
clockevents: make device shutdown robust
The device shut down does not cleanup the next_event variable of the
clock event device. So when the device is reactivated the possible
stale next_event value can prevent the device to be reprogrammed as it
claims to wait on a event already.
This is the root cause of the resurfacing suspend/resume problem,
where systems need key press to come back to life.
Fix this by setting next_event to KTIME_MAX when the device is shut
down. Use a separate function for shutdown which takes care of that
and only keep the direct set mode call in the broadcast code, where we
can not touch the next_event value.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time/tick-common.c')
-rw-r--r-- | kernel/time/tick-common.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index c4777193d567..019315ebf9de 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -249,7 +249,7 @@ static int tick_check_new_device(struct clock_event_device *newdev) | |||
249 | * not give it back to the clockevents layer ! | 249 | * not give it back to the clockevents layer ! |
250 | */ | 250 | */ |
251 | if (tick_is_broadcast_device(curdev)) { | 251 | if (tick_is_broadcast_device(curdev)) { |
252 | clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN); | 252 | clockevents_shutdown(curdev); |
253 | curdev = NULL; | 253 | curdev = NULL; |
254 | } | 254 | } |
255 | clockevents_exchange_device(curdev, newdev); | 255 | clockevents_exchange_device(curdev, newdev); |
@@ -311,7 +311,7 @@ static void tick_suspend(void) | |||
311 | unsigned long flags; | 311 | unsigned long flags; |
312 | 312 | ||
313 | spin_lock_irqsave(&tick_device_lock, flags); | 313 | spin_lock_irqsave(&tick_device_lock, flags); |
314 | clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); | 314 | clockevents_shutdown(td->evtdev); |
315 | spin_unlock_irqrestore(&tick_device_lock, flags); | 315 | spin_unlock_irqrestore(&tick_device_lock, flags); |
316 | } | 316 | } |
317 | 317 | ||