Blame view

kernel/time/clocksource.c 26.4 KB
734efb467   John Stultz   [PATCH] Time: Clo...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  /*
   * linux/kernel/time/clocksource.c
   *
   * This file contains the functions which manage clocksource drivers.
   *
   * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   * TODO WishList:
   *   o Allow clocksource drivers to be unregistered
734efb467   John Stultz   [PATCH] Time: Clo...
24
   */
d369a5d8f   Kay Sievers   clocksource: conv...
25
  #include <linux/device.h>
734efb467   John Stultz   [PATCH] Time: Clo...
26
  #include <linux/clocksource.h>
734efb467   John Stultz   [PATCH] Time: Clo...
27
28
  #include <linux/init.h>
  #include <linux/module.h>
dc29a3657   Mathieu Desnoyers   [PATCH] kernel/ti...
29
  #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */
79bf2bb33   Thomas Gleixner   [PATCH] tick-mana...
30
  #include <linux/tick.h>
01548f4d3   Martin Schwidefsky   clocksource: Avoi...
31
  #include <linux/kthread.h>
734efb467   John Stultz   [PATCH] Time: Clo...
32

a038a353c   Patrick Ohly   clocksource: allo...
33
34
35
36
37
38
39
40
  void timecounter_init(struct timecounter *tc,
  		      const struct cyclecounter *cc,
  		      u64 start_tstamp)
  {
  	tc->cc = cc;
  	tc->cycle_last = cc->read(cc);
  	tc->nsec = start_tstamp;
  }
3586e0a9a   David S. Miller   clocksource/timec...
41
  EXPORT_SYMBOL_GPL(timecounter_init);
a038a353c   Patrick Ohly   clocksource: allo...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  
  /**
   * timecounter_read_delta - get nanoseconds since last call of this function
   * @tc:         Pointer to time counter
   *
   * When the underlying cycle counter runs over, this will be handled
   * correctly as long as it does not run over more than once between
   * calls.
   *
   * The first call to this function for a new time counter initializes
   * the time tracking and returns an undefined result.
   */
  static u64 timecounter_read_delta(struct timecounter *tc)
  {
  	cycle_t cycle_now, cycle_delta;
  	u64 ns_offset;
  
  	/* read cycle counter: */
  	cycle_now = tc->cc->read(tc->cc);
  
  	/* calculate the delta since the last timecounter_read_delta(): */
  	cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
  
  	/* convert to nanoseconds: */
  	ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta);
  
  	/* update time stamp of timecounter_read_delta() call: */
  	tc->cycle_last = cycle_now;
  
  	return ns_offset;
  }
  
  u64 timecounter_read(struct timecounter *tc)
  {
  	u64 nsec;
  
  	/* increment time by nanoseconds since last call */
  	nsec = timecounter_read_delta(tc);
  	nsec += tc->nsec;
  	tc->nsec = nsec;
  
  	return nsec;
  }
3586e0a9a   David S. Miller   clocksource/timec...
85
  EXPORT_SYMBOL_GPL(timecounter_read);
a038a353c   Patrick Ohly   clocksource: allo...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  
  u64 timecounter_cyc2time(struct timecounter *tc,
  			 cycle_t cycle_tstamp)
  {
  	u64 cycle_delta = (cycle_tstamp - tc->cycle_last) & tc->cc->mask;
  	u64 nsec;
  
  	/*
  	 * Instead of always treating cycle_tstamp as more recent
  	 * than tc->cycle_last, detect when it is too far in the
  	 * future and treat it as old time stamp instead.
  	 */
  	if (cycle_delta > tc->cc->mask / 2) {
  		cycle_delta = (tc->cycle_last - cycle_tstamp) & tc->cc->mask;
  		nsec = tc->nsec - cyclecounter_cyc2ns(tc->cc, cycle_delta);
  	} else {
  		nsec = cyclecounter_cyc2ns(tc->cc, cycle_delta) + tc->nsec;
  	}
  
  	return nsec;
  }
3586e0a9a   David S. Miller   clocksource/timec...
107
  EXPORT_SYMBOL_GPL(timecounter_cyc2time);
a038a353c   Patrick Ohly   clocksource: allo...
108

7d2f944a2   Thomas Gleixner   clocksource: Prov...
109
110
111
112
113
114
  /**
   * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
   * @mult:	pointer to mult variable
   * @shift:	pointer to shift variable
   * @from:	frequency to convert from
   * @to:		frequency to convert to
5fdade95f   Nicolas Pitre   time: Rename misn...
115
   * @maxsec:	guaranteed runtime conversion range in seconds
7d2f944a2   Thomas Gleixner   clocksource: Prov...
116
117
118
119
120
121
122
123
   *
   * The function evaluates the shift/mult pair for the scaled math
   * operations of clocksources and clockevents.
   *
   * @to and @from are frequency values in HZ. For clock sources @to is
   * NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock
   * event @to is the counter frequency and @from is NSEC_PER_SEC.
   *
5fdade95f   Nicolas Pitre   time: Rename misn...
124
   * The @maxsec conversion range argument controls the time frame in
7d2f944a2   Thomas Gleixner   clocksource: Prov...
125
126
127
128
129
130
131
132
   * seconds which must be covered by the runtime conversion with the
   * calculated mult and shift factors. This guarantees that no 64bit
   * overflow happens when the input value of the conversion is
   * multiplied with the calculated mult factor. Larger ranges may
   * reduce the conversion accuracy by chosing smaller mult and shift
   * factors.
   */
  void
5fdade95f   Nicolas Pitre   time: Rename misn...
133
  clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec)
7d2f944a2   Thomas Gleixner   clocksource: Prov...
134
135
136
137
138
139
140
141
  {
  	u64 tmp;
  	u32 sft, sftacc= 32;
  
  	/*
  	 * Calculate the shift factor which is limiting the conversion
  	 * range:
  	 */
5fdade95f   Nicolas Pitre   time: Rename misn...
142
  	tmp = ((u64)maxsec * from) >> 32;
7d2f944a2   Thomas Gleixner   clocksource: Prov...
143
144
145
146
147
148
149
150
151
152
153
  	while (tmp) {
  		tmp >>=1;
  		sftacc--;
  	}
  
  	/*
  	 * Find the conversion shift/mult pair which has the best
  	 * accuracy and fits the maxsec conversion range:
  	 */
  	for (sft = 32; sft > 0; sft--) {
  		tmp = (u64) to << sft;
b5776c4a6   John Stultz   Fix rounding in c...
154
  		tmp += from / 2;
7d2f944a2   Thomas Gleixner   clocksource: Prov...
155
156
157
158
159
160
161
  		do_div(tmp, from);
  		if ((tmp >> sftacc) == 0)
  			break;
  	}
  	*mult = tmp;
  	*shift = sft;
  }
