aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/cpu.c')
-rw-r--r--drivers/base/cpu.c105
1 files changed, 47 insertions, 58 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 958bd1540c30..7036e8e96ab8 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -13,8 +13,11 @@
13 13
14#include "base.h" 14#include "base.h"
15 15
16static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
17
16struct sysdev_class cpu_sysdev_class = { 18struct sysdev_class cpu_sysdev_class = {
17 .name = "cpu", 19 .name = "cpu",
20 .attrs = cpu_sysdev_class_attrs,
18}; 21};
19EXPORT_SYMBOL(cpu_sysdev_class); 22EXPORT_SYMBOL(cpu_sysdev_class);
20 23
@@ -76,34 +79,24 @@ void unregister_cpu(struct cpu *cpu)
76} 79}
77 80
78#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE 81#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
79static ssize_t cpu_probe_store(struct class *class, const char *buf, 82static ssize_t cpu_probe_store(struct sys_device *dev,
83 struct sysdev_attribute *attr,
84 const char *buf,
80 size_t count) 85 size_t count)
81{ 86{
82 return arch_cpu_probe(buf, count); 87 return arch_cpu_probe(buf, count);
83} 88}
84 89
85static ssize_t cpu_release_store(struct class *class, const char *buf, 90static ssize_t cpu_release_store(struct sys_device *dev,
91 struct sysdev_attribute *attr,
92 const char *buf,
86 size_t count) 93 size_t count)
87{ 94{
88 return arch_cpu_release(buf, count); 95 return arch_cpu_release(buf, count);
89} 96}
90 97
91static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); 98static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
92static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store); 99static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store);
93
94int __init cpu_probe_release_init(void)
95{
96 int rc;
97
98 rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
99 &class_attr_probe.attr);
100 if (!rc)
101 rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
102 &class_attr_release.attr);
103
104 return rc;
105}
106device_initcall(cpu_probe_release_init);
107#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ 100#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
108 101
109#else /* ... !CONFIG_HOTPLUG_CPU */ 102#else /* ... !CONFIG_HOTPLUG_CPU */
@@ -141,31 +134,39 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
141/* 134/*
142 * Print cpu online, possible, present, and system maps 135 * Print cpu online, possible, present, and system maps
143 */ 136 */
144static ssize_t print_cpus_map(char *buf, const struct cpumask *map) 137
138struct cpu_attr {
139 struct sysdev_class_attribute attr;
140 const struct cpumask *const * const map;
141};
142
143static ssize_t show_cpus_attr(struct sysdev_class *class,
144 struct sysdev_class_attribute *attr,
145 char *buf)
145{ 146{
146 int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map); 147 struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
148 int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
147 149
148 buf[n++] = '\n'; 150 buf[n++] = '\n';
149 buf[n] = '\0'; 151 buf[n] = '\0';
150 return n; 152 return n;
151} 153}
152 154
153#define print_cpus_func(type) \ 155#define _CPU_ATTR(name, map) \
154static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ 156 { _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
155{ \
156 return print_cpus_map(buf, cpu_##type##_mask); \
157} \
158static struct sysdev_class_attribute attr_##type##_map = \
159 _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
160 157
161print_cpus_func(online); 158/* Keep in sync with cpu_sysdev_class_attrs */
162print_cpus_func(possible); 159static struct cpu_attr cpu_attrs[] = {
163print_cpus_func(present); 160 _CPU_ATTR(online, &cpu_online_mask),
161 _CPU_ATTR(possible, &cpu_possible_mask),
162 _CPU_ATTR(present, &cpu_present_mask),
163};
164 164
165/* 165/*
166 * Print values for NR_CPUS and offlined cpus 166 * Print values for NR_CPUS and offlined cpus
167 */ 167 */
168static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf) 168static ssize_t print_cpus_kernel_max(struct sysdev_class *class,
169 struct sysdev_class_attribute *attr, char *buf)
169{ 170{
170 int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); 171 int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
171 return n; 172 return n;
@@ -175,7 +176,8 @@ static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
175/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ 176/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
176unsigned int total_cpus; 177unsigned int total_cpus;
177 178
178static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) 179static ssize_t print_cpus_offline(struct sysdev_class *class,
180 struct sysdev_class_attribute *attr, char *buf)
179{ 181{
180 int n = 0, len = PAGE_SIZE-2; 182 int n = 0, len = PAGE_SIZE-2;
181 cpumask_var_t offline; 183 cpumask_var_t offline;
@@ -204,29 +206,6 @@ static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
204} 206}
205static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL); 207static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
206 208
207static struct sysdev_class_attribute *cpu_state_attr[] = {
208 &attr_online_map,
209 &attr_possible_map,
210 &attr_present_map,
211 &attr_kernel_max,
212 &attr_offline,
213};
214
215static int cpu_states_init(void)
216{
217 int i;
218 int err = 0;
219
220 for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) {
221 int ret;
222 ret = sysdev_class_create_file(&cpu_sysdev_class,
223 cpu_state_attr[i]);
224 if (!err)
225 err = ret;
226 }
227 return err;
228}
229
230/* 209/*
231 * register_cpu - Setup a sysfs device for a CPU. 210 * register_cpu - Setup a sysfs device for a CPU.
232 * @cpu - cpu->hotpluggable field set to 1 will generate a control file in 211 * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -272,9 +251,6 @@ int __init cpu_dev_init(void)
272 int err; 251 int err;
273 252
274 err = sysdev_class_register(&cpu_sysdev_class); 253 err = sysdev_class_register(&cpu_sysdev_class);
275 if (!err)
276 err = cpu_states_init();
277
278#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) 254#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
279 if (!err) 255 if (!err)
280 err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); 256 err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
@@ -282,3 +258,16 @@ int __init cpu_dev_init(void)
282 258
283 return err; 259 return err;
284} 260}
261
262static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
263#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
264 &attr_probe,
265 &attr_release,
266#endif
267 &cpu_attrs[0].attr,
268 &cpu_attrs[1].attr,
269 &cpu_attrs[2].attr,
270 &attr_kernel_max,
271 &attr_offline,
272 NULL
273};