diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-02-03 17:34:31 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-02-07 09:34:28 -0500 |
commit | 627ee7947e2e83ba565c31c5c9373d6e364b1ecd (patch) | |
tree | 30fc40a08542f0411e28ba9becc00e07f7ec3b44 /kernel/time/clockevents.c | |
parent | e8b175946c16d7001b22620f52d78ab497efc9d0 (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.c | 29 |
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 | } |
440 | EXPORT_SYMBOL_GPL(clockevents_config_and_register); | 440 | EXPORT_SYMBOL_GPL(clockevents_config_and_register); |
441 | 441 | ||
442 | int __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 | */ |
452 | int clockevents_update_freq(struct clock_event_device *dev, u32 freq) | 464 | int 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 | /* |