aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/clocksource.h2
-rw-r--r--kernel/time/clocksource.c33
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
284extern int clocksource_register(struct clocksource*); 284extern int clocksource_register(struct clocksource*);
285extern void clocksource_unregister(struct clocksource*); 285extern int clocksource_unregister(struct clocksource*);
286extern void clocksource_touch_watchdog(void); 286extern void clocksource_touch_watchdog(void);
287extern struct clocksource* clocksource_get_next(void); 287extern struct clocksource* clocksource_get_next(void);
288extern void clocksource_change_rating(struct clocksource *cs, int rating); 288extern 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
390static void clocksource_dequeue_watchdog(struct clocksource *cs) 390static 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 */
844void clocksource_unregister(struct clocksource *cs) 833int 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}
852EXPORT_SYMBOL(clocksource_unregister); 843EXPORT_SYMBOL(clocksource_unregister);
853 844