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

Configure Feed

Select the types of activity you want to include in your feed.

clocksource: add enable() and disable() callbacks

Add enable() and disable() callbacks for clocksources.

This allows us to put unused clocksources in power save mode. The
functions clocksource_enable() and clocksource_disable() wrap the
callbacks and are inserted in the timekeeping code to enable before use
and disable after switching to a new clocksource.

Signed-off-by: Magnus Damm <damm@igel.co.jp>
Acked-by: John Stultz <johnstul@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Magnus Damm and committed by
Linus Torvalds
4614e6ad 8e19608e

+40 -3
+31
include/linux/clocksource.h
··· 144 144 * The ideal clocksource. A must-use where 145 145 * available. 146 146 * @read: returns a cycle value, passes clocksource as argument 147 + * @enable: optional function to enable the clocksource 148 + * @disable: optional function to disable the clocksource 147 149 * @mask: bitmask for two's complement 148 150 * subtraction of non 64 bit counters 149 151 * @mult: cycle to nanosecond multiplier (adjusted by NTP) ··· 165 163 struct list_head list; 166 164 int rating; 167 165 cycle_t (*read)(struct clocksource *cs); 166 + int (*enable)(struct clocksource *cs); 167 + void (*disable)(struct clocksource *cs); 168 168 cycle_t mask; 169 169 u32 mult; 170 170 u32 mult_orig; ··· 276 272 static inline cycle_t clocksource_read(struct clocksource *cs) 277 273 { 278 274 return cs->read(cs); 275 + } 276 + 277 + /** 278 + * clocksource_enable: - enable clocksource 279 + * @cs: pointer to clocksource 280 + * 281 + * Enables the specified clocksource. The clocksource callback 282 + * function should start up the hardware and setup mult and field 283 + * members of struct clocksource to reflect hardware capabilities. 284 + */ 285 + static inline int clocksource_enable(struct clocksource *cs) 286 + { 287 + return cs->enable ? cs->enable(cs) : 0; 288 + } 289 + 290 + /** 291 + * clocksource_disable: - disable clocksource 292 + * @cs: pointer to clocksource 293 + * 294 + * Disables the specified clocksource. The clocksource callback 295 + * function should power down the now unused hardware block to 296 + * save power. 297 + */ 298 + static inline void clocksource_disable(struct clocksource *cs) 299 + { 300 + if (cs->disable) 301 + cs->disable(cs); 279 302 } 280 303 281 304 /**
+9 -3
kernel/time/timekeeping.c
··· 182 182 */ 183 183 static void change_clocksource(void) 184 184 { 185 - struct clocksource *new; 185 + struct clocksource *new, *old; 186 186 187 187 new = clocksource_get_next(); 188 188 ··· 191 191 192 192 clocksource_forward_now(); 193 193 194 - new->raw_time = clock->raw_time; 194 + if (clocksource_enable(new)) 195 + return; 195 196 197 + new->raw_time = clock->raw_time; 198 + old = clock; 196 199 clock = new; 200 + clocksource_disable(old); 201 + 197 202 clock->cycle_last = 0; 198 - clock->cycle_last = clocksource_read(new); 203 + clock->cycle_last = clocksource_read(clock); 199 204 clock->error = 0; 200 205 clock->xtime_nsec = 0; 201 206 clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); ··· 297 292 ntp_init(); 298 293 299 294 clock = clocksource_get_next(); 295 + clocksource_enable(clock); 300 296 clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); 301 297 clock->cycle_last = clocksource_read(clock); 302 298