Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a89c7edb authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

clocksource: Let clocksource_unregister() return success/error



The unregister call can fail, if the clocksource is the current one
and there is no replacement clocksource available. It can also fail,
if the clocksource is the watchdog clocksource and I'm not going to
provide support for this.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Link: http://lkml.kernel.org/r/20130425143436.029915527@linutronix.de


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 7eaeb343
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -282,7 +282,7 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)


extern int clocksource_register(struct clocksource*);
extern void clocksource_unregister(struct clocksource*);
extern int clocksource_unregister(struct clocksource*);
extern void clocksource_touch_watchdog(void);
extern struct clocksource* clocksource_get_next(void);
extern void clocksource_change_rating(struct clocksource *cs, int rating);
+12 −21
Original line number Diff line number Diff line
@@ -389,28 +389,17 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs)

static void clocksource_dequeue_watchdog(struct clocksource *cs)
{
	struct clocksource *tmp;
	unsigned long flags;

	spin_lock_irqsave(&watchdog_lock, flags);
	if (cs != watchdog) {
		if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
			/* cs is a watched clocksource. */
			list_del_init(&cs->wd_list);
	} else if (cs == watchdog) {
		/* Reset watchdog cycles */
		clocksource_reset_watchdog();
		/* Current watchdog is removed. Find an alternative. */
		watchdog = NULL;
		list_for_each_entry(tmp, &clocksource_list, list) {
			if (tmp == cs || tmp->flags & CLOCK_SOURCE_MUST_VERIFY)
				continue;
			if (!watchdog || tmp->rating > watchdog->rating)
				watchdog = tmp;
		}
	}
	cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
			/* Check if the watchdog timer needs to be stopped. */
			clocksource_stop_watchdog();
		}
	}
	spin_unlock_irqrestore(&watchdog_lock, flags);
}

@@ -841,13 +830,15 @@ static int clocksource_unbind(struct clocksource *cs)
 * clocksource_unregister - remove a registered clocksource
 * @cs:	clocksource to be unregistered
 */
void clocksource_unregister(struct clocksource *cs)
int clocksource_unregister(struct clocksource *cs)
{
	int ret = 0;

	mutex_lock(&clocksource_mutex);
	clocksource_dequeue_watchdog(cs);
	list_del(&cs->list);
	clocksource_select();
	if (!list_empty(&cs->list))
		ret = clocksource_unbind(cs);
	mutex_unlock(&clocksource_mutex);
	return ret;
}
EXPORT_SYMBOL(clocksource_unregister);