diff options
Diffstat (limited to 'arch/arm/kernel/time.c')
-rw-r--r-- | arch/arm/kernel/time.c | 124 |
1 files changed, 3 insertions, 121 deletions
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index b5867eca1d0b..368d171754cf 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -130,7 +130,9 @@ static const struct leds_evt_name evt_names[] = { | |||
130 | { "red", led_red_on, led_red_off }, | 130 | { "red", led_red_on, led_red_off }, |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static ssize_t leds_store(struct sys_device *dev, const char *buf, size_t size) | 133 | static ssize_t leds_store(struct sys_device *dev, |
134 | struct sysdev_attribute *attr, | ||
135 | const char *buf, size_t size) | ||
134 | { | 136 | { |
135 | int ret = -EINVAL, len = strcspn(buf, " "); | 137 | int ret = -EINVAL, len = strcspn(buf, " "); |
136 | 138 | ||
@@ -365,108 +367,6 @@ static struct sysdev_class timer_sysclass = { | |||
365 | .resume = timer_resume, | 367 | .resume = timer_resume, |
366 | }; | 368 | }; |
367 | 369 | ||
368 | #ifdef CONFIG_NO_IDLE_HZ | ||
369 | static int timer_dyn_tick_enable(void) | ||
370 | { | ||
371 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
372 | unsigned long flags; | ||
373 | int ret = -ENODEV; | ||
374 | |||
375 | if (dyn_tick) { | ||
376 | spin_lock_irqsave(&dyn_tick->lock, flags); | ||
377 | ret = 0; | ||
378 | if (!(dyn_tick->state & DYN_TICK_ENABLED)) { | ||
379 | ret = dyn_tick->enable(); | ||
380 | |||
381 | if (ret == 0) | ||
382 | dyn_tick->state |= DYN_TICK_ENABLED; | ||
383 | } | ||
384 | spin_unlock_irqrestore(&dyn_tick->lock, flags); | ||
385 | } | ||
386 | |||
387 | return ret; | ||
388 | } | ||
389 | |||
390 | static int timer_dyn_tick_disable(void) | ||
391 | { | ||
392 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
393 | unsigned long flags; | ||
394 | int ret = -ENODEV; | ||
395 | |||
396 | if (dyn_tick) { | ||
397 | spin_lock_irqsave(&dyn_tick->lock, flags); | ||
398 | ret = 0; | ||
399 | if (dyn_tick->state & DYN_TICK_ENABLED) { | ||
400 | ret = dyn_tick->disable(); | ||
401 | |||
402 | if (ret == 0) | ||
403 | dyn_tick->state &= ~DYN_TICK_ENABLED; | ||
404 | } | ||
405 | spin_unlock_irqrestore(&dyn_tick->lock, flags); | ||
406 | } | ||
407 | |||
408 | return ret; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Reprogram the system timer for at least the calculated time interval. | ||
413 | * This function should be called from the idle thread with IRQs disabled, | ||
414 | * immediately before sleeping. | ||
415 | */ | ||
416 | void timer_dyn_reprogram(void) | ||
417 | { | ||
418 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
419 | unsigned long next, seq, flags; | ||
420 | |||
421 | if (!dyn_tick) | ||
422 | return; | ||
423 | |||
424 | spin_lock_irqsave(&dyn_tick->lock, flags); | ||
425 | if (dyn_tick->state & DYN_TICK_ENABLED) { | ||
426 | next = next_timer_interrupt(); | ||
427 | do { | ||
428 | seq = read_seqbegin(&xtime_lock); | ||
429 | dyn_tick->reprogram(next - jiffies); | ||
430 | } while (read_seqretry(&xtime_lock, seq)); | ||
431 | } | ||
432 | spin_unlock_irqrestore(&dyn_tick->lock, flags); | ||
433 | } | ||
434 | |||
435 | static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) | ||
436 | { | ||
437 | return sprintf(buf, "%i\n", | ||
438 | (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); | ||
439 | } | ||
440 | |||
441 | static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, | ||
442 | size_t count) | ||
443 | { | ||
444 | unsigned int enable = simple_strtoul(buf, NULL, 2); | ||
445 | |||
446 | if (enable) | ||
447 | timer_dyn_tick_enable(); | ||
448 | else | ||
449 | timer_dyn_tick_disable(); | ||
450 | |||
451 | return count; | ||
452 | } | ||
453 | static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); | ||
454 | |||
455 | /* | ||
456 | * dyntick=enable|disable | ||
457 | */ | ||
458 | static char dyntick_str[4] __initdata = ""; | ||
459 | |||
460 | static int __init dyntick_setup(char *str) | ||
461 | { | ||
462 | if (str) | ||
463 | strlcpy(dyntick_str, str, sizeof(dyntick_str)); | ||
464 | return 1; | ||
465 | } | ||
466 | |||
467 | __setup("dyntick=", dyntick_setup); | ||
468 | #endif | ||
469 | |||
470 | static int __init timer_init_sysfs(void) | 370 | static int __init timer_init_sysfs(void) |
471 | { | 371 | { |
472 | int ret = sysdev_class_register(&timer_sysclass); | 372 | int ret = sysdev_class_register(&timer_sysclass); |
@@ -475,19 +375,6 @@ static int __init timer_init_sysfs(void) | |||
475 | ret = sysdev_register(&system_timer->dev); | 375 | ret = sysdev_register(&system_timer->dev); |
476 | } | 376 | } |
477 | 377 | ||
478 | #ifdef CONFIG_NO_IDLE_HZ | ||
479 | if (ret == 0 && system_timer->dyn_tick) { | ||
480 | ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick); | ||
481 | |||
482 | /* | ||
483 | * Turn on dynamic tick after calibrate delay | ||
484 | * for correct bogomips | ||
485 | */ | ||
486 | if (ret == 0 && dyntick_str[0] == 'e') | ||
487 | ret = timer_dyn_tick_enable(); | ||
488 | } | ||
489 | #endif | ||
490 | |||
491 | return ret; | 378 | return ret; |
492 | } | 379 | } |
493 | 380 | ||
@@ -500,10 +387,5 @@ void __init time_init(void) | |||
500 | system_timer->offset = dummy_gettimeoffset; | 387 | system_timer->offset = dummy_gettimeoffset; |
501 | #endif | 388 | #endif |
502 | system_timer->init(); | 389 | system_timer->init(); |
503 | |||
504 | #ifdef CONFIG_NO_IDLE_HZ | ||
505 | if (system_timer->dyn_tick) | ||
506 | spin_lock_init(&system_timer->dyn_tick->lock); | ||
507 | #endif | ||
508 | } | 390 | } |
509 | 391 | ||