aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/clockevents.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-02-03 17:34:31 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-02-07 09:34:28 -0500
commit627ee7947e2e83ba565c31c5c9373d6e364b1ecd (patch)
tree30fc40a08542f0411e28ba9becc00e07f7ec3b44 /kernel/time/clockevents.c
parente8b175946c16d7001b22620f52d78ab497efc9d0 (diff)
clockevents: Serialize calls to clockevents_update_freq() in the core
We can identify the broadcast device in the core and serialize all callers including interrupts on a different CPU against the update. Also, disabling interrupts is moved into the core allowing callers to leave interrutps enabled when calling clockevents_update_freq(). Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> Cc: linux-arm-kernel@lists.infradead.org Cc: Soeren Brinkmann <soren.brinkmann@xilinx.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Michal Simek <michal.simek@xilinx.com> Link: http://lkml.kernel.org/r/1391466877-28908-2-git-send-email-soren.brinkmann@xilinx.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time/clockevents.c')
-rw-r--r--kernel/time/clockevents.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 086ad6043bcb..641d91003a45 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -439,6 +439,16 @@ void clockevents_config_and_register(struct clock_event_device *dev,
439} 439}
440EXPORT_SYMBOL_GPL(clockevents_config_and_register); 440EXPORT_SYMBOL_GPL(clockevents_config_and_register);
441 441
442int __clockevents_update_freq(struct clock_event_device *dev, u32 freq)
443{
444 clockevents_config(dev, freq);
445
446 if (dev->mode != CLOCK_EVT_MODE_ONESHOT)
447 return 0;
448
449 return clockevents_program_event(dev, dev->next_event, false);
450}
451
442/** 452/**
443 * clockevents_update_freq - Update frequency and reprogram a clock event device. 453 * clockevents_update_freq - Update frequency and reprogram a clock event device.
444 * @dev: device to modify 454 * @dev: device to modify
@@ -446,17 +456,22 @@ EXPORT_SYMBOL_GPL(clockevents_config_and_register);
446 * 456 *
447 * Reconfigure and reprogram a clock event device in oneshot 457 * Reconfigure and reprogram a clock event device in oneshot
448 * mode. Must be called on the cpu for which the device delivers per 458 * mode. Must be called on the cpu for which the device delivers per
449 * cpu timer events with interrupts disabled! Returns 0 on success, 459 * cpu timer events. If called for the broadcast device the core takes
450 * -ETIME when the event is in the past. 460 * care of serialization.
461 *
462 * Returns 0 on success, -ETIME when the event is in the past.
451 */ 463 */
452int clockevents_update_freq(struct clock_event_device *dev, u32 freq) 464int clockevents_update_freq(struct clock_event_device *dev, u32 freq)
453{ 465{
454 clockevents_config(dev, freq); 466 unsigned long flags;
455 467 int ret;
456 if (dev->mode != CLOCK_EVT_MODE_ONESHOT)
457 return 0;
458 468
459 return clockevents_program_event(dev, dev->next_event, false); 469 local_irq_save(flags);
470 ret = tick_broadcast_update_freq(dev, freq);
471 if (ret == -ENODEV)
472 ret = __clockevents_update_freq(dev, freq);
473 local_irq_restore(flags);
474 return ret;
460} 475}
461 476
462/* 477/*