diff options
Diffstat (limited to 'kernel/time/clocksource.c')
| -rw-r--r-- | kernel/time/clocksource.c | 105 |
1 files changed, 101 insertions, 4 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 5e18c6ab2c6a..e85c23404d34 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -39,7 +39,7 @@ void timecounter_init(struct timecounter *tc, | |||
| 39 | tc->cycle_last = cc->read(cc); | 39 | tc->cycle_last = cc->read(cc); |
| 40 | tc->nsec = start_tstamp; | 40 | tc->nsec = start_tstamp; |
| 41 | } | 41 | } |
| 42 | EXPORT_SYMBOL(timecounter_init); | 42 | EXPORT_SYMBOL_GPL(timecounter_init); |
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | * timecounter_read_delta - get nanoseconds since last call of this function | 45 | * timecounter_read_delta - get nanoseconds since last call of this function |
| @@ -83,7 +83,7 @@ u64 timecounter_read(struct timecounter *tc) | |||
| 83 | 83 | ||
| 84 | return nsec; | 84 | return nsec; |
| 85 | } | 85 | } |
| 86 | EXPORT_SYMBOL(timecounter_read); | 86 | EXPORT_SYMBOL_GPL(timecounter_read); |
| 87 | 87 | ||
| 88 | u64 timecounter_cyc2time(struct timecounter *tc, | 88 | u64 timecounter_cyc2time(struct timecounter *tc, |
| 89 | cycle_t cycle_tstamp) | 89 | cycle_t cycle_tstamp) |
| @@ -105,7 +105,60 @@ u64 timecounter_cyc2time(struct timecounter *tc, | |||
| 105 | 105 | ||
| 106 | return nsec; | 106 | return nsec; |
| 107 | } | 107 | } |
| 108 | EXPORT_SYMBOL(timecounter_cyc2time); | 108 | EXPORT_SYMBOL_GPL(timecounter_cyc2time); |
| 109 | |||
| 110 | /** | ||
| 111 | * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks | ||
| 112 | * @mult: pointer to mult variable | ||
| 113 | * @shift: pointer to shift variable | ||
| 114 | * @from: frequency to convert from | ||
| 115 | * @to: frequency to convert to | ||
| 116 | * @minsec: guaranteed runtime conversion range in seconds | ||
| 117 | * | ||
| 118 | * The function evaluates the shift/mult pair for the scaled math | ||
| 119 | * operations of clocksources and clockevents. | ||
| 120 | * | ||
| 121 | * @to and @from are frequency values in HZ. For clock sources @to is | ||
| 122 | * NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock | ||
| 123 | * event @to is the counter frequency and @from is NSEC_PER_SEC. | ||
| 124 | * | ||
| 125 | * The @minsec conversion range argument controls the time frame in | ||
| 126 | * seconds which must be covered by the runtime conversion with the | ||
| 127 | * calculated mult and shift factors. This guarantees that no 64bit | ||
| 128 | * overflow happens when the input value of the conversion is | ||
| 129 | * multiplied with the calculated mult factor. Larger ranges may | ||
| 130 | * reduce the conversion accuracy by chosing smaller mult and shift | ||
| 131 | * factors. | ||
| 132 | */ | ||
| 133 | void | ||
| 134 | clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec) | ||
| 135 | { | ||
| 136 | u64 tmp; | ||
| 137 | u32 sft, sftacc= 32; | ||
| 138 | |||
| 139 | /* | ||
| 140 | * Calculate the shift factor which is limiting the conversion | ||
| 141 | * range: | ||
| 142 | */ | ||
| 143 | tmp = ((u64)minsec * from) >> 32; | ||
| 144 | while (tmp) { | ||
| 145 | tmp >>=1; | ||
| 146 | sftacc--; | ||
| 147 | } | ||
| 148 | |||
| 149 | /* | ||
| 150 | * Find the conversion shift/mult pair which has the best | ||
| 151 | * accuracy and fits the maxsec conversion range: | ||
| 152 | */ | ||
| 153 | for (sft = 32; sft > 0; sft--) { | ||
| 154 | tmp = (u64) to << sft; | ||
| 155 | do_div(tmp, from); | ||
| 156 | if ((tmp >> sftacc) == 0) | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | *mult = tmp; | ||
| 160 | *shift = sft; | ||
| 161 | } | ||
| 109 | 162 | ||
| 110 | /*[Clocksource internal variables]--------- | 163 | /*[Clocksource internal variables]--------- |
| 111 | * curr_clocksource: | 164 | * curr_clocksource: |
| @@ -413,6 +466,47 @@ void clocksource_touch_watchdog(void) | |||
| 413 | clocksource_resume_watchdog(); | 466 | clocksource_resume_watchdog(); |
| 414 | } | 467 | } |
| 415 | 468 | ||
| 469 | /** | ||
| 470 | * clocksource_max_deferment - Returns max time the clocksource can be deferred | ||
| 471 | * @cs: Pointer to clocksource | ||
| 472 | * | ||
| 473 | */ | ||
| 474 | static u64 clocksource_max_deferment(struct clocksource *cs) | ||
| 475 | { | ||
| 476 | u64 max_nsecs, max_cycles; | ||
| 477 | |||
| 478 | /* | ||
| 479 | * Calculate the maximum number of cycles that we can pass to the | ||
| 480 | * cyc2ns function without overflowing a 64-bit signed result. The | ||
| 481 | * maximum number of cycles is equal to ULLONG_MAX/cs->mult which | ||
| 482 | * is equivalent to the below. | ||
| 483 | * max_cycles < (2^63)/cs->mult | ||
| 484 | * max_cycles < 2^(log2((2^63)/cs->mult)) | ||
| 485 | * max_cycles < 2^(log2(2^63) - log2(cs->mult)) | ||
| 486 | * max_cycles < 2^(63 - log2(cs->mult)) | ||
| 487 | * max_cycles < 1 << (63 - log2(cs->mult)) | ||
| 488 | * Please note that we add 1 to the result of the log2 to account for | ||
| 489 | * any rounding errors, ensure the above inequality is satisfied and | ||
| 490 | * no overflow will occur. | ||
| 491 | */ | ||
| 492 | max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1)); | ||
| 493 | |||
| 494 | /* | ||
| 495 | * The actual maximum number of cycles we can defer the clocksource is | ||
| 496 | * determined by the minimum of max_cycles and cs->mask. | ||
| 497 | */ | ||
| 498 | max_cycles = min_t(u64, max_cycles, (u64) cs->mask); | ||
| 499 | max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift); | ||
| 500 | |||
| 501 | /* | ||
| 502 | * To ensure that the clocksource does not wrap whilst we are idle, | ||
| 503 | * limit the time the clocksource can be deferred by 12.5%. Please | ||
| 504 | * note a margin of 12.5% is used because this can be computed with | ||
| 505 | * a shift, versus say 10% which would require division. | ||
| 506 | */ | ||
| 507 | return max_nsecs - (max_nsecs >> 5); | ||
| 508 | } | ||
| 509 | |||
| 416 | #ifdef CONFIG_GENERIC_TIME | 510 | #ifdef CONFIG_GENERIC_TIME |
| 417 | 511 | ||
| 418 | /** | 512 | /** |
| @@ -511,6 +605,9 @@ static void clocksource_enqueue(struct clocksource *cs) | |||
| 511 | */ | 605 | */ |
| 512 | int clocksource_register(struct clocksource *cs) | 606 | int clocksource_register(struct clocksource *cs) |
| 513 | { | 607 | { |
| 608 | /* calculate max idle time permitted for this clocksource */ | ||
| 609 | cs->max_idle_ns = clocksource_max_deferment(cs); | ||
| 610 | |||
| 514 | mutex_lock(&clocksource_mutex); | 611 | mutex_lock(&clocksource_mutex); |
| 515 | clocksource_enqueue(cs); | 612 | clocksource_enqueue(cs); |
| 516 | clocksource_select(); | 613 | clocksource_select(); |
| @@ -580,7 +677,7 @@ sysfs_show_current_clocksources(struct sys_device *dev, | |||
| 580 | * @count: length of buffer | 677 | * @count: length of buffer |
| 581 | * | 678 | * |
| 582 | * Takes input from sysfs interface for manually overriding the default | 679 | * Takes input from sysfs interface for manually overriding the default |
| 583 | * clocksource selction. | 680 | * clocksource selection. |
| 584 | */ | 681 | */ |
| 585 | static ssize_t sysfs_override_clocksource(struct sys_device *dev, | 682 | static ssize_t sysfs_override_clocksource(struct sys_device *dev, |
| 586 | struct sysdev_attribute *attr, | 683 | struct sysdev_attribute *attr, |