734efb467   John Stultz   [PATCH] Time: Clo...
162
163
  /*[Clocksource internal variables]---------
   * curr_clocksource:
f1b82746c   Martin Schwidefsky   clocksource: Clea...
164
   *	currently selected clocksource.
734efb467   John Stultz   [PATCH] Time: Clo...
165
166
   * clocksource_list:
   *	linked list with the registered clocksources
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
167
168
   * clocksource_mutex:
   *	protects manipulations to curr_clocksource and the clocksource_list
734efb467   John Stultz   [PATCH] Time: Clo...
169
170
171
   * override_name:
   *	Name of the user-specified clocksource.
   */
f1b82746c   Martin Schwidefsky   clocksource: Clea...
172
  static struct clocksource *curr_clocksource;
734efb467   John Stultz   [PATCH] Time: Clo...
173
  static LIST_HEAD(clocksource_list);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
174
  static DEFINE_MUTEX(clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
175
  static char override_name[32];
54a6bc0b0   Thomas Gleixner   clocksource: Dela...
176
  static int finished_booting;
734efb467   John Stultz   [PATCH] Time: Clo...
177

5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
178
  #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
f79e0258e   Martin Schwidefsky   clocksource: Reso...
179
  static void clocksource_watchdog_work(struct work_struct *work);
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
180
181
182
  static LIST_HEAD(watchdog_list);
  static struct clocksource *watchdog;
  static struct timer_list watchdog_timer;
f79e0258e   Martin Schwidefsky   clocksource: Reso...
183
  static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
184
  static DEFINE_SPINLOCK(watchdog_lock);
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
185
  static int watchdog_running;
9fb603362   Thomas Gleixner   clocksource: Make...
186
  static atomic_t watchdog_reset_pending;
b52f52a09   Thomas Gleixner   clocksource: fix ...
187

01548f4d3   Martin Schwidefsky   clocksource: Avoi...
188
  static int clocksource_watchdog_kthread(void *data);
d0981a1b2   Thomas Gleixner   clocksource: Prot...
189
  static void __clocksource_change_rating(struct clocksource *cs, int rating);
c55c87c89   Martin Schwidefsky   clocksource: Move...
190

5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
191
  /*
35c35d1af   Daniel Walker   clocksource: spel...
192
   * Interval: 0.5sec Threshold: 0.0625s
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
193
194
   */
  #define WATCHDOG_INTERVAL (HZ >> 1)
35c35d1af   Daniel Walker   clocksource: spel...
195
  #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
196

01548f4d3   Martin Schwidefsky   clocksource: Avoi...
197
198
199
200
201
202
203
204
  static void clocksource_watchdog_work(struct work_struct *work)
  {
  	/*
  	 * If kthread_run fails the next watchdog scan over the
  	 * watchdog_list will find the unstable clock again.
  	 */
  	kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
  }
7285dd7fd   Thomas Gleixner   clocksource: Reso...
205
  static void __clocksource_unstable(struct clocksource *cs)
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
206
  {
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
207
  	cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
c55c87c89   Martin Schwidefsky   clocksource: Move...
208
  	cs->flags |= CLOCK_SOURCE_UNSTABLE;
54a6bc0b0   Thomas Gleixner   clocksource: Dela...
209
210
  	if (finished_booting)
  		schedule_work(&watchdog_work);
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
211
  }
7285dd7fd   Thomas Gleixner   clocksource: Reso...
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  static void clocksource_unstable(struct clocksource *cs, int64_t delta)
  {
  	printk(KERN_WARNING "Clocksource %s unstable (delta = %Ld ns)
  ",
  	       cs->name, delta);
  	__clocksource_unstable(cs);
  }
  
  /**
   * clocksource_mark_unstable - mark clocksource unstable via watchdog
   * @cs:		clocksource to be marked unstable
   *
   * This function is called instead of clocksource_change_rating from
   * cpu hotplug code to avoid a deadlock between the clocksource mutex
   * and the cpu hotplug mutex. It defers the update of the clocksource
   * to the watchdog thread.
   */
  void clocksource_mark_unstable(struct clocksource *cs)
  {
  	unsigned long flags;
  
  	spin_lock_irqsave(&watchdog_lock, flags);
  	if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) {
  		if (list_empty(&cs->wd_list))
  			list_add(&cs->wd_list, &watchdog_list);
  		__clocksource_unstable(cs);
  	}
  	spin_unlock_irqrestore(&watchdog_lock, flags);
  }
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
241
242
  static void clocksource_watchdog(unsigned long data)
  {
c55c87c89   Martin Schwidefsky   clocksource: Move...
243
  	struct clocksource *cs;
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
244
245
  	cycle_t csnow, wdnow;
  	int64_t wd_nsec, cs_nsec;
9fb603362   Thomas Gleixner   clocksource: Make...
246
  	int next_cpu, reset_pending;
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
247
248
  
  	spin_lock(&watchdog_lock);
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
249
250
  	if (!watchdog_running)
  		goto out;
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
251

9fb603362   Thomas Gleixner   clocksource: Make...
252
  	reset_pending = atomic_read(&watchdog_reset_pending);
c55c87c89   Martin Schwidefsky   clocksource: Move...
253
254
255
  	list_for_each_entry(cs, &watchdog_list, wd_list) {
  
  		/* Clocksource already marked unstable? */
01548f4d3   Martin Schwidefsky   clocksource: Avoi...
256
  		if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
54a6bc0b0   Thomas Gleixner   clocksource: Dela...
257
258
  			if (finished_booting)
  				schedule_work(&watchdog_work);
c55c87c89   Martin Schwidefsky   clocksource: Move...
259
  			continue;
01548f4d3   Martin Schwidefsky   clocksource: Avoi...
260
  		}
c55c87c89   Martin Schwidefsky   clocksource: Move...
261

b5199515c   Thomas Gleixner   clocksource: Make...
262
  		local_irq_disable();
8e19608e8   Magnus Damm   clocksource: pass...
263
  		csnow = cs->read(cs);
b5199515c   Thomas Gleixner   clocksource: Make...
264
265
  		wdnow = watchdog->read(watchdog);
  		local_irq_enable();
b52f52a09   Thomas Gleixner   clocksource: fix ...
266

8cf4e750f   Martin Schwidefsky   clocksource: Dela...
267
  		/* Clocksource initialized ? */
9fb603362   Thomas Gleixner   clocksource: Make...
268
269
  		if (!(cs->flags & CLOCK_SOURCE_WATCHDOG) ||
  		    atomic_read(&watchdog_reset_pending)) {
8cf4e750f   Martin Schwidefsky   clocksource: Dela...
270
  			cs->flags |= CLOCK_SOURCE_WATCHDOG;
b5199515c   Thomas Gleixner   clocksource: Make...
271
272
  			cs->wd_last = wdnow;
  			cs->cs_last = csnow;
b52f52a09   Thomas Gleixner   clocksource: fix ...
273
274
  			continue;
  		}
b5199515c   Thomas Gleixner   clocksource: Make...
275
276
277
278
  		wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask,
  					     watchdog->mult, watchdog->shift);
  
  		cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) &
