diff options
Diffstat (limited to 'arch/arm/kernel')
| -rw-r--r-- | arch/arm/kernel/process.c | 4 | ||||
| -rw-r--r-- | arch/arm/kernel/time.c | 120 |
2 files changed, 1 insertions, 123 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 46bf2ede6128..199b3680118b 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
| @@ -133,10 +133,8 @@ static void default_idle(void) | |||
| 133 | cpu_relax(); | 133 | cpu_relax(); |
| 134 | else { | 134 | else { |
| 135 | local_irq_disable(); | 135 | local_irq_disable(); |
| 136 | if (!need_resched()) { | 136 | if (!need_resched()) |
| 137 | timer_dyn_reprogram(); | ||
| 138 | arch_idle(); | 137 | arch_idle(); |
| 139 | } | ||
| 140 | local_irq_enable(); | 138 | local_irq_enable(); |
| 141 | } | 139 | } |
| 142 | } | 140 | } |
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index b5867eca1d0b..cc5145b28e7f 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
| @@ -365,108 +365,6 @@ static struct sysdev_class timer_sysclass = { | |||
| 365 | .resume = timer_resume, | 365 | .resume = timer_resume, |
| 366 | }; | 366 | }; |
| 367 | 367 | ||
| 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) | 368 | static int __init timer_init_sysfs(void) |
| 471 | { | 369 | { |
| 472 | int ret = sysdev_class_register(&timer_sysclass); | 370 | int ret = sysdev_class_register(&timer_sysclass); |
| @@ -475,19 +373,6 @@ static int __init timer_init_sysfs(void) | |||
| 475 | ret = sysdev_register(&system_timer->dev); | 373 | ret = sysdev_register(&system_timer->dev); |
| 476 | } | 374 | } |
| 477 | 375 | ||
| 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; | 376 | return ret; |
| 492 | } | 377 | } |
| 493 | 378 | ||
| @@ -500,10 +385,5 @@ void __init time_init(void) | |||
| 500 | system_timer->offset = dummy_gettimeoffset; | 385 | system_timer->offset = dummy_gettimeoffset; |
| 501 | #endif | 386 | #endif |
| 502 | system_timer->init(); | 387 | 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 | } | 388 | } |
| 509 | 389 | ||
