Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clocksource: Add __clocksource_updatefreq_hz/khz methods

To properly handle clocksources that change frequencies
at the clocksource->enable() point, this patch adds
a method that will update the clocksource's mult/shift and
max_idle_ns values.

Signed-off-by: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <1279068988-21864-12-git-send-email-johnstul@us.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

John Stultz and committed by
Thomas Gleixner
852db46d f12a15be

+40 -10
+11
include/linux/clocksource.h
··· 292 292 */ 293 293 extern int 294 294 __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq); 295 + extern void 296 + __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq); 295 297 296 298 static inline int clocksource_register_hz(struct clocksource *cs, u32 hz) 297 299 { ··· 305 303 return __clocksource_register_scale(cs, 1000, khz); 306 304 } 307 305 306 + static inline void __clocksource_updatefreq_hz(struct clocksource *cs, u32 hz) 307 + { 308 + __clocksource_updatefreq_scale(cs, 1, hz); 309 + } 310 + 311 + static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz) 312 + { 313 + __clocksource_updatefreq_scale(cs, 1000, khz); 314 + } 308 315 309 316 static inline void 310 317 clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
+29 -10
kernel/time/clocksource.c
··· 639 639 #define MAX_UPDATE_LENGTH 5 /* Seconds */ 640 640 641 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 + /** 642 668 * __clocksource_register_scale - Used to install new clocksources 643 669 * @t: clocksource to be registered 644 670 * @scale: Scale factor multiplied against freq to get clocksource hz ··· 678 652 int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) 679 653 { 680 654 681 - /* 682 - * Ideally we want to use some of the limits used in 683 - * clocksource_max_deferment, to provide a more informed 684 - * MAX_UPDATE_LENGTH. But for now this just gets the 685 - * register interface working properly. 686 - */ 687 - clocks_calc_mult_shift(&cs->mult, &cs->shift, freq, 688 - NSEC_PER_SEC/scale, 689 - MAX_UPDATE_LENGTH*scale); 690 - cs->max_idle_ns = clocksource_max_deferment(cs); 655 + /* Intialize mult/shift and max_idle_ns */ 656 + __clocksource_updatefreq_scale(cs, scale, freq); 691 657 658 + /* Add clocksource to the clcoksource list */ 692 659 mutex_lock(&clocksource_mutex); 693 660 clocksource_enqueue(cs); 694 661 clocksource_select();