topology.c revision 8b646bd759086f6090fe27acf414c0b5faa737f4
1dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens/* 24baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens * Copyright IBM Corp. 2007,2011 3dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 4dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens */ 5dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 6395d31d40cc38270dd7c024691404e2eddf0678dMartin Schwidefsky#define KMSG_COMPONENT "cpu" 7395d31d40cc38270dd7c024691404e2eddf0678dMartin Schwidefsky#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 8395d31d40cc38270dd7c024691404e2eddf0678dMartin Schwidefsky 983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/workqueue.h> 10dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens#include <linux/bootmem.h> 1183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/cpuset.h> 1283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/device.h> 1383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/kernel.h> 14dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens#include <linux/sched.h> 1583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/init.h> 1683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/delay.h> 17dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens#include <linux/cpu.h> 18dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens#include <linux/smp.h> 1983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens#include <linux/mm.h> 20dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 21c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens#define PTF_HORIZONTAL (0UL) 22c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens#define PTF_VERTICAL (1UL) 23c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens#define PTF_CHECK (2UL) 24dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 254cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstruct mask_info { 264cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens struct mask_info *next; 2710d3858950557cd3cc05f647ede597114c610177Heiko Carstens unsigned char id; 28dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens cpumask_t mask; 29dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}; 30dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 31c9af3fa9e1e3e5154649991a14b74f3a2dee19eeHeiko Carstensstatic int topology_enabled = 1; 32dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void topology_work_fn(struct work_struct *work); 33c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstensstatic struct sysinfo_15_1_x *tl_info; 34dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void set_topology_timer(void); 35dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic DECLARE_WORK(topology_work, topology_work_fn); 3674af283102b358b0da545460d0d176f473e110f6Heiko Carstens/* topology_lock protects the core linked list */ 3774af283102b358b0da545460d0d176f473e110f6Heiko Carstensstatic DEFINE_SPINLOCK(topology_lock); 38dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 394cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic struct mask_info core_info; 40d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstenscpumask_t cpu_core_map[NR_CPUS]; 4110d3858950557cd3cc05f647ede597114c610177Heiko Carstensunsigned char cpu_core_id[NR_CPUS]; 42d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens 434cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic struct mask_info book_info; 444cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstenscpumask_t cpu_book_map[NR_CPUS]; 454cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensunsigned char cpu_book_id[NR_CPUS]; 4683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 4783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens/* smp_cpu_state_mutex must be held when accessing this array */ 4883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensint cpu_polarization[NR_CPUS]; 494cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens 504cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) 51dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 52dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens cpumask_t mask; 53dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 540f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro cpumask_clear(&mask); 550b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) { 560b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens cpumask_copy(&mask, cpumask_of(cpu)); 570b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens return mask; 580b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens } 594cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens while (info) { 600f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro if (cpumask_test_cpu(cpu, &info->mask)) { 614cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens mask = info->mask; 62dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens break; 63dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 644cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens info = info->next; 65dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 660f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro if (cpumask_empty(&mask)) 670f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro cpumask_copy(&mask, cpumask_of(cpu)); 68dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens return mask; 69dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 70dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 71f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstensstatic struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, 72f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens struct mask_info *book, 73f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens struct mask_info *core, 744baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens int one_core_per_cpu) 75dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 76dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens unsigned int cpu; 77dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 78c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens for (cpu = find_first_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS); 79c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens cpu < TOPOLOGY_CPU_BITS; 80c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1)) 81dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens { 828b646bd759086f6090fe27acf414c0b5faa737f4Martin Schwidefsky unsigned int rcpu; 838b646bd759086f6090fe27acf414c0b5faa737f4Martin Schwidefsky int lcpu; 84dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 85c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin; 868b646bd759086f6090fe27acf414c0b5faa737f4Martin Schwidefsky lcpu = smp_find_processor_id(rcpu); 878b646bd759086f6090fe27acf414c0b5faa737f4Martin Schwidefsky if (lcpu >= 0) { 880f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro cpumask_set_cpu(lcpu, &book->mask); 894cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens cpu_book_id[lcpu] = book->id; 900f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro cpumask_set_cpu(lcpu, &core->mask); 914baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens if (one_core_per_cpu) { 92f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens cpu_core_id[lcpu] = rcpu; 93f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens core = core->next; 94f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens } else { 95f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens cpu_core_id[lcpu] = core->id; 96f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens } 9783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens cpu_set_polarization(lcpu, tl_cpu->pp); 98dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 99dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 100f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens return core; 101dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 102dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 1034cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic void clear_masks(void) 104dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 1054cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens struct mask_info *info; 106dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 1074cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens info = &core_info; 1084cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens while (info) { 1090f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro cpumask_clear(&info->mask); 1104cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens info = info->next; 1114cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens } 1124cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens info = &book_info; 1134cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens while (info) { 1140f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro cpumask_clear(&info->mask); 1154cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens info = info->next; 116dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 117dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 118dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 119c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstensstatic union topology_entry *next_tle(union topology_entry *tle) 120dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 121c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens if (!tle->nl) 122c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens return (union topology_entry *)((struct topology_cpu *)tle + 1); 123c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens return (union topology_entry *)((struct topology_container *)tle + 1); 124dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 125dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 1264baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstensstatic void __tl_to_cores_generic(struct sysinfo_15_1_x *info) 127dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 1284cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens struct mask_info *core = &core_info; 12983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens struct mask_info *book = &book_info; 130c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens union topology_entry *tle, *end; 1314cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens 132c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens tle = info->tle; 133c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens end = (union topology_entry *)((unsigned long)info + info->length); 134dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens while (tle < end) { 135dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens switch (tle->nl) { 136dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens case 2: 1374cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens book = book->next; 1384cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens book->id = tle->container.id; 139dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens break; 140dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens case 1: 141dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens core = core->next; 14210d3858950557cd3cc05f647ede597114c610177Heiko Carstens core->id = tle->container.id; 143dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens break; 144dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens case 0: 1454baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens add_cpus_to_mask(&tle->cpu, book, core, 0); 146dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens break; 147dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens default: 1484cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens clear_masks(); 1494baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens return; 150dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 151dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens tle = next_tle(tle); 152dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 1534baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens} 1544baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens 1554baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstensstatic void __tl_to_cores_z10(struct sysinfo_15_1_x *info) 1564baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens{ 1574baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens struct mask_info *core = &core_info; 1584baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens struct mask_info *book = &book_info; 1594baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens union topology_entry *tle, *end; 1604baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens 1614baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens tle = info->tle; 1624baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens end = (union topology_entry *)((unsigned long)info + info->length); 1634baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens while (tle < end) { 1644baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens switch (tle->nl) { 1654baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens case 1: 1664baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens book = book->next; 1674baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens book->id = tle->container.id; 1684baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens break; 1694baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens case 0: 1704baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens core = add_cpus_to_mask(&tle->cpu, book, core, 1); 1714baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens break; 1724baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens default: 1734baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens clear_masks(); 1744baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens return; 1754baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens } 1764baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens tle = next_tle(tle); 1774baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens } 1784baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens} 1794baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens 1804baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstensstatic void tl_to_cores(struct sysinfo_15_1_x *info) 1814baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens{ 1824baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens struct cpuid cpu_id; 1834baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens 1844baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens get_cpu_id(&cpu_id); 1854baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens spin_lock_irq(&topology_lock); 1864baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens clear_masks(); 1874baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens switch (cpu_id.machine) { 1884baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens case 0x2097: 1894baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens case 0x2098: 1904baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens __tl_to_cores_z10(info); 1914baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens break; 1924baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens default: 1934baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens __tl_to_cores_generic(info); 1944baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens } 19574af283102b358b0da545460d0d176f473e110f6Heiko Carstens spin_unlock_irq(&topology_lock); 196dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 197dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 198c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensstatic void topology_update_polarization_simple(void) 199c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens{ 200c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens int cpu; 201c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens 202c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens mutex_lock(&smp_cpu_state_mutex); 2035439050f9f1aa92381ab9beccbea6ddf0c687c2bHeiko Carstens for_each_possible_cpu(cpu) 20483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens cpu_set_polarization(cpu, POLARIZATION_HRZ); 205c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens mutex_unlock(&smp_cpu_state_mutex); 206c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens} 207c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens 208c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensstatic int ptf(unsigned long fc) 209dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 210dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens int rc; 211dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 212dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens asm volatile( 213dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens " .insn rre,0xb9a20000,%1,%1\n" 214dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens " ipm %0\n" 215dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens " srl %0,28\n" 216dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens : "=d" (rc) 217c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens : "d" (fc) : "cc"); 218c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens return rc; 219c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens} 220c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens 221c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensint topology_set_cpu_management(int fc) 222c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens{ 22383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens int cpu, rc; 224c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens 2259186d7a9cfd75e51ac4db4a40e0a558371988bd2Heiko Carstens if (!MACHINE_HAS_TOPOLOGY) 226c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens return -EOPNOTSUPP; 227c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens if (fc) 228c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens rc = ptf(PTF_VERTICAL); 229c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens else 230c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens rc = ptf(PTF_HORIZONTAL); 231c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens if (rc) 232c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens return -EBUSY; 2335439050f9f1aa92381ab9beccbea6ddf0c687c2bHeiko Carstens for_each_possible_cpu(cpu) 23483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 235dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens return rc; 236dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 237dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 238d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstensstatic void update_cpu_core_map(void) 239d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens{ 2404cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens unsigned long flags; 241d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens int cpu; 242d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens 2434cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens spin_lock_irqsave(&topology_lock, flags); 2444cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens for_each_possible_cpu(cpu) { 2454cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens cpu_core_map[cpu] = cpu_group_map(&core_info, cpu); 2464cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens cpu_book_map[cpu] = cpu_group_map(&book_info, cpu); 2474cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens } 2484cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens spin_unlock_irqrestore(&topology_lock, flags); 2494cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens} 2504cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens 25196f4a70d8eb4d746b19d5b5510407c8ff0d00340Heiko Carstensvoid store_topology(struct sysinfo_15_1_x *info) 2524cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens{ 2534cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens int rc; 2544cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens 2554cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens rc = stsi(info, 15, 1, 3); 2564cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens if (rc != -ENOSYS) 2574cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens return; 2584cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens stsi(info, 15, 1, 2); 259d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens} 260d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens 261ee79d1bdb6a10499e53f80b1e8d14110215178baHeiko Carstensint arch_update_cpu_topology(void) 262dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 263c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens struct sysinfo_15_1_x *info = tl_info; 2648a25a2fd126c621f44f3aeaef80d51f00fc11639Kay Sievers struct device *dev; 265dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens int cpu; 266dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 2679186d7a9cfd75e51ac4db4a40e0a558371988bd2Heiko Carstens if (!MACHINE_HAS_TOPOLOGY) { 268d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens update_cpu_core_map(); 269c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens topology_update_polarization_simple(); 270ee79d1bdb6a10499e53f80b1e8d14110215178baHeiko Carstens return 0; 271c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens } 2724cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens store_topology(info); 273dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens tl_to_cores(info); 274d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens update_cpu_core_map(); 275dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens for_each_online_cpu(cpu) { 2768a25a2fd126c621f44f3aeaef80d51f00fc11639Kay Sievers dev = get_cpu_device(cpu); 2778a25a2fd126c621f44f3aeaef80d51f00fc11639Kay Sievers kobject_uevent(&dev->kobj, KOBJ_CHANGE); 278dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens } 279ee79d1bdb6a10499e53f80b1e8d14110215178baHeiko Carstens return 1; 280dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 281dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 282fd781fa25c9e9c6fd1599df060b05e7c4ad724e5Heiko Carstensstatic void topology_work_fn(struct work_struct *work) 283fd781fa25c9e9c6fd1599df060b05e7c4ad724e5Heiko Carstens{ 284f414f5f15376764d68a31dc568d9e814d3fcb58aHeiko Carstens rebuild_sched_domains(); 285dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 286dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 287c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensvoid topology_schedule_update(void) 288c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens{ 289c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens schedule_work(&topology_work); 290c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens} 291c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens 292dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void topology_timer_fn(unsigned long ignored) 293dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 294c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens if (ptf(PTF_CHECK)) 295c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens topology_schedule_update(); 296dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens set_topology_timer(); 297dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 298dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 299d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstensstatic struct timer_list topology_timer = 300d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens TIMER_DEFERRED_INITIALIZER(topology_timer_fn, 0, 0); 301d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens 302d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstensstatic atomic_t topology_poll = ATOMIC_INIT(0); 303d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens 304dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void set_topology_timer(void) 305dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 306d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens if (atomic_add_unless(&topology_poll, -1, 0)) 307d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens mod_timer(&topology_timer, jiffies + HZ / 10); 308d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens else 309d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens mod_timer(&topology_timer, jiffies + HZ * 60); 310d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens} 311d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens 312d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstensvoid topology_expect_change(void) 313d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens{ 314d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens if (!MACHINE_HAS_TOPOLOGY) 315d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens return; 316d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens /* This is racy, but it doesn't matter since it is just a heuristic. 317d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens * Worst case is that we poll in a higher frequency for a bit longer. 318d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens */ 319d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens if (atomic_read(&topology_poll) > 60) 320d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens return; 321d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens atomic_add(60, &topology_poll); 322d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens set_topology_timer(); 323dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 324dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 3252b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstensstatic int __init early_parse_topology(char *p) 326dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 327c9af3fa9e1e3e5154649991a14b74f3a2dee19eeHeiko Carstens if (strncmp(p, "off", 3)) 3282b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstens return 0; 329c9af3fa9e1e3e5154649991a14b74f3a2dee19eeHeiko Carstens topology_enabled = 0; 3302b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstens return 0; 331dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 3322b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstensearly_param("topology", early_parse_topology); 333dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 334caa04f69df9a5d4c10867b475006cf6f2f1e8500Sebastian Ottstatic void __init alloc_masks(struct sysinfo_15_1_x *info, 335caa04f69df9a5d4c10867b475006cf6f2f1e8500Sebastian Ott struct mask_info *mask, int offset) 3364cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens{ 3374cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens int i, nr_masks; 3384cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens 339c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens nr_masks = info->mag[TOPOLOGY_NR_MAG - offset]; 3404cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens for (i = 0; i < info->mnest - offset; i++) 341c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i]; 3424cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens nr_masks = max(nr_masks, 1); 3434cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens for (i = 0; i < nr_masks; i++) { 3444cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens mask->next = alloc_bootmem(sizeof(struct mask_info)); 3454cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens mask = mask->next; 3464cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens } 3474cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens} 3484cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens 349dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensvoid __init s390_init_cpu_topology(void) 350dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{ 351c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens struct sysinfo_15_1_x *info; 352dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens int i; 353dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens 3549186d7a9cfd75e51ac4db4a40e0a558371988bd2Heiko Carstens if (!MACHINE_HAS_TOPOLOGY) 355dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens return; 356dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens tl_info = alloc_bootmem_pages(PAGE_SIZE); 357dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens info = tl_info; 3584cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens store_topology(info); 359395d31d40cc38270dd7c024691404e2eddf0678dMartin Schwidefsky pr_info("The CPU configuration topology of the machine is:"); 360c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens for (i = 0; i < TOPOLOGY_NR_MAG; i++) 36183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens printk(KERN_CONT " %d", info->mag[i]); 36283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens printk(KERN_CONT " / %d\n", info->mnest); 363f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens alloc_masks(info, &core_info, 1); 364f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens alloc_masks(info, &book_info, 2); 365dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens} 36683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 36783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic int cpu_management; 36883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 36972f318897e50c29b91efd1ed24515a93c138a2baLinus Torvaldsstatic ssize_t dispatching_show(struct device *dev, 37072f318897e50c29b91efd1ed24515a93c138a2baLinus Torvalds struct device_attribute *attr, 37183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens char *buf) 37283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{ 37383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens ssize_t count; 37483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 37583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens mutex_lock(&smp_cpu_state_mutex); 37683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens count = sprintf(buf, "%d\n", cpu_management); 37783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens mutex_unlock(&smp_cpu_state_mutex); 37883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens return count; 37983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens} 38083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 38172f318897e50c29b91efd1ed24515a93c138a2baLinus Torvaldsstatic ssize_t dispatching_store(struct device *dev, 38272f318897e50c29b91efd1ed24515a93c138a2baLinus Torvalds struct device_attribute *attr, 38383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens const char *buf, 38483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens size_t count) 38583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{ 38683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens int val, rc; 38783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens char delim; 38883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 38983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens if (sscanf(buf, "%d %c", &val, &delim) != 1) 39083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens return -EINVAL; 39183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens if (val != 0 && val != 1) 39283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens return -EINVAL; 39383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens rc = 0; 39483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens get_online_cpus(); 39583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens mutex_lock(&smp_cpu_state_mutex); 39683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens if (cpu_management == val) 39783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens goto out; 39883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens rc = topology_set_cpu_management(val); 399d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens if (rc) 400d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens goto out; 401d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens cpu_management = val; 402d68bddb7329a4d47d950d6b0745a7e274d230ed4Heiko Carstens topology_expect_change(); 40383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensout: 40483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens mutex_unlock(&smp_cpu_state_mutex); 40583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens put_online_cpus(); 40683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens return rc ? rc : count; 40783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens} 40872f318897e50c29b91efd1ed24515a93c138a2baLinus Torvaldsstatic DEVICE_ATTR(dispatching, 0644, dispatching_show, 40983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens dispatching_store); 41083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 41172f318897e50c29b91efd1ed24515a93c138a2baLinus Torvaldsstatic ssize_t cpu_polarization_show(struct device *dev, 41272f318897e50c29b91efd1ed24515a93c138a2baLinus Torvalds struct device_attribute *attr, char *buf) 41383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{ 41483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens int cpu = dev->id; 41583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens ssize_t count; 41683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 41783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens mutex_lock(&smp_cpu_state_mutex); 41883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens switch (cpu_read_polarization(cpu)) { 41983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens case POLARIZATION_HRZ: 42083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens count = sprintf(buf, "horizontal\n"); 42183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens break; 42283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens case POLARIZATION_VL: 42383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens count = sprintf(buf, "vertical:low\n"); 42483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens break; 42583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens case POLARIZATION_VM: 42683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens count = sprintf(buf, "vertical:medium\n"); 42783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens break; 42883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens case POLARIZATION_VH: 42983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens count = sprintf(buf, "vertical:high\n"); 43083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens break; 43183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens default: 43283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens count = sprintf(buf, "unknown\n"); 43383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens break; 43483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens } 43583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens mutex_unlock(&smp_cpu_state_mutex); 43683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens return count; 43783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens} 43872f318897e50c29b91efd1ed24515a93c138a2baLinus Torvaldsstatic DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL); 43983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 44083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic struct attribute *topology_cpu_attrs[] = { 44172f318897e50c29b91efd1ed24515a93c138a2baLinus Torvalds &dev_attr_polarization.attr, 44283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens NULL, 44383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}; 44483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 44583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic struct attribute_group topology_cpu_attr_group = { 44683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens .attrs = topology_cpu_attrs, 44783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}; 44883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 44983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensint topology_cpu_init(struct cpu *cpu) 45083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{ 45172f318897e50c29b91efd1ed24515a93c138a2baLinus Torvalds return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group); 45283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens} 45383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens 45483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic int __init topology_init(void) 45583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{ 45683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens if (!MACHINE_HAS_TOPOLOGY) { 45783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens topology_update_polarization_simple(); 45883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens goto out; 45983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens } 46083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens set_topology_timer(); 46183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensout: 46283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens update_cpu_core_map(); 46372f318897e50c29b91efd1ed24515a93c138a2baLinus Torvalds return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); 46483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens} 46583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensdevice_initcall(topology_init); 466