1#include <linux/sysdev.h> 2#include <linux/cpu.h> 3#include <linux/smp.h> 4#include <linux/percpu.h> 5#include <linux/init.h> 6#include <linux/sched.h> 7#include <linux/module.h> 8#include <linux/nodemask.h> 9#include <linux/cpumask.h> 10#include <linux/notifier.h> 11 12#include <asm/current.h> 13#include <asm/processor.h> 14#include <asm/cputable.h> 15#include <asm/firmware.h> 16#include <asm/hvcall.h> 17#include <asm/prom.h> 18#include <asm/paca.h> 19#include <asm/lppaca.h> 20#include <asm/machdep.h> 21#include <asm/smp.h> 22 23static DEFINE_PER_CPU(struct cpu, cpu_devices); 24 25/* SMT stuff */ 26 27#ifdef CONFIG_PPC_MULTIPLATFORM 28/* Time in microseconds we delay before sleeping in the idle loop */ 29DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 }; 30 31static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, 32 size_t count) 33{ 34 struct cpu *cpu = container_of(dev, struct cpu, sysdev); 35 ssize_t ret; 36 unsigned long snooze; 37 38 ret = sscanf(buf, "%lu", &snooze); 39 if (ret != 1) 40 return -EINVAL; 41 42 per_cpu(smt_snooze_delay, cpu->sysdev.id) = snooze; 43 44 return count; 45} 46 47static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf) 48{ 49 struct cpu *cpu = container_of(dev, struct cpu, sysdev); 50 51 return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id)); 52} 53 54static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, 55 store_smt_snooze_delay); 56 57/* Only parse OF options if the matching cmdline option was not specified */ 58static int smt_snooze_cmdline; 59 60static int __init smt_setup(void) 61{ 62 struct device_node *options; 63 const unsigned int *val; 64 unsigned int cpu; 65 66 if (!cpu_has_feature(CPU_FTR_SMT)) 67 return -ENODEV; 68 69 options = of_find_node_by_path("/options"); 70 if (!options) 71 return -ENODEV; 72 73 val = of_get_property(options, "ibm,smt-snooze-delay", NULL); 74 if (!smt_snooze_cmdline && val) { 75 for_each_possible_cpu(cpu) 76 per_cpu(smt_snooze_delay, cpu) = *val; 77 } 78 79 of_node_put(options); 80 return 0; 81} 82__initcall(smt_setup); 83 84static int __init setup_smt_snooze_delay(char *str) 85{ 86 unsigned int cpu; 87 int snooze; 88 89 if (!cpu_has_feature(CPU_FTR_SMT)) 90 return 1; 91 92 smt_snooze_cmdline = 1; 93 94 if (get_option(&str, &snooze)) { 95 for_each_possible_cpu(cpu) 96 per_cpu(smt_snooze_delay, cpu) = snooze; 97 } 98 99 return 1; 100} 101__setup("smt-snooze-delay=", setup_smt_snooze_delay); 102 103#endif /* CONFIG_PPC_MULTIPLATFORM */ 104 105/* 106 * Enabling PMCs will slow partition context switch times so we only do 107 * it the first time we write to the PMCs. 108 */ 109 110static DEFINE_PER_CPU(char, pmcs_enabled); 111 112void ppc64_enable_pmcs(void) 113{ 114 /* Only need to enable them once */ 115 if (__get_cpu_var(pmcs_enabled)) 116 return; 117 118 __get_cpu_var(pmcs_enabled) = 1; 119 120 if (ppc_md.enable_pmcs) 121 ppc_md.enable_pmcs(); 122} 123EXPORT_SYMBOL(ppc64_enable_pmcs); 124 125static unsigned long run_on_cpu(unsigned long cpu, 126 unsigned long (*func)(unsigned long), 127 unsigned long arg) 128{ 129 cpumask_t old_affinity = current->cpus_allowed; 130 unsigned long ret; 131 132 /* should return -EINVAL to userspace */ 133 if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) 134 return 0; 135 136 ret = func(arg); 137 138 set_cpus_allowed(current, old_affinity); 139 140 return ret; 141} 142 143#define SYSFS_PMCSETUP(NAME, ADDRESS) \ 144static unsigned long read_##NAME(unsigned long junk) \ 145{ \ 146 return mfspr(ADDRESS); \ 147} \ 148static unsigned long write_##NAME(unsigned long val) \ 149{ \ 150 ppc64_enable_pmcs(); \ 151 mtspr(ADDRESS, val); \ 152 return 0; \ 153} \ 154static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ 155{ \ 156 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 157 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ 158 return sprintf(buf, "%lx\n", val); \ 159} \ 160static ssize_t __attribute_used__ \ 161 store_##NAME(struct sys_device *dev, const char *buf, size_t count) \ 162{ \ 163 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 164 unsigned long val; \ 165 int ret = sscanf(buf, "%lx", &val); \ 166 if (ret != 1) \ 167 return -EINVAL; \ 168 run_on_cpu(cpu->sysdev.id, write_##NAME, val); \ 169 return count; \ 170} 171 172 173/* Let's define all possible registers, we'll only hook up the ones 174 * that are implemented on the current processor 175 */ 176 177SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); 178SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); 179SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); 180SYSFS_PMCSETUP(pmc1, SPRN_PMC1); 181SYSFS_PMCSETUP(pmc2, SPRN_PMC2); 182SYSFS_PMCSETUP(pmc3, SPRN_PMC3); 183SYSFS_PMCSETUP(pmc4, SPRN_PMC4); 184SYSFS_PMCSETUP(pmc5, SPRN_PMC5); 185SYSFS_PMCSETUP(pmc6, SPRN_PMC6); 186SYSFS_PMCSETUP(pmc7, SPRN_PMC7); 187SYSFS_PMCSETUP(pmc8, SPRN_PMC8); 188SYSFS_PMCSETUP(purr, SPRN_PURR); 189SYSFS_PMCSETUP(spurr, SPRN_SPURR); 190SYSFS_PMCSETUP(dscr, SPRN_DSCR); 191 192SYSFS_PMCSETUP(pa6t_pmc0, SPRN_PA6T_PMC0); 193SYSFS_PMCSETUP(pa6t_pmc1, SPRN_PA6T_PMC1); 194SYSFS_PMCSETUP(pa6t_pmc2, SPRN_PA6T_PMC2); 195SYSFS_PMCSETUP(pa6t_pmc3, SPRN_PA6T_PMC3); 196SYSFS_PMCSETUP(pa6t_pmc4, SPRN_PA6T_PMC4); 197SYSFS_PMCSETUP(pa6t_pmc5, SPRN_PA6T_PMC5); 198 199 200static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); 201static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); 202static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); 203static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); 204 205static struct sysdev_attribute ibm_common_attrs[] = { 206 _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), 207 _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), 208}; 209 210static struct sysdev_attribute ibm_pmc_attrs[] = { 211 _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1), 212 _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2), 213 _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3), 214 _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4), 215 _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5), 216 _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6), 217 _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7), 218 _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8), 219}; 220 221static struct sysdev_attribute pa6t_attrs[] = { 222 _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), 223 _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), 224 _SYSDEV_ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0), 225 _SYSDEV_ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1), 226 _SYSDEV_ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2), 227 _SYSDEV_ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3), 228 _SYSDEV_ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4), 229 _SYSDEV_ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5), 230}; 231 232 233static void register_cpu_online(unsigned int cpu) 234{ 235 struct cpu *c = &per_cpu(cpu_devices, cpu); 236 struct sys_device *s = &c->sysdev; 237 struct sysdev_attribute *attrs, *pmc_attrs; 238 int i, nattrs; 239 240 if (!firmware_has_feature(FW_FEATURE_ISERIES) && 241 cpu_has_feature(CPU_FTR_SMT)) 242 sysdev_create_file(s, &attr_smt_snooze_delay); 243 244 /* PMC stuff */ 245 switch (cur_cpu_spec->pmc_type) { 246 case PPC_PMC_IBM: 247 attrs = ibm_common_attrs; 248 nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); 249 pmc_attrs = ibm_pmc_attrs; 250 break; 251 case PPC_PMC_PA6T: 252 /* PA Semi starts counting at PMC0 */ 253 attrs = pa6t_attrs; 254 nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); 255 pmc_attrs = NULL; 256 break; 257 default: 258 attrs = NULL; 259 nattrs = 0; 260 pmc_attrs = NULL; 261 } 262 263 for (i = 0; i < nattrs; i++) 264 sysdev_create_file(s, &attrs[i]); 265 266 if (pmc_attrs) 267 for (i = 0; i < cur_cpu_spec->num_pmcs; i++) 268 sysdev_create_file(s, &pmc_attrs[i]); 269 270 if (cpu_has_feature(CPU_FTR_MMCRA)) 271 sysdev_create_file(s, &attr_mmcra); 272 273 if (cpu_has_feature(CPU_FTR_PURR)) 274 sysdev_create_file(s, &attr_purr); 275 276 if (cpu_has_feature(CPU_FTR_SPURR)) 277 sysdev_create_file(s, &attr_spurr); 278 279 if (cpu_has_feature(CPU_FTR_DSCR)) 280 sysdev_create_file(s, &attr_dscr); 281} 282 283#ifdef CONFIG_HOTPLUG_CPU 284static void unregister_cpu_online(unsigned int cpu) 285{ 286 struct cpu *c = &per_cpu(cpu_devices, cpu); 287 struct sys_device *s = &c->sysdev; 288 struct sysdev_attribute *attrs, *pmc_attrs; 289 int i, nattrs; 290 291 BUG_ON(!c->hotpluggable); 292 293 if (!firmware_has_feature(FW_FEATURE_ISERIES) && 294 cpu_has_feature(CPU_FTR_SMT)) 295 sysdev_remove_file(s, &attr_smt_snooze_delay); 296 297 /* PMC stuff */ 298 switch (cur_cpu_spec->pmc_type) { 299 case PPC_PMC_IBM: 300 attrs = ibm_common_attrs; 301 nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); 302 pmc_attrs = ibm_pmc_attrs; 303 break; 304 case PPC_PMC_PA6T: 305 /* PA Semi starts counting at PMC0 */ 306 attrs = pa6t_attrs; 307 nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); 308 pmc_attrs = NULL; 309 break; 310 default: 311 attrs = NULL; 312 nattrs = 0; 313 pmc_attrs = NULL; 314 } 315 316 for (i = 0; i < nattrs; i++) 317 sysdev_remove_file(s, &attrs[i]); 318 319 if (pmc_attrs) 320 for (i = 0; i < cur_cpu_spec->num_pmcs; i++) 321 sysdev_remove_file(s, &pmc_attrs[i]); 322 323 if (cpu_has_feature(CPU_FTR_MMCRA)) 324 sysdev_remove_file(s, &attr_mmcra); 325 326 if (cpu_has_feature(CPU_FTR_PURR)) 327 sysdev_remove_file(s, &attr_purr); 328 329 if (cpu_has_feature(CPU_FTR_SPURR)) 330 sysdev_remove_file(s, &attr_spurr); 331 332 if (cpu_has_feature(CPU_FTR_DSCR)) 333 sysdev_remove_file(s, &attr_dscr); 334} 335#endif /* CONFIG_HOTPLUG_CPU */ 336 337static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, 338 unsigned long action, void *hcpu) 339{ 340 unsigned int cpu = (unsigned int)(long)hcpu; 341 342 switch (action) { 343 case CPU_ONLINE: 344 case CPU_ONLINE_FROZEN: 345 register_cpu_online(cpu); 346 break; 347#ifdef CONFIG_HOTPLUG_CPU 348 case CPU_DEAD: 349 case CPU_DEAD_FROZEN: 350 unregister_cpu_online(cpu); 351 break; 352#endif 353 } 354 return NOTIFY_OK; 355} 356 357static struct notifier_block __cpuinitdata sysfs_cpu_nb = { 358 .notifier_call = sysfs_cpu_notify, 359}; 360 361static DEFINE_MUTEX(cpu_mutex); 362 363int cpu_add_sysdev_attr(struct sysdev_attribute *attr) 364{ 365 int cpu; 366 367 mutex_lock(&cpu_mutex); 368 369 for_each_possible_cpu(cpu) { 370 sysdev_create_file(get_cpu_sysdev(cpu), attr); 371 } 372 373 mutex_unlock(&cpu_mutex); 374 return 0; 375} 376EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr); 377 378int cpu_add_sysdev_attr_group(struct attribute_group *attrs) 379{ 380 int cpu; 381 struct sys_device *sysdev; 382 383 mutex_lock(&cpu_mutex); 384 385 for_each_possible_cpu(cpu) { 386 sysdev = get_cpu_sysdev(cpu); 387 sysfs_create_group(&sysdev->kobj, attrs); 388 } 389 390 mutex_unlock(&cpu_mutex); 391 return 0; 392} 393EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr_group); 394 395 396void cpu_remove_sysdev_attr(struct sysdev_attribute *attr) 397{ 398 int cpu; 399 400 mutex_lock(&cpu_mutex); 401 402 for_each_possible_cpu(cpu) { 403 sysdev_remove_file(get_cpu_sysdev(cpu), attr); 404 } 405 406 mutex_unlock(&cpu_mutex); 407} 408EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr); 409 410void cpu_remove_sysdev_attr_group(struct attribute_group *attrs) 411{ 412 int cpu; 413 struct sys_device *sysdev; 414 415 mutex_lock(&cpu_mutex); 416 417 for_each_possible_cpu(cpu) { 418 sysdev = get_cpu_sysdev(cpu); 419 sysfs_remove_group(&sysdev->kobj, attrs); 420 } 421 422 mutex_unlock(&cpu_mutex); 423} 424EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr_group); 425 426 427/* NUMA stuff */ 428 429#ifdef CONFIG_NUMA 430static void register_nodes(void) 431{ 432 int i; 433 434 for (i = 0; i < MAX_NUMNODES; i++) 435 register_one_node(i); 436} 437 438int sysfs_add_device_to_node(struct sys_device *dev, int nid) 439{ 440 struct node *node = &node_devices[nid]; 441 return sysfs_create_link(&node->sysdev.kobj, &dev->kobj, 442 kobject_name(&dev->kobj)); 443} 444 445void sysfs_remove_device_from_node(struct sys_device *dev, int nid) 446{ 447 struct node *node = &node_devices[nid]; 448 sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj)); 449} 450 451#else 452static void register_nodes(void) 453{ 454 return; 455} 456 457#endif 458 459EXPORT_SYMBOL_GPL(sysfs_add_device_to_node); 460EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node); 461 462/* Only valid if CPU is present. */ 463static ssize_t show_physical_id(struct sys_device *dev, char *buf) 464{ 465 struct cpu *cpu = container_of(dev, struct cpu, sysdev); 466 467 return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->sysdev.id)); 468} 469static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL); 470 471static int __init topology_init(void) 472{ 473 int cpu; 474 475 register_nodes(); 476 register_cpu_notifier(&sysfs_cpu_nb); 477 478 for_each_possible_cpu(cpu) { 479 struct cpu *c = &per_cpu(cpu_devices, cpu); 480 481 /* 482 * For now, we just see if the system supports making 483 * the RTAS calls for CPU hotplug. But, there may be a 484 * more comprehensive way to do this for an individual 485 * CPU. For instance, the boot cpu might never be valid 486 * for hotplugging. 487 */ 488 if (ppc_md.cpu_die) 489 c->hotpluggable = 1; 490 491 if (cpu_online(cpu) || c->hotpluggable) { 492 register_cpu(c, cpu); 493 494 sysdev_create_file(&c->sysdev, &attr_physical_id); 495 } 496 497 if (cpu_online(cpu)) 498 register_cpu_online(cpu); 499 } 500 501 return 0; 502} 503subsys_initcall(topology_init); 504