diff options
-rw-r--r-- | include/linux/clocksource.h | 2 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 33 |
2 files changed, 13 insertions, 22 deletions
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 32a895b114d8..2f39a4911668 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -282,7 +282,7 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift) | |||
282 | 282 | ||
283 | 283 | ||
284 | extern int clocksource_register(struct clocksource*); | 284 | extern int clocksource_register(struct clocksource*); |
285 | extern void clocksource_unregister(struct clocksource*); | 285 | extern int clocksource_unregister(struct clocksource*); |
286 | extern void clocksource_touch_watchdog(void); | 286 | extern void clocksource_touch_watchdog(void); |
287 | extern struct clocksource* clocksource_get_next(void); | 287 | extern struct clocksource* clocksource_get_next(void); |
288 | extern void clocksource_change_rating(struct clocksource *cs, int rating); | 288 | extern void clocksource_change_rating(struct clocksource *cs, int rating); |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 791d1aeb17ac..31b90332f47b 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -389,28 +389,17 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs) | |||
389 | 389 | ||
390 | static void clocksource_dequeue_watchdog(struct clocksource *cs) | 390 | static void clocksource_dequeue_watchdog(struct clocksource *cs) |
391 | { | 391 | { |
392 | struct clocksource *tmp; | ||
393 | unsigned long flags; | 392 | unsigned long flags; |
394 | 393 | ||
395 | spin_lock_irqsave(&watchdog_lock, flags); | 394 | spin_lock_irqsave(&watchdog_lock, flags); |
396 | if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { | 395 | if (cs != watchdog) { |
397 | /* cs is a watched clocksource. */ | 396 | if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { |
398 | list_del_init(&cs->wd_list); | 397 | /* cs is a watched clocksource. */ |
399 | } else if (cs == watchdog) { | 398 | list_del_init(&cs->wd_list); |
400 | /* Reset watchdog cycles */ | 399 | /* Check if the watchdog timer needs to be stopped. */ |
401 | clocksource_reset_watchdog(); | 400 | clocksource_stop_watchdog(); |
402 | /* Current watchdog is removed. Find an alternative. */ | ||
403 | watchdog = NULL; | ||
404 | list_for_each_entry(tmp, &clocksource_list, list) { | ||
405 | if (tmp == cs || tmp->flags & CLOCK_SOURCE_MUST_VERIFY) | ||
406 | continue; | ||
407 | if (!watchdog || tmp->rating > watchdog->rating) | ||
408 | watchdog = tmp; | ||
409 | } | 401 | } |
410 | } | 402 | } |
411 | cs->flags &= ~CLOCK_SOURCE_WATCHDOG; | ||
412 | /* Check if the watchdog timer needs to be stopped. */ | ||
413 | clocksource_stop_watchdog(); | ||
414 | spin_unlock_irqrestore(&watchdog_lock, flags); | 403 | spin_unlock_irqrestore(&watchdog_lock, flags); |
415 | } | 404 | } |
416 | 405 | ||
@@ -841,13 +830,15 @@ static int clocksource_unbind(struct clocksource *cs) | |||
841 | * clocksource_unregister - remove a registered clocksource | 830 | * clocksource_unregister - remove a registered clocksource |
842 | * @cs: clocksource to be unregistered | 831 | * @cs: clocksource to be unregistered |
843 | */ | 832 | */ |
844 | void clocksource_unregister(struct clocksource *cs) | 833 | int clocksource_unregister(struct clocksource *cs) |
845 | { | 834 | { |
835 | int ret = 0; | ||
836 | |||
846 | mutex_lock(&clocksource_mutex); | 837 | mutex_lock(&clocksource_mutex); |
847 | clocksource_dequeue_watchdog(cs); | 838 | if (!list_empty(&cs->list)) |
848 | list_del(&cs->list); | 839 | ret = clocksource_unbind(cs); |
849 | clocksource_select(); | ||
850 | mutex_unlock(&clocksource_mutex); | 840 | mutex_unlock(&clocksource_mutex); |
841 | return ret; | ||
851 | } | 842 | } |
852 | EXPORT_SYMBOL(clocksource_unregister); | 843 | EXPORT_SYMBOL(clocksource_unregister); |
853 | 844 | ||