mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
clocksource: add API to force re-selection of the best clocksource
As the best clocksource is not selected till core boot completion, only periodic tick timer works and it increases jiffies by one at every tick updates. If interrupt is disabled more than one tick(10ms), timer interrupts are missed and jiffies can't be updated at every 10ms and it can be behind the real time. So add API to force re- selection of the best clocksource among registered clocksources so that the best clocksource can be selected whenever it is available. Change-Id: I481de3cdf1df8f0e35ed10aee7ab3882bf7a35b3 Signed-off-by: Se Wang (Patrick) Oh <sewango@codeaurora.org> Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
parent
9fe2640572
commit
f587015e88
2 changed files with 34 additions and 13 deletions
|
|
@ -197,6 +197,7 @@ extern void clocksource_mark_unstable(struct clocksource *cs);
|
|||
extern void
|
||||
clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles);
|
||||
extern u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 now);
|
||||
extern void clocksource_select_force(void);
|
||||
|
||||
extern u64
|
||||
clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cycles);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ static u64 suspend_start;
|
|||
|
||||
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
|
||||
static void clocksource_watchdog_work(struct work_struct *work);
|
||||
static void clocksource_select(void);
|
||||
static void clocksource_select(bool force);
|
||||
|
||||
static LIST_HEAD(watchdog_list);
|
||||
static struct clocksource *watchdog;
|
||||
|
|
@ -700,11 +700,12 @@ static inline void clocksource_update_max_deferment(struct clocksource *cs)
|
|||
|
||||
#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||
|
||||
static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur)
|
||||
static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur,
|
||||
bool force)
|
||||
{
|
||||
struct clocksource *cs;
|
||||
|
||||
if (!finished_booting || list_empty(&clocksource_list))
|
||||
if ((!finished_booting && !force) || list_empty(&clocksource_list))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
|
|
@ -722,13 +723,13 @@ static struct clocksource *clocksource_find_best(bool oneshot, bool skipcur)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void __clocksource_select(bool skipcur)
|
||||
static void __clocksource_select(bool skipcur, bool force)
|
||||
{
|
||||
bool oneshot = tick_oneshot_mode_active();
|
||||
struct clocksource *best, *cs;
|
||||
|
||||
/* Find the best suitable clocksource */
|
||||
best = clocksource_find_best(oneshot, skipcur);
|
||||
best = clocksource_find_best(oneshot, skipcur, force);
|
||||
if (!best)
|
||||
return;
|
||||
|
||||
|
|
@ -781,22 +782,40 @@ found:
|
|||
* Select the clocksource with the best rating, or the clocksource,
|
||||
* which is selected by userspace override.
|
||||
*/
|
||||
static void clocksource_select(void)
|
||||
static void clocksource_select(bool force)
|
||||
{
|
||||
__clocksource_select(false);
|
||||
return __clocksource_select(false, force);
|
||||
}
|
||||
|
||||
static void clocksource_select_fallback(void)
|
||||
{
|
||||
__clocksource_select(true);
|
||||
__clocksource_select(true, false);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */
|
||||
static inline void clocksource_select(void) { }
|
||||
|
||||
static inline void clocksource_select(bool force) { }
|
||||
static inline void clocksource_select_fallback(void) { }
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* clocksource_select_force - Force re-selection of the best clocksource
|
||||
* among registered clocksources
|
||||
*
|
||||
* clocksource_select() can't select the best clocksource before
|
||||
* calling clocksource_done_booting() and since clocksource_select()
|
||||
* should be called with clocksource_mutex held, provide a new API
|
||||
* can be called from other files to select best clockrouce irrespective
|
||||
* of finished_booting flag.
|
||||
*/
|
||||
void clocksource_select_force(void)
|
||||
{
|
||||
mutex_lock(&clocksource_mutex);
|
||||
clocksource_select(true);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* clocksource_done_booting - Called near the end of core bootup
|
||||
*
|
||||
|
|
@ -813,7 +832,7 @@ static int __init clocksource_done_booting(void)
|
|||
* Run the watchdog first to eliminate unstable clock sources
|
||||
*/
|
||||
__clocksource_watchdog_kthread();
|
||||
clocksource_select();
|
||||
clocksource_select(false);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -904,6 +923,7 @@ void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(__clocksource_update_freq_scale);
|
||||
|
||||
|
||||
/**
|
||||
* __clocksource_register_scale - Used to install new clocksources
|
||||
* @cs: clocksource to be registered
|
||||
|
|
@ -932,7 +952,7 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
|
|||
clocksource_enqueue_watchdog(cs);
|
||||
clocksource_watchdog_unlock(&flags);
|
||||
|
||||
clocksource_select();
|
||||
clocksource_select(false);
|
||||
clocksource_select_watchdog(false);
|
||||
__clocksource_suspend_select(cs);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
|
|
@ -961,7 +981,7 @@ void clocksource_change_rating(struct clocksource *cs, int rating)
|
|||
__clocksource_change_rating(cs, rating);
|
||||
clocksource_watchdog_unlock(&flags);
|
||||
|
||||
clocksource_select();
|
||||
clocksource_select(false);
|
||||
clocksource_select_watchdog(false);
|
||||
clocksource_suspend_select(false);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
|
|
@ -1081,7 +1101,7 @@ static ssize_t current_clocksource_store(struct device *dev,
|
|||
|
||||
ret = sysfs_get_uname(buf, override_name, count);
|
||||
if (ret >= 0)
|
||||
clocksource_select();
|
||||
clocksource_select(false);
|
||||
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue