diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2015-03-25 08:09:16 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-04-01 08:22:59 -0400 |
commit | 4ffee521f36390c7720d493591b764ca35c8030b (patch) | |
tree | 9836af97487f83a0680c293f187cd116875ec2c5 /kernel/time | |
parent | db6f672ef11d7a3c5aa128a3c3e57c92580a25f7 (diff) |
clockevents: Make suspend/resume calls explicit
clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call.
We are way better off to have explicit calls instead of this
monstrosity. Split out the suspend/resume() calls and invoke
them directly from the call sites.
No locking required at this point because these calls happen
with interrupts disabled and a single cpu online.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ Rebased on top of 4.0-rc5. ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/713674030.jVm1qaHuPf@vostro.rjw.lan
[ Rebased on top of latest timers/core. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/clockevents.c | 9 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 26 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 3 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 6 |
4 files changed, 27 insertions, 17 deletions
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index b73002718536..7af614829da1 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -670,15 +670,6 @@ int clockevents_notify(unsigned long reason, void *arg) | |||
670 | tick_handover_do_timer(arg); | 670 | tick_handover_do_timer(arg); |
671 | break; | 671 | break; |
672 | 672 | ||
673 | case CLOCK_EVT_NOTIFY_SUSPEND: | ||
674 | tick_suspend(); | ||
675 | tick_suspend_broadcast(); | ||
676 | break; | ||
677 | |||
678 | case CLOCK_EVT_NOTIFY_RESUME: | ||
679 | tick_resume(); | ||
680 | break; | ||
681 | |||
682 | case CLOCK_EVT_NOTIFY_CPU_DEAD: | 673 | case CLOCK_EVT_NOTIFY_CPU_DEAD: |
683 | tick_shutdown_broadcast_oneshot(arg); | 674 | tick_shutdown_broadcast_oneshot(arg); |
684 | tick_shutdown_broadcast(arg); | 675 | tick_shutdown_broadcast(arg); |
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index a5b877130ae9..1a60c2ae96a8 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -373,18 +373,39 @@ void tick_shutdown(unsigned int *cpup) | |||
373 | } | 373 | } |
374 | } | 374 | } |
375 | 375 | ||
376 | /** | ||
377 | * tick_suspend - Suspend the tick and the broadcast device | ||
378 | * | ||
379 | * Called from syscore_suspend() via timekeeping_suspend with only one | ||
380 | * CPU online and interrupts disabled or from tick_unfreeze() under | ||
381 | * tick_freeze_lock. | ||
382 | * | ||
383 | * No locks required. Nothing can change the per cpu device. | ||
384 | */ | ||
376 | void tick_suspend(void) | 385 | void tick_suspend(void) |
377 | { | 386 | { |
378 | struct tick_device *td = this_cpu_ptr(&tick_cpu_device); | 387 | struct tick_device *td = this_cpu_ptr(&tick_cpu_device); |
379 | 388 | ||
380 | clockevents_shutdown(td->evtdev); | 389 | clockevents_shutdown(td->evtdev); |
390 | tick_suspend_broadcast(); | ||
381 | } | 391 | } |
382 | 392 | ||
393 | /** | ||
394 | * tick_resume - Resume the tick and the broadcast device | ||
395 | * | ||
396 | * Called from syscore_resume() via timekeeping_resume with only one | ||
397 | * CPU online and interrupts disabled or from tick_unfreeze() under | ||
398 | * tick_freeze_lock. | ||
399 | * | ||
400 | * No locks required. Nothing can change the per cpu device. | ||
401 | */ | ||
383 | void tick_resume(void) | 402 | void tick_resume(void) |
384 | { | 403 | { |
385 | struct tick_device *td = this_cpu_ptr(&tick_cpu_device); | 404 | struct tick_device *td; |
386 | int broadcast = tick_resume_broadcast(); | 405 | int broadcast; |
387 | 406 | ||
407 | broadcast = tick_resume_broadcast(); | ||
408 | td = this_cpu_ptr(&tick_cpu_device); | ||
388 | clockevents_tick_resume(td->evtdev); | 409 | clockevents_tick_resume(td->evtdev); |
389 | 410 | ||
390 | if (!broadcast) { | 411 | if (!broadcast) { |
@@ -416,7 +437,6 @@ void tick_freeze(void) | |||
416 | timekeeping_suspend(); | 437 | timekeeping_suspend(); |
417 | } else { | 438 | } else { |
418 | tick_suspend(); | 439 | tick_suspend(); |
419 | tick_suspend_broadcast(); | ||
420 | } | 440 | } |
421 | 441 | ||
422 | raw_spin_unlock(&tick_freeze_lock); | 442 | raw_spin_unlock(&tick_freeze_lock); |
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index dd2c45d057b9..85a957195bf6 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
@@ -23,7 +23,6 @@ extern void tick_check_new_device(struct clock_event_device *dev); | |||
23 | extern void tick_handover_do_timer(int *cpup); | 23 | extern void tick_handover_do_timer(int *cpup); |
24 | extern void tick_shutdown(unsigned int *cpup); | 24 | extern void tick_shutdown(unsigned int *cpup); |
25 | extern void tick_suspend(void); | 25 | extern void tick_suspend(void); |
26 | extern void tick_resume(void); | ||
27 | extern bool tick_check_replacement(struct clock_event_device *curdev, | 26 | extern bool tick_check_replacement(struct clock_event_device *curdev, |
28 | struct clock_event_device *newdev); | 27 | struct clock_event_device *newdev); |
29 | extern void tick_install_replacement(struct clock_event_device *dev); | 28 | extern void tick_install_replacement(struct clock_event_device *dev); |
@@ -42,6 +41,8 @@ extern void clockevents_exchange_device(struct clock_event_device *old, | |||
42 | extern void clockevents_handle_noop(struct clock_event_device *dev); | 41 | extern void clockevents_handle_noop(struct clock_event_device *dev); |
43 | extern int __clockevents_update_freq(struct clock_event_device *dev, u32 freq); | 42 | extern int __clockevents_update_freq(struct clock_event_device *dev, u32 freq); |
44 | extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt); | 43 | extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt); |
44 | #else | ||
45 | static inline void tick_suspend(void) { } | ||
45 | #endif /* GENERIC_CLOCKEVENTS */ | 46 | #endif /* GENERIC_CLOCKEVENTS */ |
46 | 47 | ||
47 | /* Oneshot related functions */ | 48 | /* Oneshot related functions */ |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index c3fcff06d30a..5b12292b343a 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -1389,9 +1389,7 @@ void timekeeping_resume(void) | |||
1389 | 1389 | ||
1390 | touch_softlockup_watchdog(); | 1390 | touch_softlockup_watchdog(); |
1391 | 1391 | ||
1392 | clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); | 1392 | tick_resume(); |
1393 | |||
1394 | /* Resume hrtimers */ | ||
1395 | hrtimers_resume(); | 1393 | hrtimers_resume(); |
1396 | } | 1394 | } |
1397 | 1395 | ||
@@ -1444,7 +1442,7 @@ int timekeeping_suspend(void) | |||
1444 | write_seqcount_end(&tk_core.seq); | 1442 | write_seqcount_end(&tk_core.seq); |
1445 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 1443 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
1446 | 1444 | ||
1447 | clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); | 1445 | tick_suspend(); |
1448 | clocksource_suspend(); | 1446 | clocksource_suspend(); |
1449 | clockevents_suspend(); | 1447 | clockevents_suspend(); |
1450 | 1448 | ||