155ec6022   Martin Schwidefsky   timekeeping: Intr...
279
  					     cs->mask, cs->mult, cs->shift);
b5199515c   Thomas Gleixner   clocksource: Make...
280
281
  		cs->cs_last = csnow;
  		cs->wd_last = wdnow;
9fb603362   Thomas Gleixner   clocksource: Make...
282
283
  		if (atomic_read(&watchdog_reset_pending))
  			continue;
b5199515c   Thomas Gleixner   clocksource: Make...
284
  		/* Check the deviation from the watchdog clocksource. */
9fb603362   Thomas Gleixner   clocksource: Make...
285
  		if ((abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD)) {
8cf4e750f   Martin Schwidefsky   clocksource: Dela...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  			clocksource_unstable(cs, cs_nsec - wd_nsec);
  			continue;
  		}
  
  		if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&
  		    (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
  		    (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) {
  			cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
  			/*
  			 * We just marked the clocksource as highres-capable,
  			 * notify the rest of the system as well so that we
  			 * transition into high-res mode:
  			 */
  			tick_clock_notify();
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
300
301
  		}
  	}
c55c87c89   Martin Schwidefsky   clocksource: Move...
302
  	/*
9fb603362   Thomas Gleixner   clocksource: Make...
303
304
305
306
307
308
309
  	 * We only clear the watchdog_reset_pending, when we did a
  	 * full cycle through all clocksources.
  	 */
  	if (reset_pending)
  		atomic_dec(&watchdog_reset_pending);
  
  	/*
c55c87c89   Martin Schwidefsky   clocksource: Move...
310
311
312
313
314
315
316
317
  	 * Cycle through CPUs to check if the CPUs stay synchronized
  	 * to each other.
  	 */
  	next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
  	if (next_cpu >= nr_cpu_ids)
  		next_cpu = cpumask_first(cpu_online_mask);
  	watchdog_timer.expires += WATCHDOG_INTERVAL;
  	add_timer_on(&watchdog_timer, next_cpu);
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
318
  out:
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
319
320
  	spin_unlock(&watchdog_lock);
  }
0f8e8ef7c   Martin Schwidefsky   clocksource: Simp...
321

fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
322
323
324
325
326
327
  static inline void clocksource_start_watchdog(void)
  {
  	if (watchdog_running || !watchdog || list_empty(&watchdog_list))
  		return;
  	init_timer(&watchdog_timer);
  	watchdog_timer.function = clocksource_watchdog;
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
328
329
330
331
332
333
334
335
336
337
338
339
  	watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
  	add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask));
  	watchdog_running = 1;
  }
  
  static inline void clocksource_stop_watchdog(void)
  {
  	if (!watchdog_running || (watchdog && !list_empty(&watchdog_list)))
  		return;
  	del_timer(&watchdog_timer);
  	watchdog_running = 0;
  }
0f8e8ef7c   Martin Schwidefsky   clocksource: Simp...
340
341
342
343
344
345
346
  static inline void clocksource_reset_watchdog(void)
  {
  	struct clocksource *cs;
  
  	list_for_each_entry(cs, &watchdog_list, wd_list)
  		cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
  }
b52f52a09   Thomas Gleixner   clocksource: fix ...
347
348
  static void clocksource_resume_watchdog(void)
  {
9fb603362   Thomas Gleixner   clocksource: Make...
349
  	atomic_inc(&watchdog_reset_pending);
b52f52a09   Thomas Gleixner   clocksource: fix ...
350
  }
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
351
  static void clocksource_enqueue_watchdog(struct clocksource *cs)
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
352
  {
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
353
354
355
356
  	unsigned long flags;
  
  	spin_lock_irqsave(&watchdog_lock, flags);
  	if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
357
  		/* cs is a clocksource to be watched. */
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
358
  		list_add(&cs->wd_list, &watchdog_list);
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
359
  		cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
948ac6d71   Thomas Gleixner   [PATCH] clocksour...
360
  	} else {
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
361
  		/* cs is a watchdog. */
948ac6d71   Thomas Gleixner   [PATCH] clocksour...
362
  		if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
363
  			cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
364
  		/* Pick the best watchdog. */
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
365
  		if (!watchdog || cs->rating > watchdog->rating) {
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
366
  			watchdog = cs;
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
367
  			/* Reset watchdog cycles */
0f8e8ef7c   Martin Schwidefsky   clocksource: Simp...
368
  			clocksource_reset_watchdog();
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
369
370
  		}
  	}
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
371
372
  	/* Check if the watchdog timer needs to be started. */
  	clocksource_start_watchdog();
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
373
374
  	spin_unlock_irqrestore(&watchdog_lock, flags);
  }
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
  
  static void clocksource_dequeue_watchdog(struct clocksource *cs)
  {
  	struct clocksource *tmp;
  	unsigned long flags;
  
  	spin_lock_irqsave(&watchdog_lock, flags);
  	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);
  }
01548f4d3   Martin Schwidefsky   clocksource: Avoi...
402
  static int clocksource_watchdog_kthread(void *data)
c55c87c89   Martin Schwidefsky   clocksource: Move...
403
404
405
  {
  	struct clocksource *cs, *tmp;
  	unsigned long flags;
6ea41d252   Thomas Gleixner   clocksource: Call...
406
  	LIST_HEAD(unstable);
c55c87c89   Martin Schwidefsky   clocksource: Move...
407

d0981a1b2   Thomas Gleixner   clocksource: Prot...
408
  	mutex_lock(&clocksource_mutex);
c55c87c89   Martin Schwidefsky   clocksource: Move...
409
410
411
412
  	spin_lock_irqsave(&watchdog_lock, flags);
  	list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list)
  		if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
  			list_del_init(&cs->wd_list);
