topology.c revision 4baeb964d96d38dff461af5b9d578f0a9ba67617
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 struct timer_list topology_timer;
35dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void set_topology_timer(void);
36dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic DECLARE_WORK(topology_work, topology_work_fn);
3774af283102b358b0da545460d0d176f473e110f6Heiko Carstens/* topology_lock protects the core linked list */
3874af283102b358b0da545460d0d176f473e110f6Heiko Carstensstatic DEFINE_SPINLOCK(topology_lock);
39dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
404cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic struct mask_info core_info;
41d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstenscpumask_t cpu_core_map[NR_CPUS];
4210d3858950557cd3cc05f647ede597114c610177Heiko Carstensunsigned char cpu_core_id[NR_CPUS];
43d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens
444cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic struct mask_info book_info;
454cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstenscpumask_t cpu_book_map[NR_CPUS];
464cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensunsigned char cpu_book_id[NR_CPUS];
4783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
4883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens/* smp_cpu_state_mutex must be held when accessing this array */
4983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensint cpu_polarization[NR_CPUS];
504cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens
514cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
52dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
53dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	cpumask_t mask;
54dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
550f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro	cpumask_clear(&mask);
560b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens	if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) {
570b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens		cpumask_copy(&mask, cpumask_of(cpu));
580b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens		return mask;
590b52783d4feb14d6ff990a63512a66d6131d41f9Heiko Carstens	}
604cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	while (info) {
610f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro		if (cpumask_test_cpu(cpu, &info->mask)) {
624cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens			mask = info->mask;
63dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens			break;
64dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		}
654cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		info = info->next;
66dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	}
670f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro	if (cpumask_empty(&mask))
680f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro		cpumask_copy(&mask, cpumask_of(cpu));
69dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	return mask;
70dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
71dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
72f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstensstatic struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
73f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens					  struct mask_info *book,
74f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens					  struct mask_info *core,
754baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens					  int one_core_per_cpu)
76dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
77dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	unsigned int cpu;
78dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
79c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	for (cpu = find_first_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS);
80c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	     cpu < TOPOLOGY_CPU_BITS;
81c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	     cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1))
82dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	{
83dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		unsigned int rcpu, lcpu;
84dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
85c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens		rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin;
86dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		for_each_present_cpu(lcpu) {
874cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens			if (cpu_logical_map(lcpu) != rcpu)
884cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens				continue;
890f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro			cpumask_set_cpu(lcpu, &book->mask);
904cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens			cpu_book_id[lcpu] = book->id;
910f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro			cpumask_set_cpu(lcpu, &core->mask);
924baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			if (one_core_per_cpu) {
93f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens				cpu_core_id[lcpu] = rcpu;
94f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens				core = core->next;
95f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens			} else {
96f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens				cpu_core_id[lcpu] = core->id;
97f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens			}
9883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens			cpu_set_polarization(lcpu, tl_cpu->pp);
99dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		}
100dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	}
101f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens	return core;
102dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
103dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
1044cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstensstatic void clear_masks(void)
105dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
1064cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	struct mask_info *info;
107dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
1084cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	info = &core_info;
1094cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	while (info) {
1100f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro		cpumask_clear(&info->mask);
1114cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		info = info->next;
1124cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	}
1134cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	info = &book_info;
1144cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	while (info) {
1150f1959f50646612b247d624bdbf8b0c8816f2a93KOSAKI Motohiro		cpumask_clear(&info->mask);
1164cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		info = info->next;
117dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	}
118dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
119dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
120c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstensstatic union topology_entry *next_tle(union topology_entry *tle)
121dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
122c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	if (!tle->nl)
123c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens		return (union topology_entry *)((struct topology_cpu *)tle + 1);
124c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	return (union topology_entry *)((struct topology_container *)tle + 1);
125dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
126dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
1274baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstensstatic void __tl_to_cores_generic(struct sysinfo_15_1_x *info)
128dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
1294cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	struct mask_info *core = &core_info;
13083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	struct mask_info *book = &book_info;
131c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	union topology_entry *tle, *end;
1324cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens
133c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	tle = info->tle;
134c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	end = (union topology_entry *)((unsigned long)info + info->length);
135dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	while (tle < end) {
136dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		switch (tle->nl) {
137dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		case 2:
1384cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens			book = book->next;
1394cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens			book->id = tle->container.id;
140dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens			break;
141dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		case 1:
142dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens			core = core->next;
14310d3858950557cd3cc05f647ede597114c610177Heiko Carstens			core->id = tle->container.id;
144dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens			break;
145dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		case 0:
1464baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			add_cpus_to_mask(&tle->cpu, book, core, 0);
147dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens			break;
148dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		default:
1494cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens			clear_masks();
1504baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			return;
151dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		}
152dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		tle = next_tle(tle);
153dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	}
1544baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens}
1554baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens
1564baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstensstatic void __tl_to_cores_z10(struct sysinfo_15_1_x *info)
1574baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens{
1584baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	struct mask_info *core = &core_info;
1594baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	struct mask_info *book = &book_info;
1604baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	union topology_entry *tle, *end;
1614baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens
1624baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	tle = info->tle;
1634baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	end = (union topology_entry *)((unsigned long)info + info->length);
1644baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	while (tle < end) {
1654baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		switch (tle->nl) {
1664baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		case 1:
1674baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			book = book->next;
1684baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			book->id = tle->container.id;
1694baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			break;
1704baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		case 0:
1714baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			core = add_cpus_to_mask(&tle->cpu, book, core, 1);
1724baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			break;
1734baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		default:
1744baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			clear_masks();
1754baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens			return;
1764baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		}
1774baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		tle = next_tle(tle);
1784baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	}
1794baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens}
1804baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens
1814baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstensstatic void tl_to_cores(struct sysinfo_15_1_x *info)
1824baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens{
1834baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	struct cpuid cpu_id;
1844baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens
1854baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	get_cpu_id(&cpu_id);
1864baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	spin_lock_irq(&topology_lock);
1874baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	clear_masks();
1884baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	switch (cpu_id.machine) {
1894baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	case 0x2097:
1904baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	case 0x2098:
1914baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		__tl_to_cores_z10(info);
1924baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		break;
1934baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	default:
1944baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens		__tl_to_cores_generic(info);
1954baeb964d96d38dff461af5b9d578f0a9ba67617Heiko Carstens	}
19674af283102b358b0da545460d0d176f473e110f6Heiko Carstens	spin_unlock_irq(&topology_lock);
197dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
198dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
199c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensstatic void topology_update_polarization_simple(void)
200c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens{
201c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	int cpu;
202c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens
203c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	mutex_lock(&smp_cpu_state_mutex);
2045439050f9f1aa92381ab9beccbea6ddf0c687c2bHeiko Carstens	for_each_possible_cpu(cpu)
20583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		cpu_set_polarization(cpu, POLARIZATION_HRZ);
206c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	mutex_unlock(&smp_cpu_state_mutex);
207c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens}
208c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens
209c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensstatic int ptf(unsigned long fc)
210dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
211dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	int rc;
212dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
213dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	asm volatile(
214dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		"	.insn	rre,0xb9a20000,%1,%1\n"
215dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		"	ipm	%0\n"
216dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		"	srl	%0,28\n"
217dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		: "=d" (rc)
218c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		: "d" (fc)  : "cc");
219c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	return rc;
220c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens}
221c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens
222c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensint topology_set_cpu_management(int fc)
223c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens{
22483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	int cpu, rc;
225c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens
2269186d7a9cfd75e51ac4db4a40e0a558371988bd2Heiko Carstens	if (!MACHINE_HAS_TOPOLOGY)
227c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		return -EOPNOTSUPP;
228c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	if (fc)
229c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		rc = ptf(PTF_VERTICAL);
230c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	else
231c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		rc = ptf(PTF_HORIZONTAL);
232c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	if (rc)
233c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		return -EBUSY;
2345439050f9f1aa92381ab9beccbea6ddf0c687c2bHeiko Carstens	for_each_possible_cpu(cpu)
23583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
236dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	return rc;
237dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
238dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
239d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstensstatic void update_cpu_core_map(void)
240d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens{
2414cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	unsigned long flags;
242d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens	int cpu;
243d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens
2444cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	spin_lock_irqsave(&topology_lock, flags);
2454cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	for_each_possible_cpu(cpu) {
2464cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		cpu_core_map[cpu] = cpu_group_map(&core_info, cpu);
2474cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		cpu_book_map[cpu] = cpu_group_map(&book_info, cpu);
2484cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	}
2494cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	spin_unlock_irqrestore(&topology_lock, flags);
2504cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens}
2514cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens
25296f4a70d8eb4d746b19d5b5510407c8ff0d00340Heiko Carstensvoid store_topology(struct sysinfo_15_1_x *info)
2534cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens{
2544cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	int rc;
2554cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens
2564cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	rc = stsi(info, 15, 1, 3);
2574cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	if (rc != -ENOSYS)
2584cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		return;
2594cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	stsi(info, 15, 1, 2);
260d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens}
261d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens
262ee79d1bdb6a10499e53f80b1e8d14110215178baHeiko Carstensint arch_update_cpu_topology(void)
263dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
264c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	struct sysinfo_15_1_x *info = tl_info;
265dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	struct sys_device *sysdev;
266dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	int cpu;
267dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
2689186d7a9cfd75e51ac4db4a40e0a558371988bd2Heiko Carstens	if (!MACHINE_HAS_TOPOLOGY) {
269d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens		update_cpu_core_map();
270c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		topology_update_polarization_simple();
271ee79d1bdb6a10499e53f80b1e8d14110215178baHeiko Carstens		return 0;
272c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	}
2734cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	store_topology(info);
274dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	tl_to_cores(info);
275d00aa4e7d0129983fc4389c85e15a066eb4e69a9Heiko Carstens	update_cpu_core_map();
276dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	for_each_online_cpu(cpu) {
277dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		sysdev = get_cpu_sysdev(cpu);
278dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
279dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	}
280ee79d1bdb6a10499e53f80b1e8d14110215178baHeiko Carstens	return 1;
281dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
282dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
283fd781fa25c9e9c6fd1599df060b05e7c4ad724e5Heiko Carstensstatic void topology_work_fn(struct work_struct *work)
284fd781fa25c9e9c6fd1599df060b05e7c4ad724e5Heiko Carstens{
285f414f5f15376764d68a31dc568d9e814d3fcb58aHeiko Carstens	rebuild_sched_domains();
286dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
287dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
288c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstensvoid topology_schedule_update(void)
289c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens{
290c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	schedule_work(&topology_work);
291c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens}
292c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens
293dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void topology_timer_fn(unsigned long ignored)
294dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
295c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens	if (ptf(PTF_CHECK))
296c10fde0d9e2112c25052a8742e893ec5965c0007Heiko Carstens		topology_schedule_update();
297dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	set_topology_timer();
298dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
299dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
300dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensstatic void set_topology_timer(void)
301dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
302dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	topology_timer.function = topology_timer_fn;
303dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	topology_timer.data = 0;
304dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	topology_timer.expires = jiffies + 60 * HZ;
305dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	add_timer(&topology_timer);
306dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
307dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
3082b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstensstatic int __init early_parse_topology(char *p)
309dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
310c9af3fa9e1e3e5154649991a14b74f3a2dee19eeHeiko Carstens	if (strncmp(p, "off", 3))
3112b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstens		return 0;
312c9af3fa9e1e3e5154649991a14b74f3a2dee19eeHeiko Carstens	topology_enabled = 0;
3132b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstens	return 0;
314dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
3152b1a61f0a8c714c96277bf16a823a84bafa1397dHeiko Carstensearly_param("topology", early_parse_topology);
316dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
317caa04f69df9a5d4c10867b475006cf6f2f1e8500Sebastian Ottstatic void __init alloc_masks(struct sysinfo_15_1_x *info,
318caa04f69df9a5d4c10867b475006cf6f2f1e8500Sebastian Ott			       struct mask_info *mask, int offset)
3194cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens{
3204cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	int i, nr_masks;
3214cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens
322c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	nr_masks = info->mag[TOPOLOGY_NR_MAG - offset];
3234cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	for (i = 0; i < info->mnest - offset; i++)
324c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens		nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i];
3254cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	nr_masks = max(nr_masks, 1);
3264cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	for (i = 0; i < nr_masks; i++) {
3274cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		mask->next = alloc_bootmem(sizeof(struct mask_info));
3284cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens		mask = mask->next;
3294cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	}
3304cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens}
3314cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens
332dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstensvoid __init s390_init_cpu_topology(void)
333dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens{
334c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	struct sysinfo_15_1_x *info;
335dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	int i;
336dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens
3379186d7a9cfd75e51ac4db4a40e0a558371988bd2Heiko Carstens	if (!MACHINE_HAS_TOPOLOGY)
338dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens		return;
339dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	tl_info = alloc_bootmem_pages(PAGE_SIZE);
340dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens	info = tl_info;
3414cb14bc8c54f8489251d5cba8328cb410ead0ceaHeiko Carstens	store_topology(info);
342395d31d40cc38270dd7c024691404e2eddf0678dMartin Schwidefsky	pr_info("The CPU configuration topology of the machine is:");
343c30f91b6a264aef9ffb05e13931514c2a988c495Heiko Carstens	for (i = 0; i < TOPOLOGY_NR_MAG; i++)
34483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		printk(KERN_CONT " %d", info->mag[i]);
34583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	printk(KERN_CONT " / %d\n", info->mnest);
346f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens	alloc_masks(info, &core_info, 1);
347f6bf1a8acd2cb3a92a7b7c9ab03e56a32ac5ece5Heiko Carstens	alloc_masks(info, &book_info, 2);
348dbd70fb499952d0ba282f0159dafacfc31d50313Heiko Carstens}
34983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
35083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic int cpu_management;
35183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
35283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic ssize_t dispatching_show(struct sysdev_class *class,
35383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens				struct sysdev_class_attribute *attr,
35483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens				char *buf)
35583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{
35683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	ssize_t count;
35783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
35883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	mutex_lock(&smp_cpu_state_mutex);
35983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	count = sprintf(buf, "%d\n", cpu_management);
36083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	mutex_unlock(&smp_cpu_state_mutex);
36183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	return count;
36283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}
36383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
36483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic ssize_t dispatching_store(struct sysdev_class *dev,
36583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens				 struct sysdev_class_attribute *attr,
36683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens				 const char *buf,
36783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens				 size_t count)
36883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{
36983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	int val, rc;
37083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	char delim;
37183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
37283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	if (sscanf(buf, "%d %c", &val, &delim) != 1)
37383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		return -EINVAL;
37483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	if (val != 0 && val != 1)
37583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		return -EINVAL;
37683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	rc = 0;
37783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	get_online_cpus();
37883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	mutex_lock(&smp_cpu_state_mutex);
37983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	if (cpu_management == val)
38083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		goto out;
38183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	rc = topology_set_cpu_management(val);
38283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	if (!rc)
38383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		cpu_management = val;
38483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensout:
38583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	mutex_unlock(&smp_cpu_state_mutex);
38683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	put_online_cpus();
38783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	return rc ? rc : count;
38883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}
38983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show,
39083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens			 dispatching_store);
39183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
39283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic ssize_t cpu_polarization_show(struct sys_device *dev,
39383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens				     struct sysdev_attribute *attr, char *buf)
39483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{
39583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	int cpu = dev->id;
39683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	ssize_t count;
39783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
39883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	mutex_lock(&smp_cpu_state_mutex);
39983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	switch (cpu_read_polarization(cpu)) {
40083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	case POLARIZATION_HRZ:
40183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		count = sprintf(buf, "horizontal\n");
40283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		break;
40383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	case POLARIZATION_VL:
40483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		count = sprintf(buf, "vertical:low\n");
40583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		break;
40683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	case POLARIZATION_VM:
40783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		count = sprintf(buf, "vertical:medium\n");
40883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		break;
40983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	case POLARIZATION_VH:
41083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		count = sprintf(buf, "vertical:high\n");
41183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		break;
41283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	default:
41383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		count = sprintf(buf, "unknown\n");
41483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		break;
41583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	}
41683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	mutex_unlock(&smp_cpu_state_mutex);
41783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	return count;
41883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}
41983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL);
42083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
42183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic struct attribute *topology_cpu_attrs[] = {
42283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	&attr_polarization.attr,
42383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	NULL,
42483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens};
42583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
42683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic struct attribute_group topology_cpu_attr_group = {
42783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	.attrs = topology_cpu_attrs,
42883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens};
42983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
43083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensint topology_cpu_init(struct cpu *cpu)
43183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{
43283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	return sysfs_create_group(&cpu->sysdev.kobj, &topology_cpu_attr_group);
43383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}
43483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens
43583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensstatic int __init topology_init(void)
43683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens{
43783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	if (!MACHINE_HAS_TOPOLOGY) {
43883a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		topology_update_polarization_simple();
43983a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens		goto out;
44083a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	}
44183a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	init_timer_deferrable(&topology_timer);
44283a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	set_topology_timer();
44383a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensout:
44483a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	update_cpu_core_map();
44583a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens	return sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching);
44683a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstens}
44783a24e32908476c33ea9abc132c73020e2cd3620Heiko Carstensdevice_initcall(topology_init);
448