aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/Kconfig5
-rw-r--r--kernel/time/Makefile2
-rw-r--r--kernel/time/clockevents.c3
-rw-r--r--kernel/time/clocksource.c22
-rw-r--r--kernel/time/tick-broadcast.c51
-rw-r--r--kernel/time/tick-common.c5
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/time/timekeeping.c12
8 files changed, 43 insertions, 59 deletions
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index f66351126544..8d53106a0a92 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -23,3 +23,8 @@ config HIGH_RES_TIMERS
23 hardware is not capable then this option only increases 23 hardware is not capable then this option only increases
24 the size of the kernel image. 24 the size of the kernel image.
25 25
26config GENERIC_CLOCKEVENTS_BUILD
27 bool
28 default y
29 depends on GENERIC_CLOCKEVENTS || GENERIC_CLOCKEVENTS_MIGR
30
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 99b6034fc86b..905b0b50792d 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -1,6 +1,6 @@
1obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o 1obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
2 2
3obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o 3obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o
4obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o 4obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
5obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o 5obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o
6obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o 6obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 41dd3105ce7f..822beebe664a 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -194,6 +194,7 @@ void clockevents_exchange_device(struct clock_event_device *old,
194 local_irq_restore(flags); 194 local_irq_restore(flags);
195} 195}
196 196
197#ifdef CONFIG_GENERIC_CLOCKEVENTS
197/** 198/**
198 * clockevents_notify - notification about relevant events 199 * clockevents_notify - notification about relevant events
199 */ 200 */
@@ -222,4 +223,4 @@ void clockevents_notify(unsigned long reason, void *arg)
222 spin_unlock(&clockevents_lock); 223 spin_unlock(&clockevents_lock);
223} 224}
224EXPORT_SYMBOL_GPL(clockevents_notify); 225EXPORT_SYMBOL_GPL(clockevents_notify);
225 226#endif
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 51b6a6a6158c..c8a9d13874df 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -207,15 +207,12 @@ static inline void clocksource_resume_watchdog(void) { }
207 */ 207 */
208void clocksource_resume(void) 208void clocksource_resume(void)
209{ 209{
210 struct list_head *tmp; 210 struct clocksource *cs;
211 unsigned long flags; 211 unsigned long flags;
212 212
213 spin_lock_irqsave(&clocksource_lock, flags); 213 spin_lock_irqsave(&clocksource_lock, flags);
214 214
215 list_for_each(tmp, &clocksource_list) { 215 list_for_each_entry(cs, &clocksource_list, list) {
216 struct clocksource *cs;
217
218 cs = list_entry(tmp, struct clocksource, list);
219 if (cs->resume) 216 if (cs->resume)
220 cs->resume(); 217 cs->resume();
221 } 218 }
@@ -369,7 +366,6 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
369 const char *buf, size_t count) 366 const char *buf, size_t count)
370{ 367{
371 struct clocksource *ovr = NULL; 368 struct clocksource *ovr = NULL;
372 struct list_head *tmp;
373 size_t ret = count; 369 size_t ret = count;
374 int len; 370 int len;
375 371
@@ -389,12 +385,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
389 385
390 len = strlen(override_name); 386 len = strlen(override_name);
391 if (len) { 387 if (len) {
388 struct clocksource *cs;
389
392 ovr = clocksource_override; 390 ovr = clocksource_override;
393 /* try to select it: */ 391 /* try to select it: */
394 list_for_each(tmp, &clocksource_list) { 392 list_for_each_entry(cs, &clocksource_list, list) {
395 struct clocksource *cs;
396
397 cs = list_entry(tmp, struct clocksource, list);
398 if (strlen(cs->name) == len && 393 if (strlen(cs->name) == len &&
399 !strcmp(cs->name, override_name)) 394 !strcmp(cs->name, override_name))
400 ovr = cs; 395 ovr = cs;
@@ -422,14 +417,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
422static ssize_t 417static ssize_t
423sysfs_show_available_clocksources(struct sys_device *dev, char *buf) 418sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
424{ 419{
425 struct list_head *tmp; 420 struct clocksource *src;
426 char *curr = buf; 421 char *curr = buf;
427 422
428 spin_lock_irq(&clocksource_lock); 423 spin_lock_irq(&clocksource_lock);
429 list_for_each(tmp, &clocksource_list) { 424 list_for_each_entry(src, &clocksource_list, list) {
430 struct clocksource *src;
431
432 src = list_entry(tmp, struct clocksource, list);
433 curr += sprintf(curr, "%s ", src->name); 425 curr += sprintf(curr, "%s ", src->name);
434 } 426 }
435 spin_unlock_irq(&clocksource_lock); 427 spin_unlock_irq(&clocksource_lock);
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 0962e0577660..8cfb8b2ce773 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -64,8 +64,9 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc)
64 */ 64 */
65int tick_check_broadcast_device(struct clock_event_device *dev) 65int tick_check_broadcast_device(struct clock_event_device *dev)
66{ 66{
67 if (tick_broadcast_device.evtdev || 67 if ((tick_broadcast_device.evtdev &&
68 (dev->features & CLOCK_EVT_FEAT_C3STOP)) 68 tick_broadcast_device.evtdev->rating >= dev->rating) ||
69 (dev->features & CLOCK_EVT_FEAT_C3STOP))
69 return 0; 70 return 0;
70 71
71 clockevents_exchange_device(NULL, dev); 72 clockevents_exchange_device(NULL, dev);
@@ -176,8 +177,6 @@ static void tick_do_periodic_broadcast(void)
176 */ 177 */
177static void tick_handle_periodic_broadcast(struct clock_event_device *dev) 178static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
178{ 179{
179 dev->next_event.tv64 = KTIME_MAX;
180
181 tick_do_periodic_broadcast(); 180 tick_do_periodic_broadcast();
182 181
183 /* 182 /*
@@ -218,26 +217,33 @@ static void tick_do_broadcast_on_off(void *why)
218 bc = tick_broadcast_device.evtdev; 217 bc = tick_broadcast_device.evtdev;
219 218
220 /* 219 /*
221 * Is the device in broadcast mode forever or is it not 220 * Is the device not affected by the powerstate ?
222 * affected by the powerstate ?
223 */ 221 */
224 if (!dev || !tick_device_is_functional(dev) || 222 if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
225 !(dev->features & CLOCK_EVT_FEAT_C3STOP)) 223 goto out;
224
225 if (!tick_device_is_functional(dev))
226 goto out; 226 goto out;
227 227
228 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_ON) { 228 switch (*reason) {
229 case CLOCK_EVT_NOTIFY_BROADCAST_ON:
230 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
229 if (!cpu_isset(cpu, tick_broadcast_mask)) { 231 if (!cpu_isset(cpu, tick_broadcast_mask)) {
230 cpu_set(cpu, tick_broadcast_mask); 232 cpu_set(cpu, tick_broadcast_mask);
231 if (td->mode == TICKDEV_MODE_PERIODIC) 233 if (td->mode == TICKDEV_MODE_PERIODIC)
232 clockevents_set_mode(dev, 234 clockevents_set_mode(dev,
233 CLOCK_EVT_MODE_SHUTDOWN); 235 CLOCK_EVT_MODE_SHUTDOWN);
234 } 236 }
235 } else { 237 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
238 dev->features |= CLOCK_EVT_FEAT_DUMMY;
239 break;
240 case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
236 if (cpu_isset(cpu, tick_broadcast_mask)) { 241 if (cpu_isset(cpu, tick_broadcast_mask)) {
237 cpu_clear(cpu, tick_broadcast_mask); 242 cpu_clear(cpu, tick_broadcast_mask);
238 if (td->mode == TICKDEV_MODE_PERIODIC) 243 if (td->mode == TICKDEV_MODE_PERIODIC)
239 tick_setup_periodic(dev, 0); 244 tick_setup_periodic(dev, 0);
240 } 245 }
246 break;
241 } 247 }
242 248
243 if (cpus_empty(tick_broadcast_mask)) 249 if (cpus_empty(tick_broadcast_mask))
@@ -258,21 +264,12 @@ out:
258 */ 264 */
259void tick_broadcast_on_off(unsigned long reason, int *oncpu) 265void tick_broadcast_on_off(unsigned long reason, int *oncpu)
260{ 266{
261 int cpu = get_cpu(); 267 if (!cpu_isset(*oncpu, cpu_online_map))
262
263 if (!cpu_isset(*oncpu, cpu_online_map)) {
264 printk(KERN_ERR "tick-braodcast: ignoring broadcast for " 268 printk(KERN_ERR "tick-braodcast: ignoring broadcast for "
265 "offline CPU #%d\n", *oncpu); 269 "offline CPU #%d\n", *oncpu);
266 } else { 270 else
267 271 smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
268 if (cpu == *oncpu) 272 &reason, 1, 1);
269 tick_do_broadcast_on_off(&reason);
270 else
271 smp_call_function_single(*oncpu,
272 tick_do_broadcast_on_off,
273 &reason, 1, 1);
274 }
275 put_cpu();
276} 273}
277 274
278/* 275/*
@@ -515,11 +512,9 @@ static void tick_broadcast_clear_oneshot(int cpu)
515 */ 512 */
516void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 513void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
517{ 514{
518 if (bc->mode != CLOCK_EVT_MODE_ONESHOT) { 515 bc->event_handler = tick_handle_oneshot_broadcast;
519 bc->event_handler = tick_handle_oneshot_broadcast; 516 clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
520 clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); 517 bc->next_event.tv64 = KTIME_MAX;
521 bc->next_event.tv64 = KTIME_MAX;
522 }
523} 518}
524 519
525/* 520/*
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 77a21abc8716..1bea399a9ef0 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -200,7 +200,7 @@ static int tick_check_new_device(struct clock_event_device *newdev)
200 200
201 cpu = smp_processor_id(); 201 cpu = smp_processor_id();
202 if (!cpu_isset(cpu, newdev->cpumask)) 202 if (!cpu_isset(cpu, newdev->cpumask))
203 goto out; 203 goto out_bc;
204 204
205 td = &per_cpu(tick_cpu_device, cpu); 205 td = &per_cpu(tick_cpu_device, cpu);
206 curdev = td->evtdev; 206 curdev = td->evtdev;
@@ -265,7 +265,7 @@ out_bc:
265 */ 265 */
266 if (tick_check_broadcast_device(newdev)) 266 if (tick_check_broadcast_device(newdev))
267 ret = NOTIFY_STOP; 267 ret = NOTIFY_STOP;
268out: 268
269 spin_unlock_irqrestore(&tick_device_lock, flags); 269 spin_unlock_irqrestore(&tick_device_lock, flags);
270 270
271 return ret; 271 return ret;
@@ -345,6 +345,7 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
345 345
346 case CLOCK_EVT_NOTIFY_BROADCAST_ON: 346 case CLOCK_EVT_NOTIFY_BROADCAST_ON:
347 case CLOCK_EVT_NOTIFY_BROADCAST_OFF: 347 case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
348 case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
348 tick_broadcast_on_off(reason, dev); 349 tick_broadcast_on_off(reason, dev);
349 break; 350 break;
350 351
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 637519af6151..10a1347597fd 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -586,7 +586,7 @@ void tick_setup_sched_timer(void)
586 /* Get the next period (per cpu) */ 586 /* Get the next period (per cpu) */
587 ts->sched_timer.expires = tick_init_jiffy_update(); 587 ts->sched_timer.expires = tick_init_jiffy_update();
588 offset = ktime_to_ns(tick_period) >> 1; 588 offset = ktime_to_ns(tick_period) >> 1;
589 do_div(offset, NR_CPUS); 589 do_div(offset, num_possible_cpus());
590 offset *= smp_processor_id(); 590 offset *= smp_processor_id();
591 ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); 591 ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset);
592 592
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 4ad79f6bdec6..e5e466b27598 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -24,9 +24,7 @@
24 * This read-write spinlock protects us from races in SMP while 24 * This read-write spinlock protects us from races in SMP while
25 * playing with xtime and avenrun. 25 * playing with xtime and avenrun.
26 */ 26 */
27__attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); 27__cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
28
29EXPORT_SYMBOL(xtime_lock);
30 28
31 29
32/* 30/*
@@ -47,21 +45,13 @@ EXPORT_SYMBOL(xtime_lock);
47struct timespec xtime __attribute__ ((aligned (16))); 45struct timespec xtime __attribute__ ((aligned (16)));
48struct timespec wall_to_monotonic __attribute__ ((aligned (16))); 46struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
49static unsigned long total_sleep_time; /* seconds */ 47static unsigned long total_sleep_time; /* seconds */
50EXPORT_SYMBOL(xtime);
51
52 48
53#ifdef CONFIG_NO_HZ
54static struct timespec xtime_cache __attribute__ ((aligned (16))); 49static struct timespec xtime_cache __attribute__ ((aligned (16)));
55static inline void update_xtime_cache(u64 nsec) 50static inline void update_xtime_cache(u64 nsec)
56{ 51{
57 xtime_cache = xtime; 52 xtime_cache = xtime;
58 timespec_add_ns(&xtime_cache, nsec); 53 timespec_add_ns(&xtime_cache, nsec);
59} 54}
60#else
61#define xtime_cache xtime
62/* We do *not* want to evaluate the argument for this case */
63#define update_xtime_cache(n) do { } while (0)
64#endif
65 55
66static struct clocksource *clock; /* pointer to current clocksource */ 56static struct clocksource *clock; /* pointer to current clocksource */
67 57