6ea41d252   Thomas Gleixner   clocksource: Call...
413
  			list_add(&cs->wd_list, &unstable);
c55c87c89   Martin Schwidefsky   clocksource: Move...
414
415
416
  		}
  	/* Check if the watchdog timer needs to be stopped. */
  	clocksource_stop_watchdog();
6ea41d252   Thomas Gleixner   clocksource: Call...
417
418
419
420
421
  	spin_unlock_irqrestore(&watchdog_lock, flags);
  
  	/* Needs to be done outside of watchdog lock */
  	list_for_each_entry_safe(cs, tmp, &unstable, wd_list) {
  		list_del_init(&cs->wd_list);
d0981a1b2   Thomas Gleixner   clocksource: Prot...
422
  		__clocksource_change_rating(cs, 0);
6ea41d252   Thomas Gleixner   clocksource: Call...
423
  	}
d0981a1b2   Thomas Gleixner   clocksource: Prot...
424
  	mutex_unlock(&clocksource_mutex);
01548f4d3   Martin Schwidefsky   clocksource: Avoi...
425
  	return 0;
c55c87c89   Martin Schwidefsky   clocksource: Move...
426
  }
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
427
428
429
  #else /* CONFIG_CLOCKSOURCE_WATCHDOG */
  
  static void clocksource_enqueue_watchdog(struct clocksource *cs)
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
430
431
432
433
  {
  	if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
  		cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
  }
b52f52a09   Thomas Gleixner   clocksource: fix ...
434

fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
435
  static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
b52f52a09   Thomas Gleixner   clocksource: fix ...
436
  static inline void clocksource_resume_watchdog(void) { }
54a6bc0b0   Thomas Gleixner   clocksource: Dela...
437
  static inline int clocksource_watchdog_kthread(void *data) { return 0; }
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
438
439
  
  #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
440

734efb467   John Stultz   [PATCH] Time: Clo...
441
  /**
c54a42b19   Magnus Damm   clocksource: add ...
442
443
444
445
446
447
448
449
450
451
452
453
   * clocksource_suspend - suspend the clocksource(s)
   */
  void clocksource_suspend(void)
  {
  	struct clocksource *cs;
  
  	list_for_each_entry_reverse(cs, &clocksource_list, list)
  		if (cs->suspend)
  			cs->suspend(cs);
  }
  
  /**
b52f52a09   Thomas Gleixner   clocksource: fix ...
454
455
456
457
   * clocksource_resume - resume the clocksource(s)
   */
  void clocksource_resume(void)
  {
2e1975868   Matthias Kaehlcke   kernel/time/clock...
458
  	struct clocksource *cs;
b52f52a09   Thomas Gleixner   clocksource: fix ...
459

75c5158f7   Martin Schwidefsky   timekeeping: Upda...
460
  	list_for_each_entry(cs, &clocksource_list, list)
b52f52a09   Thomas Gleixner   clocksource: fix ...
461
  		if (cs->resume)
17622339a   Magnus Damm   clocksource: add ...
462
  			cs->resume(cs);
b52f52a09   Thomas Gleixner   clocksource: fix ...
463
464
  
  	clocksource_resume_watchdog();
b52f52a09   Thomas Gleixner   clocksource: fix ...
465
466
467
  }
  
  /**
7c3078b63   Jason Wessel   kgdb: clocksource...
468
469
470
   * clocksource_touch_watchdog - Update watchdog
   *
   * Update the watchdog after exception contexts such as kgdb so as not
7b7422a56   Thomas Gleixner   clocksource: Prev...
471
472
   * to incorrectly trip the watchdog. This might fail when the kernel
   * was stopped in code which holds watchdog_lock.
7c3078b63   Jason Wessel   kgdb: clocksource...
473
474
475
476
477
   */
  void clocksource_touch_watchdog(void)
  {
  	clocksource_resume_watchdog();
  }
734efb467   John Stultz   [PATCH] Time: Clo...
478
  /**
d65670a78   John Stultz   clocksource: Avoi...
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
   * clocksource_max_adjustment- Returns max adjustment amount
   * @cs:         Pointer to clocksource
   *
   */
  static u32 clocksource_max_adjustment(struct clocksource *cs)
  {
  	u64 ret;
  	/*
  	 * We won't try to correct for more then 11% adjustments (110,000 ppm),
  	 */
  	ret = (u64)cs->mult * 11;
  	do_div(ret,100);
  	return (u32)ret;
  }
  
  /**
98962465e   Jon Hunter   nohz: Prevent clo...
495
496
497
498
499
500
501
502
503
504
505
   * clocksource_max_deferment - Returns max time the clocksource can be deferred
   * @cs:         Pointer to clocksource
   *
   */
  static u64 clocksource_max_deferment(struct clocksource *cs)
  {
  	u64 max_nsecs, max_cycles;
  
  	/*
  	 * Calculate the maximum number of cycles that we can pass to the
  	 * cyc2ns function without overflowing a 64-bit signed result. The
d65670a78   John Stultz   clocksource: Avoi...
506
507
508
509
510
511
512
  	 * maximum number of cycles is equal to ULLONG_MAX/(cs->mult+cs->maxadj)
  	 * which is equivalent to the below.
  	 * max_cycles < (2^63)/(cs->mult + cs->maxadj)
  	 * max_cycles < 2^(log2((2^63)/(cs->mult + cs->maxadj)))
  	 * max_cycles < 2^(log2(2^63) - log2(cs->mult + cs->maxadj))
  	 * max_cycles < 2^(63 - log2(cs->mult + cs->maxadj))
  	 * max_cycles < 1 << (63 - log2(cs->mult + cs->maxadj))
98962465e   Jon Hunter   nohz: Prevent clo...
513
514
515
516
  	 * Please note that we add 1 to the result of the log2 to account for
  	 * any rounding errors, ensure the above inequality is satisfied and
  	 * no overflow will occur.
  	 */
d65670a78   John Stultz   clocksource: Avoi...
517
  	max_cycles = 1ULL << (63 - (ilog2(cs->mult + cs->maxadj) + 1));
98962465e   Jon Hunter   nohz: Prevent clo...
518
519
520
521
  
  	/*
  	 * The actual maximum number of cycles we can defer the clocksource is
  	 * determined by the minimum of max_cycles and cs->mask.
d65670a78   John Stultz   clocksource: Avoi...
522
523
  	 * Note: Here we subtract the maxadj to make sure we don't sleep for
  	 * too long if there's a large negative adjustment.
98962465e   Jon Hunter   nohz: Prevent clo...
524
525
  	 */
  	max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
d65670a78   John Stultz   clocksource: Avoi...
526
527
  	max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult - cs->maxadj,
  					cs->shift);
