1 /* 2 * linux/kernel/time/clocksource.c 3 * 4 * This file contains the functions which manage clocksource drivers. 5 * 6 * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * 22 * TODO WishList: 23 * o Allow clocksource drivers to be unregistered 24 * o get rid of clocksource_jiffies extern 25 */ 26 27 #include <linux/clocksource.h> 28 #include <linux/sysdev.h> 29 #include <linux/init.h> 30 #include <linux/module.h> 31 32 /* XXX - Would like a better way for initializing curr_clocksource */ 33 extern struct clocksource clocksource_jiffies; 34 35 /*[Clocksource internal variables]--------- 36 * curr_clocksource: 37 * currently selected clocksource. Initialized to clocksource_jiffies. 38 * next_clocksource: 39 * pending next selected clocksource. 40 * clocksource_list: 41 * linked list with the registered clocksources 42 * clocksource_lock: 43 * protects manipulations to curr_clocksource and next_clocksource 44 * and the clocksource_list 45 * override_name: 46 * Name of the user-specified clocksource. 47 */ 48 static struct clocksource *curr_clocksource = &clocksource_jiffies; 49 static struct clocksource *next_clocksource; 50 static LIST_HEAD(clocksource_list); 51 static DEFINE_SPINLOCK(clocksource_lock); 52 static char override_name[32]; 53 static int finished_booting; 54 55 /* clocksource_done_booting - Called near the end of bootup 56 * 57 * Hack to avoid lots of clocksource churn at boot time 58 */ 59 static int __init clocksource_done_booting(void) 60 { 61 finished_booting = 1; 62 return 0; 63 } 64 65 late_initcall(clocksource_done_booting); 66 67 /** 68 * clocksource_get_next - Returns the selected clocksource 69 * 70 */ 71 struct clocksource *clocksource_get_next(void) 72 { 73 unsigned long flags; 74 75 spin_lock_irqsave(&clocksource_lock, flags); 76 if (next_clocksource && finished_booting) { 77 curr_clocksource = next_clocksource; 78 next_clocksource = NULL; 79 } 80 spin_unlock_irqrestore(&clocksource_lock, flags); 81 82 return curr_clocksource; 83 } 84 85 /** 86 * select_clocksource - Finds the best registered clocksource. 87 * 88 * Private function. Must hold clocksource_lock when called. 89 * 90 * Looks through the list of registered clocksources, returning 91 * the one with the highest rating value. If there is a clocksource 92 * name that matches the override string, it returns that clocksource. 93 */ 94 static struct clocksource *select_clocksource(void) 95 { 96 struct clocksource *best = NULL; 97 struct list_head *tmp; 98 99 list_for_each(tmp, &clocksource_list) { 100 struct clocksource *src; 101 102 src = list_entry(tmp, struct clocksource, list); 103 if (!best) 104 best = src; 105 106 /* check for override: */ 107 if (strlen(src->name) == strlen(override_name) && 108 !strcmp(src->name, override_name)) { 109 best = src; 110 break; 111 } 112 /* pick the highest rating: */ 113 if (src->rating > best->rating) 114 best = src; 115 } 116 117 return best; 118 } 119 120 /** 121 * is_registered_source - Checks if clocksource is registered 122 * @c: pointer to a clocksource 123 * 124 * Private helper function. Must hold clocksource_lock when called. 125 * 126 * Returns one if the clocksource is already registered, zero otherwise. 127 */ 128 static int is_registered_source(struct clocksource *c) 129 { 130 int len = strlen(c->name); 131 struct list_head *tmp; 132 133 list_for_each(tmp, &clocksource_list) { 134 struct clocksource *src; 135 136 src = list_entry(tmp, struct clocksource, list); 137 if (strlen(src->name) == len && !strcmp(src->name, c->name)) 138 return 1; 139 } 140 141 return 0; 142 } 143 144 /** 145 * clocksource_register - Used to install new clocksources 146 * @t: clocksource to be registered 147 * 148 * Returns -EBUSY if registration fails, zero otherwise. 149 */ 150 int clocksource_register(struct clocksource *c) 151 { 152 int ret = 0; 153 unsigned long flags; 154 155 spin_lock_irqsave(&clocksource_lock, flags); 156 /* check if clocksource is already registered */ 157 if (is_registered_source(c)) { 158 printk("register_clocksource: Cannot register %s. " 159 "Already registered!", c->name); 160 ret = -EBUSY; 161 } else { 162 /* register it */ 163 list_add(&c->list, &clocksource_list); 164 /* scan the registered clocksources, and pick the best one */ 165 next_clocksource = select_clocksource(); 166 } 167 spin_unlock_irqrestore(&clocksource_lock, flags); 168 return ret; 169 } 170 EXPORT_SYMBOL(clocksource_register); 171 172 /** 173 * clocksource_reselect - Rescan list for next clocksource 174 * 175 * A quick helper function to be used if a clocksource changes its 176 * rating. Forces the clocksource list to be re-scanned for the best 177 * clocksource. 178 */ 179 void clocksource_reselect(void) 180 { 181 unsigned long flags; 182 183 spin_lock_irqsave(&clocksource_lock, flags); 184 next_clocksource = select_clocksource(); 185 spin_unlock_irqrestore(&clocksource_lock, flags); 186 } 187 EXPORT_SYMBOL(clocksource_reselect); 188 189 /** 190 * sysfs_show_current_clocksources - sysfs interface for current clocksource 191 * @dev: unused 192 * @buf: char buffer to be filled with clocksource list 193 * 194 * Provides sysfs interface for listing current clocksource. 195 */ 196 static ssize_t 197 sysfs_show_current_clocksources(struct sys_device *dev, char *buf) 198 { 199 char *curr = buf; 200 201 spin_lock_irq(&clocksource_lock); 202 curr += sprintf(curr, "%s ", curr_clocksource->name); 203 spin_unlock_irq(&clocksource_lock); 204 205 curr += sprintf(curr, "\n"); 206 207 return curr - buf; 208 } 209 210 /** 211 * sysfs_override_clocksource - interface for manually overriding clocksource 212 * @dev: unused 213 * @buf: name of override clocksource 214 * @count: length of buffer 215 * 216 * Takes input from sysfs interface for manually overriding the default 217 * clocksource selction. 218 */ 219 static ssize_t sysfs_override_clocksource(struct sys_device *dev, 220 const char *buf, size_t count) 221 { 222 size_t ret = count; 223 /* strings from sysfs write are not 0 terminated! */ 224 if (count >= sizeof(override_name)) 225 return -EINVAL; 226 227 /* strip of \n: */ 228 if (buf[count-1] == '\n') 229 count--; 230 if (count < 1) 231 return -EINVAL; 232 233 spin_lock_irq(&clocksource_lock); 234 235 /* copy the name given: */ 236 memcpy(override_name, buf, count); 237 override_name[count] = 0; 238 239 /* try to select it: */ 240 next_clocksource = select_clocksource(); 241 242 spin_unlock_irq(&clocksource_lock); 243 244 return ret; 245 } 246 247 /** 248 * sysfs_show_available_clocksources - sysfs interface for listing clocksource 249 * @dev: unused 250 * @buf: char buffer to be filled with clocksource list 251 * 252 * Provides sysfs interface for listing registered clocksources 253 */ 254 static ssize_t 255 sysfs_show_available_clocksources(struct sys_device *dev, char *buf) 256 { 257 struct list_head *tmp; 258 char *curr = buf; 259 260 spin_lock_irq(&clocksource_lock); 261 list_for_each(tmp, &clocksource_list) { 262 struct clocksource *src; 263 264 src = list_entry(tmp, struct clocksource, list); 265 curr += sprintf(curr, "%s ", src->name); 266 } 267 spin_unlock_irq(&clocksource_lock); 268 269 curr += sprintf(curr, "\n"); 270 271 return curr - buf; 272 } 273 274 /* 275 * Sysfs setup bits: 276 */ 277 static SYSDEV_ATTR(current_clocksource, 0600, sysfs_show_current_clocksources, 278 sysfs_override_clocksource); 279 280 static SYSDEV_ATTR(available_clocksource, 0600, 281 sysfs_show_available_clocksources, NULL); 282 283 static struct sysdev_class clocksource_sysclass = { 284 set_kset_name("clocksource"), 285 }; 286 287 static struct sys_device device_clocksource = { 288 .id = 0, 289 .cls = &clocksource_sysclass, 290 }; 291 292 static int __init init_clocksource_sysfs(void) 293 { 294 int error = sysdev_class_register(&clocksource_sysclass); 295 296 if (!error) 297 error = sysdev_register(&device_clocksource); 298 if (!error) 299 error = sysdev_create_file( 300 &device_clocksource, 301 &attr_current_clocksource); 302 if (!error) 303 error = sysdev_create_file( 304 &device_clocksource, 305 &attr_available_clocksource); 306 return error; 307 } 308 309 device_initcall(init_clocksource_sysfs); 310 311 /** 312 * boot_override_clocksource - boot clock override 313 * @str: override name 314 * 315 * Takes a clocksource= boot argument and uses it 316 * as the clocksource override name. 317 */ 318 static int __init boot_override_clocksource(char* str) 319 { 320 unsigned long flags; 321 spin_lock_irqsave(&clocksource_lock, flags); 322 if (str) 323 strlcpy(override_name, str, sizeof(override_name)); 324 spin_unlock_irqrestore(&clocksource_lock, flags); 325 return 1; 326 } 327 328 __setup("clocksource=", boot_override_clocksource); 329 330 /** 331 * boot_override_clock - Compatibility layer for deprecated boot option 332 * @str: override name 333 * 334 * DEPRECATED! Takes a clock= boot argument and uses it 335 * as the clocksource override name 336 */ 337 static int __init boot_override_clock(char* str) 338 { 339 if (!strcmp(str, "pmtmr")) { 340 printk("Warning: clock=pmtmr is deprecated. " 341 "Use clocksource=acpi_pm.\n"); 342 return boot_override_clocksource("acpi_pm"); 343 } 344 printk("Warning! clock= boot option is deprecated. " 345 "Use clocksource=xyz\n"); 346 return boot_override_clocksource(str); 347 } 348 349 __setup("clock=", boot_override_clock); 350