diff options
-rw-r--r-- | kernel/time/clocksource.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 76256c5aecb8..89a7b91bfbdd 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -145,7 +145,6 @@ static struct clocksource *watchdog; | |||
145 | static struct timer_list watchdog_timer; | 145 | static struct timer_list watchdog_timer; |
146 | static DEFINE_SPINLOCK(watchdog_lock); | 146 | static DEFINE_SPINLOCK(watchdog_lock); |
147 | static cycle_t watchdog_last; | 147 | static cycle_t watchdog_last; |
148 | static unsigned long watchdog_resumed; | ||
149 | 148 | ||
150 | /* | 149 | /* |
151 | * Interval: 0.5sec Threshold: 0.0625s | 150 | * Interval: 0.5sec Threshold: 0.0625s |
@@ -167,12 +166,9 @@ static void clocksource_watchdog(unsigned long data) | |||
167 | struct clocksource *cs, *tmp; | 166 | struct clocksource *cs, *tmp; |
168 | cycle_t csnow, wdnow; | 167 | cycle_t csnow, wdnow; |
169 | int64_t wd_nsec, cs_nsec; | 168 | int64_t wd_nsec, cs_nsec; |
170 | int resumed; | ||
171 | 169 | ||
172 | spin_lock(&watchdog_lock); | 170 | spin_lock(&watchdog_lock); |
173 | 171 | ||
174 | resumed = test_and_clear_bit(0, &watchdog_resumed); | ||
175 | |||
176 | wdnow = watchdog->read(watchdog); | 172 | wdnow = watchdog->read(watchdog); |
177 | wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask); | 173 | wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask); |
178 | watchdog_last = wdnow; | 174 | watchdog_last = wdnow; |
@@ -223,14 +219,26 @@ static void clocksource_watchdog(unsigned long data) | |||
223 | } | 219 | } |
224 | spin_unlock(&watchdog_lock); | 220 | spin_unlock(&watchdog_lock); |
225 | } | 221 | } |
222 | |||
223 | static inline void clocksource_reset_watchdog(void) | ||
224 | { | ||
225 | struct clocksource *cs; | ||
226 | |||
227 | list_for_each_entry(cs, &watchdog_list, wd_list) | ||
228 | cs->flags &= ~CLOCK_SOURCE_WATCHDOG; | ||
229 | } | ||
230 | |||
226 | static void clocksource_resume_watchdog(void) | 231 | static void clocksource_resume_watchdog(void) |
227 | { | 232 | { |
228 | set_bit(0, &watchdog_resumed); | 233 | unsigned long flags; |
234 | |||
235 | spin_lock_irqsave(&watchdog_lock, flags); | ||
236 | clocksource_reset_watchdog(); | ||
237 | spin_unlock_irqrestore(&watchdog_lock, flags); | ||
229 | } | 238 | } |
230 | 239 | ||
231 | static void clocksource_check_watchdog(struct clocksource *cs) | 240 | static void clocksource_check_watchdog(struct clocksource *cs) |
232 | { | 241 | { |
233 | struct clocksource *cse; | ||
234 | unsigned long flags; | 242 | unsigned long flags; |
235 | 243 | ||
236 | spin_lock_irqsave(&watchdog_lock, flags); | 244 | spin_lock_irqsave(&watchdog_lock, flags); |
@@ -256,8 +264,7 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
256 | watchdog_timer.function = clocksource_watchdog; | 264 | watchdog_timer.function = clocksource_watchdog; |
257 | 265 | ||
258 | /* Reset watchdog cycles */ | 266 | /* Reset watchdog cycles */ |
259 | list_for_each_entry(cse, &watchdog_list, wd_list) | 267 | clocksource_reset_watchdog(); |
260 | cse->flags &= ~CLOCK_SOURCE_WATCHDOG; | ||
261 | /* Start if list is not empty */ | 268 | /* Start if list is not empty */ |
262 | if (!list_empty(&watchdog_list)) { | 269 | if (!list_empty(&watchdog_list)) { |
263 | watchdog_last = watchdog->read(watchdog); | 270 | watchdog_last = watchdog->read(watchdog); |