98962465e   Jon Hunter   nohz: Prevent clo...
528
529
530
531
532
533
534
  
  	/*
  	 * To ensure that the clocksource does not wrap whilst we are idle,
  	 * limit the time the clocksource can be deferred by 12.5%. Please
  	 * note a margin of 12.5% is used because this can be computed with
  	 * a shift, versus say 10% which would require division.
  	 */
b1f919664   Yang Honggang (Joseph)   clocksource: Fix ...
535
  	return max_nsecs - (max_nsecs >> 3);
98962465e   Jon Hunter   nohz: Prevent clo...
536
  }
592913ecb   John Stultz   time: Kill off CO...
537
  #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
734efb467   John Stultz   [PATCH] Time: Clo...
538

734efb467   John Stultz   [PATCH] Time: Clo...
539
  /**
f1b82746c   Martin Schwidefsky   clocksource: Clea...
540
   * clocksource_select - Select the best clocksource available
734efb467   John Stultz   [PATCH] Time: Clo...
541
   *
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
542
   * Private function. Must hold clocksource_mutex when called.
734efb467   John Stultz   [PATCH] Time: Clo...
543
   *
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
544
545
   * Select the clocksource with the best rating, or the clocksource,
   * which is selected by userspace override.
734efb467   John Stultz   [PATCH] Time: Clo...
546
   */
f1b82746c   Martin Schwidefsky   clocksource: Clea...
547
  static void clocksource_select(void)
734efb467   John Stultz   [PATCH] Time: Clo...
548
  {
f1b82746c   Martin Schwidefsky   clocksource: Clea...
549
  	struct clocksource *best, *cs;
5d8b34fdc   Thomas Gleixner   [PATCH] clocksour...
550

75c5158f7   Martin Schwidefsky   timekeeping: Upda...
551
  	if (!finished_booting || list_empty(&clocksource_list))
f1b82746c   Martin Schwidefsky   clocksource: Clea...
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  		return;
  	/* First clocksource on the list has the best rating. */
  	best = list_first_entry(&clocksource_list, struct clocksource, list);
  	/* Check for the override clocksource. */
  	list_for_each_entry(cs, &clocksource_list, list) {
  		if (strcmp(cs->name, override_name) != 0)
  			continue;
  		/*
  		 * Check to make sure we don't switch to a non-highres
  		 * capable clocksource if the tick code is in oneshot
  		 * mode (highres or nohz)
  		 */
  		if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&
  		    tick_oneshot_mode_active()) {
  			/* Override clocksource cannot be used. */
  			printk(KERN_WARNING "Override clocksource %s is not "
  			       "HRT compatible. Cannot switch while in "
  			       "HRT/NOHZ mode
  ", cs->name);
  			override_name[0] = 0;
  		} else
  			/* Override clocksource can be used. */
  			best = cs;
  		break;
  	}
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
577
578
579
580
581
582
  	if (curr_clocksource != best) {
  		printk(KERN_INFO "Switching to clocksource %s
  ", best->name);
  		curr_clocksource = best;
  		timekeeping_notify(curr_clocksource);
  	}
f1b82746c   Martin Schwidefsky   clocksource: Clea...
583
  }
734efb467   John Stultz   [PATCH] Time: Clo...
584

592913ecb   John Stultz   time: Kill off CO...
585
  #else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */
54a6bc0b0   Thomas Gleixner   clocksource: Dela...
586
587
588
589
  
  static inline void clocksource_select(void) { }
  
  #endif
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
590
591
592
593
594
595
596
597
598
  /*
   * clocksource_done_booting - Called near the end of core bootup
   *
   * Hack to avoid lots of clocksource churn at boot time.
   * We use fs_initcall because we want this to start before
   * device_initcall but after subsys_initcall.
   */
  static int __init clocksource_done_booting(void)
  {
ad6759fbf   John Stultz   timekeeping: Prev...
599
600
601
  	mutex_lock(&clocksource_mutex);
  	curr_clocksource = clocksource_default_clock();
  	mutex_unlock(&clocksource_mutex);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
602
  	finished_booting = 1;
54a6bc0b0   Thomas Gleixner   clocksource: Dela...
603
604
605
606
607
  
  	/*
  	 * Run the watchdog first to eliminate unstable clock sources
  	 */
  	clocksource_watchdog_kthread(NULL);
e6c733050   Thomas Gleixner   clocksource: cloc...
608
  	mutex_lock(&clocksource_mutex);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
609
  	clocksource_select();
e6c733050   Thomas Gleixner   clocksource: cloc...
610
  	mutex_unlock(&clocksource_mutex);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
611
612
613
  	return 0;
  }
  fs_initcall(clocksource_done_booting);
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
614
615
  /*
   * Enqueue the clocksource sorted by rating
734efb467   John Stultz   [PATCH] Time: Clo...
616
   */
f1b82746c   Martin Schwidefsky   clocksource: Clea...
617
  static void clocksource_enqueue(struct clocksource *cs)
734efb467   John Stultz   [PATCH] Time: Clo...
618
  {
f1b82746c   Martin Schwidefsky   clocksource: Clea...
619
620
  	struct list_head *entry = &clocksource_list;
  	struct clocksource *tmp;
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
621

f1b82746c   Martin Schwidefsky   clocksource: Clea...
622
  	list_for_each_entry(tmp, &clocksource_list, list)
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
623
  		/* Keep track of the place, where to insert */
f1b82746c   Martin Schwidefsky   clocksource: Clea...
624
625
626
  		if (tmp->rating >= cs->rating)
  			entry = &tmp->list;
  	list_add(&cs->list, entry);
734efb467   John Stultz   [PATCH] Time: Clo...
627
  }
d7e81c269   John Stultz   clocksource: Add ...
628
  /**
852db46d5   John Stultz   clocksource: Add ...
629
   * __clocksource_updatefreq_scale - Used update clocksource with new freq
b1b73d095   Kusanagi Kouichi   time/clocksource:...
630
   * @cs:		clocksource to be registered
d7e81c269   John Stultz   clocksource: Add ...
631
632
633
   * @scale:	Scale factor multiplied against freq to get clocksource hz
   * @freq:	clocksource frequency (cycles per second) divided by scale
   *
852db46d5   John Stultz   clocksource: Add ...
634
   * This should only be called from the clocksource->enable() method.
d7e81c269   John Stultz   clocksource: Add ...
635
636
   *
   * This *SHOULD NOT* be called directly! Please use the
852db46d5   John Stultz   clocksource: Add ...
637
   * clocksource_updatefreq_hz() or clocksource_updatefreq_khz helper functions.
d7e81c269   John Stultz   clocksource: Add ...
638
   */
852db46d5   John Stultz   clocksource: Add ...
639
  void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
d7e81c269   John Stultz   clocksource: Add ...
640
  {
c0e299b1a   Thomas Gleixner   clockevents/sourc...
641
  	u64 sec;
d7e81c269   John Stultz   clocksource: Add ...
642
  	/*
724ed53e8   Thomas Gleixner   clocksource: Get ...
643
644
645
646
647
648
649
650
  	 * Calc the maximum number of seconds which we can run before
  	 * wrapping around. For clocksources which have a mask > 32bit
  	 * we need to limit the max sleep time to have a good
  	 * conversion precision. 10 minutes is still a reasonable
  	 * amount. That results in a shift value of 24 for a
  	 * clocksource with mask >= 40bit and f >= 4GHz. That maps to
  	 * ~ 0.06ppm granularity for NTP. We apply the same 12.5%
  	 * margin as we do in clocksource_max_deferment()
d7e81c269   John Stultz   clocksource: Add ...
651
  	 */
b1f919664   Yang Honggang (Joseph)   clocksource: Fix ...
652
  	sec = (cs->mask - (cs->mask >> 3));
724ed53e8   Thomas Gleixner   clocksource: Get ...
653
654
655
656
657
658
  	do_div(sec, freq);
  	do_div(sec, scale);
  	if (!sec)
  		sec = 1;
  	else if (sec > 600 && cs->mask > UINT_MAX)
  		sec = 600;
d7e81c269   John Stultz   clocksource: Add ...
659
  	clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
724ed53e8   Thomas Gleixner   clocksource: Get ...
660
  			       NSEC_PER_SEC / scale, sec * scale);
d65670a78   John Stultz   clocksource: Avoi...
661
662
663
664
665
666
667
668
669
670
671
672
673
  
  	/*
  	 * for clocksources that have large mults, to avoid overflow.
  	 * Since mult may be adjusted by ntp, add an safety extra margin
  	 *
  	 */
  	cs->maxadj = clocksource_max_adjustment(cs);
  	while ((cs->mult + cs->maxadj < cs->mult)
  		|| (cs->mult - cs->maxadj > cs->mult)) {
  		cs->mult >>= 1;
  		cs->shift--;
  		cs->maxadj = clocksource_max_adjustment(cs);
  	}
d7e81c269   John Stultz   clocksource: Add ...
674
  	cs->max_idle_ns = clocksource_max_deferment(cs);
852db46d5   John Stultz   clocksource: Add ...
675
676
677
678
679
  }
  EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
  
  /**
   * __clocksource_register_scale - Used to install new clocksources
b1b73d095   Kusanagi Kouichi   time/clocksource:...
680
   * @cs:		clocksource to be registered
852db46d5   John Stultz   clocksource: Add ...
681
682
683
684
685
686
687
688
689
690
   * @scale:	Scale factor multiplied against freq to get clocksource hz
   * @freq:	clocksource frequency (cycles per second) divided by scale
   *
   * Returns -EBUSY if registration fails, zero otherwise.
   *
   * This *SHOULD NOT* be called directly! Please use the
   * clocksource_register_hz() or clocksource_register_khz helper functions.
   */
  int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
  {
b595076a1   Uwe Kleine-König   tree-wide: fix co...
691
  	/* Initialize mult/shift and max_idle_ns */
852db46d5   John Stultz   clocksource: Add ...
692
  	__clocksource_updatefreq_scale(cs, scale, freq);
d7e81c269   John Stultz   clocksource: Add ...
693

852db46d5   John Stultz   clocksource: Add ...
694
  	/* Add clocksource to the clcoksource list */
d7e81c269   John Stultz   clocksource: Add ...
695
696
  	mutex_lock(&clocksource_mutex);
  	clocksource_enqueue(cs);
d7e81c269   John Stultz   clocksource: Add ...
697
  	clocksource_enqueue_watchdog(cs);
e05b2efb8   John Stultz   clocksource: Inst...
698
  	clocksource_select();
d7e81c269   John Stultz   clocksource: Add ...
699
700
701
702
  	mutex_unlock(&clocksource_mutex);
  	return 0;
  }
  EXPORT_SYMBOL_GPL(__clocksource_register_scale);
