diff options
| author | Anton Altaparmakov <aia21@cantab.net> | 2005-06-26 17:19:40 -0400 |
|---|---|---|
| committer | Anton Altaparmakov <aia21@cantab.net> | 2005-06-26 17:19:40 -0400 |
| commit | 2a322e4c08be4e7cb0c04b427ddaaa679fd88863 (patch) | |
| tree | ad8cc17bfd3b5e57e36f07a249028667d72f0b96 /arch/arm/kernel/time.c | |
| parent | ba6d2377c85c9b8a793f455d8c9b6cf31985d70f (diff) | |
| parent | 8678887e7fb43cd6c9be6c9807b05e77848e0920 (diff) | |
Automatic merge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'arch/arm/kernel/time.c')
| -rw-r--r-- | arch/arm/kernel/time.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index c232f24f4a60..06054c9ba074 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
| @@ -381,6 +381,95 @@ static struct sysdev_class timer_sysclass = { | |||
| 381 | .resume = timer_resume, | 381 | .resume = timer_resume, |
| 382 | }; | 382 | }; |
| 383 | 383 | ||
| 384 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 385 | static int timer_dyn_tick_enable(void) | ||
| 386 | { | ||
| 387 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
| 388 | unsigned long flags; | ||
| 389 | int ret = -ENODEV; | ||
| 390 | |||
| 391 | if (dyn_tick) { | ||
| 392 | write_seqlock_irqsave(&xtime_lock, flags); | ||
| 393 | ret = 0; | ||
| 394 | if (!(dyn_tick->state & DYN_TICK_ENABLED)) { | ||
| 395 | ret = dyn_tick->enable(); | ||
| 396 | |||
| 397 | if (ret == 0) | ||
| 398 | dyn_tick->state |= DYN_TICK_ENABLED; | ||
| 399 | } | ||
| 400 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
| 401 | } | ||
| 402 | |||
| 403 | return ret; | ||
| 404 | } | ||
| 405 | |||
| 406 | static int timer_dyn_tick_disable(void) | ||
| 407 | { | ||
| 408 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
| 409 | unsigned long flags; | ||
| 410 | int ret = -ENODEV; | ||
| 411 | |||
| 412 | if (dyn_tick) { | ||
| 413 | write_seqlock_irqsave(&xtime_lock, flags); | ||
| 414 | ret = 0; | ||
| 415 | if (dyn_tick->state & DYN_TICK_ENABLED) { | ||
| 416 | ret = dyn_tick->disable(); | ||
| 417 | |||
| 418 | if (ret == 0) | ||
| 419 | dyn_tick->state &= ~DYN_TICK_ENABLED; | ||
| 420 | } | ||
| 421 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
| 422 | } | ||
| 423 | |||
| 424 | return ret; | ||
| 425 | } | ||
| 426 | |||
| 427 | void timer_dyn_reprogram(void) | ||
| 428 | { | ||
| 429 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
| 430 | unsigned long flags; | ||
| 431 | |||
| 432 | write_seqlock_irqsave(&xtime_lock, flags); | ||
| 433 | if (dyn_tick->state & DYN_TICK_ENABLED) | ||
| 434 | dyn_tick->reprogram(next_timer_interrupt() - jiffies); | ||
| 435 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
| 436 | } | ||
| 437 | |||
| 438 | static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) | ||
| 439 | { | ||
| 440 | return sprintf(buf, "%i\n", | ||
| 441 | (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); | ||
| 442 | } | ||
| 443 | |||
| 444 | static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, | ||
| 445 | size_t count) | ||
| 446 | { | ||
| 447 | unsigned int enable = simple_strtoul(buf, NULL, 2); | ||
| 448 | |||
| 449 | if (enable) | ||
| 450 | timer_dyn_tick_enable(); | ||
| 451 | else | ||
| 452 | timer_dyn_tick_disable(); | ||
| 453 | |||
| 454 | return count; | ||
| 455 | } | ||
| 456 | static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); | ||
| 457 | |||
| 458 | /* | ||
| 459 | * dyntick=enable|disable | ||
| 460 | */ | ||
| 461 | static char dyntick_str[4] __initdata = ""; | ||
| 462 | |||
| 463 | static int __init dyntick_setup(char *str) | ||
| 464 | { | ||
| 465 | if (str) | ||
| 466 | strlcpy(dyntick_str, str, sizeof(dyntick_str)); | ||
| 467 | return 1; | ||
| 468 | } | ||
| 469 | |||
| 470 | __setup("dyntick=", dyntick_setup); | ||
| 471 | #endif | ||
| 472 | |||
| 384 | static int __init timer_init_sysfs(void) | 473 | static int __init timer_init_sysfs(void) |
| 385 | { | 474 | { |
| 386 | int ret = sysdev_class_register(&timer_sysclass); | 475 | int ret = sysdev_class_register(&timer_sysclass); |
| @@ -388,6 +477,20 @@ static int __init timer_init_sysfs(void) | |||
| 388 | system_timer->dev.cls = &timer_sysclass; | 477 | system_timer->dev.cls = &timer_sysclass; |
| 389 | ret = sysdev_register(&system_timer->dev); | 478 | ret = sysdev_register(&system_timer->dev); |
| 390 | } | 479 | } |
| 480 | |||
| 481 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 482 | if (ret == 0 && system_timer->dyn_tick) { | ||
| 483 | ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick); | ||
| 484 | |||
| 485 | /* | ||
| 486 | * Turn on dynamic tick after calibrate delay | ||
| 487 | * for correct bogomips | ||
| 488 | */ | ||
| 489 | if (ret == 0 && dyntick_str[0] == 'e') | ||
| 490 | ret = timer_dyn_tick_enable(); | ||
| 491 | } | ||
| 492 | #endif | ||
| 493 | |||
| 391 | return ret; | 494 | return ret; |
| 392 | } | 495 | } |
| 393 | 496 | ||
