diff options
Diffstat (limited to 'kernel/time/clocksource.c')
| -rw-r--r-- | kernel/time/clocksource.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 1f5dde637457..c18d7efa1b4b 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -531,7 +531,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs) | |||
| 531 | return max_nsecs - (max_nsecs >> 5); | 531 | return max_nsecs - (max_nsecs >> 5); |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | #ifdef CONFIG_GENERIC_TIME | 534 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET |
| 535 | 535 | ||
| 536 | /** | 536 | /** |
| 537 | * clocksource_select - Select the best clocksource available | 537 | * clocksource_select - Select the best clocksource available |
| @@ -577,7 +577,7 @@ static void clocksource_select(void) | |||
| 577 | } | 577 | } |
| 578 | } | 578 | } |
| 579 | 579 | ||
| 580 | #else /* CONFIG_GENERIC_TIME */ | 580 | #else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */ |
| 581 | 581 | ||
| 582 | static inline void clocksource_select(void) { } | 582 | static inline void clocksource_select(void) { } |
| 583 | 583 | ||
| @@ -625,6 +625,73 @@ static void clocksource_enqueue(struct clocksource *cs) | |||
| 625 | list_add(&cs->list, entry); | 625 | list_add(&cs->list, entry); |
| 626 | } | 626 | } |
| 627 | 627 | ||
| 628 | |||
| 629 | /* | ||
| 630 | * Maximum time we expect to go between ticks. This includes idle | ||
| 631 | * tickless time. It provides the trade off between selecting a | ||
| 632 | * mult/shift pair that is very precise but can only handle a short | ||
| 633 | * period of time, vs. a mult/shift pair that can handle long periods | ||
| 634 | * of time but isn't as precise. | ||
| 635 | * | ||
| 636 | * This is a subsystem constant, and actual hardware limitations | ||
| 637 | * may override it (ie: clocksources that wrap every 3 seconds). | ||
| 638 | */ | ||
| 639 | #define MAX_UPDATE_LENGTH 5 /* Seconds */ | ||
| 640 | |||
| 641 | /** | ||
| 642 | * __clocksource_updatefreq_scale - Used update clocksource with new freq | ||
| 643 | * @t: clocksource to be registered | ||
| 644 | * @scale: Scale factor multiplied against freq to get clocksource hz | ||
| 645 | * @freq: clocksource frequency (cycles per second) divided by scale | ||
| 646 | * | ||
| 647 | * This should only be called from the clocksource->enable() method. | ||
| 648 | * | ||
| 649 | * This *SHOULD NOT* be called directly! Please use the | ||
| 650 | * clocksource_updatefreq_hz() or clocksource_updatefreq_khz helper functions. | ||
| 651 | */ | ||
| 652 | void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq) | ||
| 653 | { | ||
| 654 | /* | ||
| 655 | * Ideally we want to use some of the limits used in | ||
| 656 | * clocksource_max_deferment, to provide a more informed | ||
| 657 | * MAX_UPDATE_LENGTH. But for now this just gets the | ||
| 658 | * register interface working properly. | ||
| 659 | */ | ||
| 660 | clocks_calc_mult_shift(&cs->mult, &cs->shift, freq, | ||
| 661 | NSEC_PER_SEC/scale, | ||
| 662 | MAX_UPDATE_LENGTH*scale); | ||
| 663 | cs->max_idle_ns = clocksource_max_deferment(cs); | ||
| 664 | } | ||
| 665 | EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale); | ||
| 666 | |||
| 667 | /** | ||
| 668 | * __clocksource_register_scale - Used to install new clocksources | ||
| 669 | * @t: clocksource to be registered | ||
| 670 | * @scale: Scale factor multiplied against freq to get clocksource hz | ||
| 671 | * @freq: clocksource frequency (cycles per second) divided by scale | ||
| 672 | * | ||
| 673 | * Returns -EBUSY if registration fails, zero otherwise. | ||
| 674 | * | ||
| 675 | * This *SHOULD NOT* be called directly! Please use the | ||
| 676 | * clocksource_register_hz() or clocksource_register_khz helper functions. | ||
| 677 | */ | ||
| 678 | int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) | ||
| 679 | { | ||
| 680 | |||
| 681 | /* Intialize mult/shift and max_idle_ns */ | ||
| 682 | __clocksource_updatefreq_scale(cs, scale, freq); | ||
| 683 | |||
| 684 | /* Add clocksource to the clcoksource list */ | ||
| 685 | mutex_lock(&clocksource_mutex); | ||
| 686 | clocksource_enqueue(cs); | ||
| 687 | clocksource_select(); | ||
| 688 | clocksource_enqueue_watchdog(cs); | ||
| 689 | mutex_unlock(&clocksource_mutex); | ||
| 690 | return 0; | ||
| 691 | } | ||
| 692 | EXPORT_SYMBOL_GPL(__clocksource_register_scale); | ||
| 693 | |||
| 694 | |||
| 628 | /** | 695 | /** |
| 629 | * clocksource_register - Used to install new clocksources | 696 | * clocksource_register - Used to install new clocksources |
| 630 | * @t: clocksource to be registered | 697 | * @t: clocksource to be registered |