734efb467   John Stultz   [PATCH] Time: Clo...
703
  /**
a27525497   John Stultz   [PATCH] time: ren...
704
   * clocksource_register - Used to install new clocksources
b1b73d095   Kusanagi Kouichi   time/clocksource:...
705
   * @cs:		clocksource to be registered
734efb467   John Stultz   [PATCH] Time: Clo...
706
707
708
   *
   * Returns -EBUSY if registration fails, zero otherwise.
   */
f1b82746c   Martin Schwidefsky   clocksource: Clea...
709
  int clocksource_register(struct clocksource *cs)
734efb467   John Stultz   [PATCH] Time: Clo...
710
  {
d65670a78   John Stultz   clocksource: Avoi...
711
712
713
714
715
716
  	/* calculate max adjustment for given mult/shift */
  	cs->maxadj = clocksource_max_adjustment(cs);
  	WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
  		"Clocksource %s might overflow on 11%% adjustment
  ",
  		cs->name);
98962465e   Jon Hunter   nohz: Prevent clo...
717
718
  	/* calculate max idle time permitted for this clocksource */
  	cs->max_idle_ns = clocksource_max_deferment(cs);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
719
  	mutex_lock(&clocksource_mutex);
f1b82746c   Martin Schwidefsky   clocksource: Clea...
720
  	clocksource_enqueue(cs);
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
721
  	clocksource_enqueue_watchdog(cs);
e05b2efb8   John Stultz   clocksource: Inst...
722
  	clocksource_select();
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
723
  	mutex_unlock(&clocksource_mutex);
f1b82746c   Martin Schwidefsky   clocksource: Clea...
724
  	return 0;
734efb467   John Stultz   [PATCH] Time: Clo...
725
  }
a27525497   John Stultz   [PATCH] time: ren...
726
  EXPORT_SYMBOL(clocksource_register);
734efb467   John Stultz   [PATCH] Time: Clo...
727

