aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/topology.c')
-rw-r--r--drivers/base/topology.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 28dccb730af9..067a9e8bc377 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -94,54 +94,61 @@ static struct attribute_group topology_attr_group = {
94 .name = "topology" 94 .name = "topology"
95}; 95};
96 96
97static cpumask_t topology_dev_map = CPU_MASK_NONE;
98
97/* Add/Remove cpu_topology interface for CPU device */ 99/* Add/Remove cpu_topology interface for CPU device */
98static int __cpuinit topology_add_dev(struct sys_device * sys_dev) 100static int __cpuinit topology_add_dev(unsigned int cpu)
99{ 101{
100 return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); 102 int rc;
103 struct sys_device *sys_dev = get_cpu_sysdev(cpu);
104
105 rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
106 if (!rc)
107 cpu_set(cpu, topology_dev_map);
108 return rc;
101} 109}
102 110
103static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) 111static void __cpuinit topology_remove_dev(unsigned int cpu)
104{ 112{
113 struct sys_device *sys_dev = get_cpu_sysdev(cpu);
114
115 if (!cpu_isset(cpu, topology_dev_map))
116 return;
117 cpu_clear(cpu, topology_dev_map);
105 sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); 118 sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
106 return 0;
107} 119}
108 120
109static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, 121static int __cpuinit topology_cpu_callback(struct notifier_block *nfb,
110 unsigned long action, void *hcpu) 122 unsigned long action, void *hcpu)
111{ 123{
112 unsigned int cpu = (unsigned long)hcpu; 124 unsigned int cpu = (unsigned long)hcpu;
113 struct sys_device *sys_dev; 125 int rc = 0;
114 126
115 sys_dev = get_cpu_sysdev(cpu);
116 switch (action) { 127 switch (action) {
117 case CPU_ONLINE: 128 case CPU_UP_PREPARE:
118 topology_add_dev(sys_dev); 129 rc = topology_add_dev(cpu);
119 break; 130 break;
131 case CPU_UP_CANCELED:
120 case CPU_DEAD: 132 case CPU_DEAD:
121 topology_remove_dev(sys_dev); 133 topology_remove_dev(cpu);
122 break; 134 break;
123 } 135 }
124 return NOTIFY_OK; 136 return rc ? NOTIFY_BAD : NOTIFY_OK;
125} 137}
126 138
127static struct notifier_block __cpuinitdata topology_cpu_notifier =
128{
129 .notifier_call = topology_cpu_callback,
130};
131
132static int __cpuinit topology_sysfs_init(void) 139static int __cpuinit topology_sysfs_init(void)
133{ 140{
134 int i; 141 int cpu;
142 int rc;
135 143
136 for_each_online_cpu(i) { 144 for_each_online_cpu(cpu) {
137 topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE, 145 rc = topology_add_dev(cpu);
138 (void *)(long)i); 146 if (rc)
147 return rc;
139 } 148 }
140 149 hotcpu_notifier(topology_cpu_callback, 0);
141 register_hotcpu_notifier(&topology_cpu_notifier);
142 150
143 return 0; 151 return 0;
144} 152}
145 153
146device_initcall(topology_sysfs_init); 154device_initcall(topology_sysfs_init);
147