d0981a1b2   Thomas Gleixner   clocksource: Prot...
728
729
730
731
732
733
734
  static void __clocksource_change_rating(struct clocksource *cs, int rating)
  {
  	list_del(&cs->list);
  	cs->rating = rating;
  	clocksource_enqueue(cs);
  	clocksource_select();
  }
734efb467   John Stultz   [PATCH] Time: Clo...
735
  /**
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
736
   * clocksource_change_rating - Change the rating of a registered clocksource
b1b73d095   Kusanagi Kouichi   time/clocksource:...
737
738
   * @cs:		clocksource to be changed
   * @rating:	new rating
734efb467   John Stultz   [PATCH] Time: Clo...
739
   */
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
740
  void clocksource_change_rating(struct clocksource *cs, int rating)
734efb467   John Stultz   [PATCH] Time: Clo...
741
  {
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
742
  	mutex_lock(&clocksource_mutex);
d0981a1b2   Thomas Gleixner   clocksource: Prot...
743
  	__clocksource_change_rating(cs, rating);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
744
  	mutex_unlock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
745
  }
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
746
  EXPORT_SYMBOL(clocksource_change_rating);
734efb467   John Stultz   [PATCH] Time: Clo...
747

4713e22ce   Thomas Gleixner   clocksource: add ...
748
749
  /**
   * clocksource_unregister - remove a registered clocksource
b1b73d095   Kusanagi Kouichi   time/clocksource:...
750
   * @cs:	clocksource to be unregistered
4713e22ce   Thomas Gleixner   clocksource: add ...
751
752
753
   */
  void clocksource_unregister(struct clocksource *cs)
  {
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
754
  	mutex_lock(&clocksource_mutex);
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
755
  	clocksource_dequeue_watchdog(cs);
4713e22ce   Thomas Gleixner   clocksource: add ...
756
  	list_del(&cs->list);
f1b82746c   Martin Schwidefsky   clocksource: Clea...
757
  	clocksource_select();
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
758
  	mutex_unlock(&clocksource_mutex);
4713e22ce   Thomas Gleixner   clocksource: add ...
759
  }
fb63a0ebe   Martin Schwidefsky   clocksource: Refa...
760
  EXPORT_SYMBOL(clocksource_unregister);
4713e22ce   Thomas Gleixner   clocksource: add ...
761

2b0137001   Daniel Walker   [PATCH] clocksour...
762
  #ifdef CONFIG_SYSFS
734efb467   John Stultz   [PATCH] Time: Clo...
763
764
765
  /**
   * sysfs_show_current_clocksources - sysfs interface for current clocksource
   * @dev:	unused
b1b73d095   Kusanagi Kouichi   time/clocksource:...
766
   * @attr:	unused
734efb467   John Stultz   [PATCH] Time: Clo...
767
768
769
770
771
   * @buf:	char buffer to be filled with clocksource list
   *
   * Provides sysfs interface for listing current clocksource.
   */
  static ssize_t
d369a5d8f   Kay Sievers   clocksource: conv...
772
773
  sysfs_show_current_clocksources(struct device *dev,
  				struct device_attribute *attr, char *buf)
734efb467   John Stultz   [PATCH] Time: Clo...
774
  {
5e2cb1018   Miao Xie   time: fix sysfs_s...
775
  	ssize_t count = 0;
734efb467   John Stultz   [PATCH] Time: Clo...
776

75c5158f7   Martin Schwidefsky   timekeeping: Upda...
777
  	mutex_lock(&clocksource_mutex);
5e2cb1018   Miao Xie   time: fix sysfs_s...
778
779
  	count = snprintf(buf, PAGE_SIZE, "%s
  ", curr_clocksource->name);
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
780
  	mutex_unlock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
781

5e2cb1018   Miao Xie   time: fix sysfs_s...
782
  	return count;
734efb467   John Stultz   [PATCH] Time: Clo...
783
784
785
786
787
  }
  
  /**
   * sysfs_override_clocksource - interface for manually overriding clocksource
   * @dev:	unused
b1b73d095   Kusanagi Kouichi   time/clocksource:...
788
   * @attr:	unused
734efb467   John Stultz   [PATCH] Time: Clo...
789
790
791
792
   * @buf:	name of override clocksource
   * @count:	length of buffer
   *
   * Takes input from sysfs interface for manually overriding the default
b71a8eb0f   Uwe Kleine-König   tree-wide: fix ty...
793
   * clocksource selection.
734efb467   John Stultz   [PATCH] Time: Clo...
794
   */
d369a5d8f   Kay Sievers   clocksource: conv...
795
796
  static ssize_t sysfs_override_clocksource(struct device *dev,
  					  struct device_attribute *attr,
734efb467   John Stultz   [PATCH] Time: Clo...
797
798
799
  					  const char *buf, size_t count)
  {
  	size_t ret = count;
92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
800

734efb467   John Stultz   [PATCH] Time: Clo...
801
802
803
804
805
806
807
808
809
  	/* strings from sysfs write are not 0 terminated! */
  	if (count >= sizeof(override_name))
  		return -EINVAL;
  
  	/* strip of 
  : */
  	if (buf[count-1] == '
  ')
  		count--;
734efb467   John Stultz   [PATCH] Time: Clo...
810

75c5158f7   Martin Schwidefsky   timekeeping: Upda...
811
  	mutex_lock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
812

92c7e0025   Thomas Gleixner   [PATCH] Simplify ...
813
814
  	if (count > 0)
  		memcpy(override_name, buf, count);
734efb467   John Stultz   [PATCH] Time: Clo...
815
  	override_name[count] = 0;
f1b82746c   Martin Schwidefsky   clocksource: Clea...
816
  	clocksource_select();
734efb467   John Stultz   [PATCH] Time: Clo...
817

75c5158f7   Martin Schwidefsky   timekeeping: Upda...
818
  	mutex_unlock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
819
820
821
822
823
824
825
  
  	return ret;
  }
  
  /**
   * sysfs_show_available_clocksources - sysfs interface for listing clocksource
   * @dev:	unused
b1b73d095   Kusanagi Kouichi   time/clocksource:...
826
   * @attr:	unused
734efb467   John Stultz   [PATCH] Time: Clo...
827
828
829
830
831
   * @buf:	char buffer to be filled with clocksource list
   *
   * Provides sysfs interface for listing registered clocksources
   */
  static ssize_t
d369a5d8f   Kay Sievers   clocksource: conv...
832
833
  sysfs_show_available_clocksources(struct device *dev,
  				  struct device_attribute *attr,
4a0b2b4db   Andi Kleen   sysdev: Pass the ...
834
  				  char *buf)
734efb467   John Stultz   [PATCH] Time: Clo...
835
  {
2e1975868   Matthias Kaehlcke   kernel/time/clock...
836
  	struct clocksource *src;
5e2cb1018   Miao Xie   time: fix sysfs_s...
837
  	ssize_t count = 0;
734efb467   John Stultz   [PATCH] Time: Clo...
838

75c5158f7   Martin Schwidefsky   timekeeping: Upda...
839
  	mutex_lock(&clocksource_mutex);
2e1975868   Matthias Kaehlcke   kernel/time/clock...
840
  	list_for_each_entry(src, &clocksource_list, list) {
cd6d95d84   Thomas Gleixner   clocksource: prev...
841
842
843
844
845
846
  		/*
  		 * Don't show non-HRES clocksource if the tick code is
  		 * in one shot mode (highres=on or nohz=on)
  		 */
  		if (!tick_oneshot_mode_active() ||
  		    (src->flags & CLOCK_SOURCE_VALID_FOR_HRES))
3f68535ad   John Stultz   clocksource: sani...
847
  			count += snprintf(buf + count,
5e2cb1018   Miao Xie   time: fix sysfs_s...
848
849
  				  max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
  				  "%s ", src->name);
734efb467   John Stultz   [PATCH] Time: Clo...
850
  	}
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
851
  	mutex_unlock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
852

5e2cb1018   Miao Xie   time: fix sysfs_s...
853
854
855
  	count += snprintf(buf + count,
  			  max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "
  ");
734efb467   John Stultz   [PATCH] Time: Clo...
856

5e2cb1018   Miao Xie   time: fix sysfs_s...
857
  	return count;
734efb467   John Stultz   [PATCH] Time: Clo...
858
859
860
861
862
  }
  
  /*
   * Sysfs setup bits:
   */
d369a5d8f   Kay Sievers   clocksource: conv...
863
  static DEVICE_ATTR(current_clocksource, 0644, sysfs_show_current_clocksources,
f5f1a24a2   Daniel Walker   [PATCH] clocksour...
864
  		   sysfs_override_clocksource);
734efb467   John Stultz   [PATCH] Time: Clo...
865

d369a5d8f   Kay Sievers   clocksource: conv...
866
  static DEVICE_ATTR(available_clocksource, 0444,
f5f1a24a2   Daniel Walker   [PATCH] clocksour...
867
  		   sysfs_show_available_clocksources, NULL);
734efb467   John Stultz   [PATCH] Time: Clo...
868

d369a5d8f   Kay Sievers   clocksource: conv...
869
  static struct bus_type clocksource_subsys = {
af5ca3f4e   Kay Sievers   Driver core: chan...
870
  	.name = "clocksource",
d369a5d8f   Kay Sievers   clocksource: conv...
871
  	.dev_name = "clocksource",
734efb467   John Stultz   [PATCH] Time: Clo...
872
  };
d369a5d8f   Kay Sievers   clocksource: conv...
873
  static struct device device_clocksource = {
734efb467   John Stultz   [PATCH] Time: Clo...
874
  	.id	= 0,
d369a5d8f   Kay Sievers   clocksource: conv...
875
  	.bus	= &clocksource_subsys,
734efb467   John Stultz   [PATCH] Time: Clo...
876
  };
ad596171e   John Stultz   [PATCH] Time: Use...
877
  static int __init init_clocksource_sysfs(void)
734efb467   John Stultz   [PATCH] Time: Clo...
878
  {
d369a5d8f   Kay Sievers   clocksource: conv...
879
  	int error = subsys_system_register(&clocksource_subsys, NULL);
734efb467   John Stultz   [PATCH] Time: Clo...
880
881
  
  	if (!error)
d369a5d8f   Kay Sievers   clocksource: conv...
882
  		error = device_register(&device_clocksource);
734efb467   John Stultz   [PATCH] Time: Clo...
883
  	if (!error)
d369a5d8f   Kay Sievers   clocksource: conv...
884
  		error = device_create_file(
734efb467   John Stultz   [PATCH] Time: Clo...
885
  				&device_clocksource,
d369a5d8f   Kay Sievers   clocksource: conv...
886
  				&dev_attr_current_clocksource);
734efb467   John Stultz   [PATCH] Time: Clo...
887
  	if (!error)
d369a5d8f   Kay Sievers   clocksource: conv...
888
  		error = device_create_file(
734efb467   John Stultz   [PATCH] Time: Clo...
889
  				&device_clocksource,
d369a5d8f   Kay Sievers   clocksource: conv...
890
  				&dev_attr_available_clocksource);
734efb467   John Stultz   [PATCH] Time: Clo...
891
892
893
894
  	return error;
  }
  
  device_initcall(init_clocksource_sysfs);
2b0137001   Daniel Walker   [PATCH] clocksour...
895
  #endif /* CONFIG_SYSFS */
734efb467   John Stultz   [PATCH] Time: Clo...
896
897
898
899
900
901
902
903
904
905
  
  /**
   * boot_override_clocksource - boot clock override
   * @str:	override name
   *
   * Takes a clocksource= boot argument and uses it
   * as the clocksource override name.
   */
  static int __init boot_override_clocksource(char* str)
  {
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
906
  	mutex_lock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
907
908
  	if (str)
  		strlcpy(override_name, str, sizeof(override_name));
75c5158f7   Martin Schwidefsky   timekeeping: Upda...
909
  	mutex_unlock(&clocksource_mutex);
734efb467   John Stultz   [PATCH] Time: Clo...
910
911
912
913
914
915
916
917
918
919
920
921
922
923
  	return 1;
  }
  
  __setup("clocksource=", boot_override_clocksource);
  
  /**
   * boot_override_clock - Compatibility layer for deprecated boot option
   * @str:	override name
   *
   * DEPRECATED! Takes a clock= boot argument and uses it
   * as the clocksource override name
   */
  static int __init boot_override_clock(char* str)
  {
5d0cf410e   John Stultz   [PATCH] Time: i38...
924
925
926
927
928
929
930
931
932
  	if (!strcmp(str, "pmtmr")) {
  		printk("Warning: clock=pmtmr is deprecated. "
  			"Use clocksource=acpi_pm.
  ");
  		return boot_override_clocksource("acpi_pm");
  	}
  	printk("Warning! clock= boot option is deprecated. "
  		"Use clocksource=xyz
  ");
734efb467   John Stultz   [PATCH] Time: Clo...
933
934
935
936
  	return boot_override_clocksource(str);
  }
  
  __setup("clock=", boot_override_clock);