diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Kconfig | 3 | ||||
-rw-r--r-- | drivers/base/base.h | 27 | ||||
-rw-r--r-- | drivers/base/class.c | 153 | ||||
-rw-r--r-- | drivers/base/core.c | 196 | ||||
-rw-r--r-- | drivers/base/cpu.c | 10 | ||||
-rw-r--r-- | drivers/base/memory.c | 12 | ||||
-rw-r--r-- | drivers/base/node.c | 15 | ||||
-rw-r--r-- | drivers/base/power/trace.c | 2 | ||||
-rw-r--r-- | drivers/base/sys.c | 64 | ||||
-rw-r--r-- | drivers/base/topology.c | 17 |
10 files changed, 338 insertions, 161 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index d47482fa1d21..6318f6b57360 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -27,8 +27,9 @@ config PREVENT_FIRMWARE_BUILD | |||
27 | If unsure say Y here. | 27 | If unsure say Y here. |
28 | 28 | ||
29 | config FW_LOADER | 29 | config FW_LOADER |
30 | tristate "Userspace firmware loading support" | 30 | tristate "Userspace firmware loading support" if EMBEDDED |
31 | depends on HOTPLUG | 31 | depends on HOTPLUG |
32 | default y | ||
32 | ---help--- | 33 | ---help--- |
33 | This option is provided for the case where no in-kernel-tree modules | 34 | This option is provided for the case where no in-kernel-tree modules |
34 | require userspace firmware loading support, but a module built outside | 35 | require userspace firmware loading support, but a module built outside |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 2c9ae43e2219..31dc0cd84afa 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -36,6 +36,33 @@ struct driver_private { | |||
36 | }; | 36 | }; |
37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) | 37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) |
38 | 38 | ||
39 | |||
40 | /** | ||
41 | * struct class_private - structure to hold the private to the driver core portions of the class structure. | ||
42 | * | ||
43 | * @class_subsys - the struct kset that defines this class. This is the main kobject | ||
44 | * @class_devices - list of devices associated with this class | ||
45 | * @class_interfaces - list of class_interfaces associated with this class | ||
46 | * @class_dirs - "glue" directory for virtual devices associated with this class | ||
47 | * @class_mutex - mutex to protect the children, devices, and interfaces lists. | ||
48 | * @class - pointer back to the struct class that this structure is associated | ||
49 | * with. | ||
50 | * | ||
51 | * This structure is the one that is the actual kobject allowing struct | ||
52 | * class to be statically allocated safely. Nothing outside of the driver | ||
53 | * core should ever touch these fields. | ||
54 | */ | ||
55 | struct class_private { | ||
56 | struct kset class_subsys; | ||
57 | struct list_head class_devices; | ||
58 | struct list_head class_interfaces; | ||
59 | struct kset class_dirs; | ||
60 | struct mutex class_mutex; | ||
61 | struct class *class; | ||
62 | }; | ||
63 | #define to_class(obj) \ | ||
64 | container_of(obj, struct class_private, class_subsys.kobj) | ||
65 | |||
39 | /* initialisation functions */ | 66 | /* initialisation functions */ |
40 | extern int devices_init(void); | 67 | extern int devices_init(void); |
41 | extern int buses_init(void); | 68 | extern int buses_init(void); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index e085af0ff94f..839d27cecb36 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -18,20 +18,20 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/genhd.h> | 20 | #include <linux/genhd.h> |
21 | #include <linux/mutex.h> | ||
21 | #include "base.h" | 22 | #include "base.h" |
22 | 23 | ||
23 | #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) | 24 | #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) |
24 | #define to_class(obj) container_of(obj, struct class, subsys.kobj) | ||
25 | 25 | ||
26 | static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, | 26 | static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, |
27 | char *buf) | 27 | char *buf) |
28 | { | 28 | { |
29 | struct class_attribute *class_attr = to_class_attr(attr); | 29 | struct class_attribute *class_attr = to_class_attr(attr); |
30 | struct class *dc = to_class(kobj); | 30 | struct class_private *cp = to_class(kobj); |
31 | ssize_t ret = -EIO; | 31 | ssize_t ret = -EIO; |
32 | 32 | ||
33 | if (class_attr->show) | 33 | if (class_attr->show) |
34 | ret = class_attr->show(dc, buf); | 34 | ret = class_attr->show(cp->class, buf); |
35 | return ret; | 35 | return ret; |
36 | } | 36 | } |
37 | 37 | ||
@@ -39,17 +39,18 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, | |||
39 | const char *buf, size_t count) | 39 | const char *buf, size_t count) |
40 | { | 40 | { |
41 | struct class_attribute *class_attr = to_class_attr(attr); | 41 | struct class_attribute *class_attr = to_class_attr(attr); |
42 | struct class *dc = to_class(kobj); | 42 | struct class_private *cp = to_class(kobj); |
43 | ssize_t ret = -EIO; | 43 | ssize_t ret = -EIO; |
44 | 44 | ||
45 | if (class_attr->store) | 45 | if (class_attr->store) |
46 | ret = class_attr->store(dc, buf, count); | 46 | ret = class_attr->store(cp->class, buf, count); |
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | static void class_release(struct kobject *kobj) | 50 | static void class_release(struct kobject *kobj) |
51 | { | 51 | { |
52 | struct class *class = to_class(kobj); | 52 | struct class_private *cp = to_class(kobj); |
53 | struct class *class = cp->class; | ||
53 | 54 | ||
54 | pr_debug("class '%s': release.\n", class->name); | 55 | pr_debug("class '%s': release.\n", class->name); |
55 | 56 | ||
@@ -70,7 +71,7 @@ static struct kobj_type class_ktype = { | |||
70 | .release = class_release, | 71 | .release = class_release, |
71 | }; | 72 | }; |
72 | 73 | ||
73 | /* Hotplug events for classes go to the class_obj subsys */ | 74 | /* Hotplug events for classes go to the class class_subsys */ |
74 | static struct kset *class_kset; | 75 | static struct kset *class_kset; |
75 | 76 | ||
76 | 77 | ||
@@ -78,7 +79,8 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) | |||
78 | { | 79 | { |
79 | int error; | 80 | int error; |
80 | if (cls) | 81 | if (cls) |
81 | error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); | 82 | error = sysfs_create_file(&cls->p->class_subsys.kobj, |
83 | &attr->attr); | ||
82 | else | 84 | else |
83 | error = -EINVAL; | 85 | error = -EINVAL; |
84 | return error; | 86 | return error; |
@@ -87,21 +89,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) | |||
87 | void class_remove_file(struct class *cls, const struct class_attribute *attr) | 89 | void class_remove_file(struct class *cls, const struct class_attribute *attr) |
88 | { | 90 | { |
89 | if (cls) | 91 | if (cls) |
90 | sysfs_remove_file(&cls->subsys.kobj, &attr->attr); | 92 | sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr); |
91 | } | 93 | } |
92 | 94 | ||
93 | static struct class *class_get(struct class *cls) | 95 | static struct class *class_get(struct class *cls) |
94 | { | 96 | { |
95 | if (cls) | 97 | if (cls) |
96 | return container_of(kset_get(&cls->subsys), | 98 | kset_get(&cls->p->class_subsys); |
97 | struct class, subsys); | 99 | return cls; |
98 | return NULL; | ||
99 | } | 100 | } |
100 | 101 | ||
101 | static void class_put(struct class *cls) | 102 | static void class_put(struct class *cls) |
102 | { | 103 | { |
103 | if (cls) | 104 | if (cls) |
104 | kset_put(&cls->subsys); | 105 | kset_put(&cls->p->class_subsys); |
105 | } | 106 | } |
106 | 107 | ||
107 | static int add_class_attrs(struct class *cls) | 108 | static int add_class_attrs(struct class *cls) |
@@ -134,42 +135,57 @@ static void remove_class_attrs(struct class *cls) | |||
134 | } | 135 | } |
135 | } | 136 | } |
136 | 137 | ||
137 | int class_register(struct class *cls) | 138 | int __class_register(struct class *cls, struct lock_class_key *key) |
138 | { | 139 | { |
140 | struct class_private *cp; | ||
139 | int error; | 141 | int error; |
140 | 142 | ||
141 | pr_debug("device class '%s': registering\n", cls->name); | 143 | pr_debug("device class '%s': registering\n", cls->name); |
142 | 144 | ||
143 | INIT_LIST_HEAD(&cls->devices); | 145 | cp = kzalloc(sizeof(*cp), GFP_KERNEL); |
144 | INIT_LIST_HEAD(&cls->interfaces); | 146 | if (!cp) |
145 | kset_init(&cls->class_dirs); | 147 | return -ENOMEM; |
146 | init_MUTEX(&cls->sem); | 148 | INIT_LIST_HEAD(&cp->class_devices); |
147 | error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name); | 149 | INIT_LIST_HEAD(&cp->class_interfaces); |
148 | if (error) | 150 | kset_init(&cp->class_dirs); |
151 | __mutex_init(&cp->class_mutex, "struct class mutex", key); | ||
152 | error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); | ||
153 | if (error) { | ||
154 | kfree(cp); | ||
149 | return error; | 155 | return error; |
156 | } | ||
157 | |||
158 | /* set the default /sys/dev directory for devices of this class */ | ||
159 | if (!cls->dev_kobj) | ||
160 | cls->dev_kobj = sysfs_dev_char_kobj; | ||
150 | 161 | ||
151 | #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) | 162 | #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) |
152 | /* let the block class directory show up in the root of sysfs */ | 163 | /* let the block class directory show up in the root of sysfs */ |
153 | if (cls != &block_class) | 164 | if (cls != &block_class) |
154 | cls->subsys.kobj.kset = class_kset; | 165 | cp->class_subsys.kobj.kset = class_kset; |
155 | #else | 166 | #else |
156 | cls->subsys.kobj.kset = class_kset; | 167 | cp->class_subsys.kobj.kset = class_kset; |
157 | #endif | 168 | #endif |
158 | cls->subsys.kobj.ktype = &class_ktype; | 169 | cp->class_subsys.kobj.ktype = &class_ktype; |
170 | cp->class = cls; | ||
171 | cls->p = cp; | ||
159 | 172 | ||
160 | error = kset_register(&cls->subsys); | 173 | error = kset_register(&cp->class_subsys); |
161 | if (!error) { | 174 | if (error) { |
162 | error = add_class_attrs(class_get(cls)); | 175 | kfree(cp); |
163 | class_put(cls); | 176 | return error; |
164 | } | 177 | } |
178 | error = add_class_attrs(class_get(cls)); | ||
179 | class_put(cls); | ||
165 | return error; | 180 | return error; |
166 | } | 181 | } |
182 | EXPORT_SYMBOL_GPL(__class_register); | ||
167 | 183 | ||
168 | void class_unregister(struct class *cls) | 184 | void class_unregister(struct class *cls) |
169 | { | 185 | { |
170 | pr_debug("device class '%s': unregistering\n", cls->name); | 186 | pr_debug("device class '%s': unregistering\n", cls->name); |
171 | remove_class_attrs(cls); | 187 | remove_class_attrs(cls); |
172 | kset_unregister(&cls->subsys); | 188 | kset_unregister(&cls->p->class_subsys); |
173 | } | 189 | } |
174 | 190 | ||
175 | static void class_create_release(struct class *cls) | 191 | static void class_create_release(struct class *cls) |
@@ -189,7 +205,8 @@ static void class_create_release(struct class *cls) | |||
189 | * Note, the pointer created here is to be destroyed when finished by | 205 | * Note, the pointer created here is to be destroyed when finished by |
190 | * making a call to class_destroy(). | 206 | * making a call to class_destroy(). |
191 | */ | 207 | */ |
192 | struct class *class_create(struct module *owner, const char *name) | 208 | struct class *__class_create(struct module *owner, const char *name, |
209 | struct lock_class_key *key) | ||
193 | { | 210 | { |
194 | struct class *cls; | 211 | struct class *cls; |
195 | int retval; | 212 | int retval; |
@@ -204,7 +221,7 @@ struct class *class_create(struct module *owner, const char *name) | |||
204 | cls->owner = owner; | 221 | cls->owner = owner; |
205 | cls->class_release = class_create_release; | 222 | cls->class_release = class_create_release; |
206 | 223 | ||
207 | retval = class_register(cls); | 224 | retval = __class_register(cls, key); |
208 | if (retval) | 225 | if (retval) |
209 | goto error; | 226 | goto error; |
210 | 227 | ||
@@ -214,6 +231,7 @@ error: | |||
214 | kfree(cls); | 231 | kfree(cls); |
215 | return ERR_PTR(retval); | 232 | return ERR_PTR(retval); |
216 | } | 233 | } |
234 | EXPORT_SYMBOL_GPL(__class_create); | ||
217 | 235 | ||
218 | /** | 236 | /** |
219 | * class_destroy - destroys a struct class structure | 237 | * class_destroy - destroys a struct class structure |
@@ -252,39 +270,44 @@ char *make_class_name(const char *name, struct kobject *kobj) | |||
252 | /** | 270 | /** |
253 | * class_for_each_device - device iterator | 271 | * class_for_each_device - device iterator |
254 | * @class: the class we're iterating | 272 | * @class: the class we're iterating |
273 | * @start: the device to start with in the list, if any. | ||
255 | * @data: data for the callback | 274 | * @data: data for the callback |
256 | * @fn: function to be called for each device | 275 | * @fn: function to be called for each device |
257 | * | 276 | * |
258 | * Iterate over @class's list of devices, and call @fn for each, | 277 | * Iterate over @class's list of devices, and call @fn for each, |
259 | * passing it @data. | 278 | * passing it @data. If @start is set, the list iteration will start |
279 | * there, otherwise if it is NULL, the iteration starts at the | ||
280 | * beginning of the list. | ||
260 | * | 281 | * |
261 | * We check the return of @fn each time. If it returns anything | 282 | * We check the return of @fn each time. If it returns anything |
262 | * other than 0, we break out and return that value. | 283 | * other than 0, we break out and return that value. |
263 | * | 284 | * |
264 | * Note, we hold class->sem in this function, so it can not be | 285 | * Note, we hold class->class_mutex in this function, so it can not be |
265 | * re-acquired in @fn, otherwise it will self-deadlocking. For | 286 | * re-acquired in @fn, otherwise it will self-deadlocking. For |
266 | * example, calls to add or remove class members would be verboten. | 287 | * example, calls to add or remove class members would be verboten. |
267 | */ | 288 | */ |
268 | int class_for_each_device(struct class *class, void *data, | 289 | int class_for_each_device(struct class *class, struct device *start, |
269 | int (*fn)(struct device *, void *)) | 290 | void *data, int (*fn)(struct device *, void *)) |
270 | { | 291 | { |
271 | struct device *dev; | 292 | struct device *dev; |
272 | int error = 0; | 293 | int error = 0; |
273 | 294 | ||
274 | if (!class) | 295 | if (!class) |
275 | return -EINVAL; | 296 | return -EINVAL; |
276 | down(&class->sem); | 297 | mutex_lock(&class->p->class_mutex); |
277 | list_for_each_entry(dev, &class->devices, node) { | 298 | list_for_each_entry(dev, &class->p->class_devices, node) { |
299 | if (start) { | ||
300 | if (start == dev) | ||
301 | start = NULL; | ||
302 | continue; | ||
303 | } | ||
278 | dev = get_device(dev); | 304 | dev = get_device(dev); |
279 | if (dev) { | 305 | error = fn(dev, data); |
280 | error = fn(dev, data); | 306 | put_device(dev); |
281 | put_device(dev); | ||
282 | } else | ||
283 | error = -ENODEV; | ||
284 | if (error) | 307 | if (error) |
285 | break; | 308 | break; |
286 | } | 309 | } |
287 | up(&class->sem); | 310 | mutex_unlock(&class->p->class_mutex); |
288 | 311 | ||
289 | return error; | 312 | return error; |
290 | } | 313 | } |
@@ -293,6 +316,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device); | |||
293 | /** | 316 | /** |
294 | * class_find_device - device iterator for locating a particular device | 317 | * class_find_device - device iterator for locating a particular device |
295 | * @class: the class we're iterating | 318 | * @class: the class we're iterating |
319 | * @start: Device to begin with | ||
296 | * @data: data for the match function | 320 | * @data: data for the match function |
297 | * @match: function to check device | 321 | * @match: function to check device |
298 | * | 322 | * |
@@ -306,12 +330,13 @@ EXPORT_SYMBOL_GPL(class_for_each_device); | |||
306 | * | 330 | * |
307 | * Note, you will need to drop the reference with put_device() after use. | 331 | * Note, you will need to drop the reference with put_device() after use. |
308 | * | 332 | * |
309 | * We hold class->sem in this function, so it can not be | 333 | * We hold class->class_mutex in this function, so it can not be |
310 | * re-acquired in @match, otherwise it will self-deadlocking. For | 334 | * re-acquired in @match, otherwise it will self-deadlocking. For |
311 | * example, calls to add or remove class members would be verboten. | 335 | * example, calls to add or remove class members would be verboten. |
312 | */ | 336 | */ |
313 | struct device *class_find_device(struct class *class, void *data, | 337 | struct device *class_find_device(struct class *class, struct device *start, |
314 | int (*match)(struct device *, void *)) | 338 | void *data, |
339 | int (*match)(struct device *, void *)) | ||
315 | { | 340 | { |
316 | struct device *dev; | 341 | struct device *dev; |
317 | int found = 0; | 342 | int found = 0; |
@@ -319,19 +344,21 @@ struct device *class_find_device(struct class *class, void *data, | |||
319 | if (!class) | 344 | if (!class) |
320 | return NULL; | 345 | return NULL; |
321 | 346 | ||
322 | down(&class->sem); | 347 | mutex_lock(&class->p->class_mutex); |
323 | list_for_each_entry(dev, &class->devices, node) { | 348 | list_for_each_entry(dev, &class->p->class_devices, node) { |
349 | if (start) { | ||
350 | if (start == dev) | ||
351 | start = NULL; | ||
352 | continue; | ||
353 | } | ||
324 | dev = get_device(dev); | 354 | dev = get_device(dev); |
325 | if (dev) { | 355 | if (match(dev, data)) { |
326 | if (match(dev, data)) { | 356 | found = 1; |
327 | found = 1; | ||
328 | break; | ||
329 | } else | ||
330 | put_device(dev); | ||
331 | } else | ||
332 | break; | 357 | break; |
358 | } else | ||
359 | put_device(dev); | ||
333 | } | 360 | } |
334 | up(&class->sem); | 361 | mutex_unlock(&class->p->class_mutex); |
335 | 362 | ||
336 | return found ? dev : NULL; | 363 | return found ? dev : NULL; |
337 | } | 364 | } |
@@ -349,13 +376,13 @@ int class_interface_register(struct class_interface *class_intf) | |||
349 | if (!parent) | 376 | if (!parent) |
350 | return -EINVAL; | 377 | return -EINVAL; |
351 | 378 | ||
352 | down(&parent->sem); | 379 | mutex_lock(&parent->p->class_mutex); |
353 | list_add_tail(&class_intf->node, &parent->interfaces); | 380 | list_add_tail(&class_intf->node, &parent->p->class_interfaces); |
354 | if (class_intf->add_dev) { | 381 | if (class_intf->add_dev) { |
355 | list_for_each_entry(dev, &parent->devices, node) | 382 | list_for_each_entry(dev, &parent->p->class_devices, node) |
356 | class_intf->add_dev(dev, class_intf); | 383 | class_intf->add_dev(dev, class_intf); |
357 | } | 384 | } |
358 | up(&parent->sem); | 385 | mutex_unlock(&parent->p->class_mutex); |
359 | 386 | ||
360 | return 0; | 387 | return 0; |
361 | } | 388 | } |
@@ -368,13 +395,13 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
368 | if (!parent) | 395 | if (!parent) |
369 | return; | 396 | return; |
370 | 397 | ||
371 | down(&parent->sem); | 398 | mutex_lock(&parent->p->class_mutex); |
372 | list_del_init(&class_intf->node); | 399 | list_del_init(&class_intf->node); |
373 | if (class_intf->remove_dev) { | 400 | if (class_intf->remove_dev) { |
374 | list_for_each_entry(dev, &parent->devices, node) | 401 | list_for_each_entry(dev, &parent->p->class_devices, node) |
375 | class_intf->remove_dev(dev, class_intf); | 402 | class_intf->remove_dev(dev, class_intf); |
376 | } | 403 | } |
377 | up(&parent->sem); | 404 | mutex_unlock(&parent->p->class_mutex); |
378 | 405 | ||
379 | class_put(parent); | 406 | class_put(parent); |
380 | } | 407 | } |
@@ -389,9 +416,7 @@ int __init classes_init(void) | |||
389 | 416 | ||
390 | EXPORT_SYMBOL_GPL(class_create_file); | 417 | EXPORT_SYMBOL_GPL(class_create_file); |
391 | EXPORT_SYMBOL_GPL(class_remove_file); | 418 | EXPORT_SYMBOL_GPL(class_remove_file); |
392 | EXPORT_SYMBOL_GPL(class_register); | ||
393 | EXPORT_SYMBOL_GPL(class_unregister); | 419 | EXPORT_SYMBOL_GPL(class_unregister); |
394 | EXPORT_SYMBOL_GPL(class_create); | ||
395 | EXPORT_SYMBOL_GPL(class_destroy); | 420 | EXPORT_SYMBOL_GPL(class_destroy); |
396 | 421 | ||
397 | EXPORT_SYMBOL_GPL(class_interface_register); | 422 | EXPORT_SYMBOL_GPL(class_interface_register); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index ee0a51a3a41d..7d5c63c81a59 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -21,12 +21,16 @@ | |||
21 | #include <linux/genhd.h> | 21 | #include <linux/genhd.h> |
22 | #include <linux/kallsyms.h> | 22 | #include <linux/kallsyms.h> |
23 | #include <linux/semaphore.h> | 23 | #include <linux/semaphore.h> |
24 | #include <linux/mutex.h> | ||
24 | 25 | ||
25 | #include "base.h" | 26 | #include "base.h" |
26 | #include "power/power.h" | 27 | #include "power/power.h" |
27 | 28 | ||
28 | int (*platform_notify)(struct device *dev) = NULL; | 29 | int (*platform_notify)(struct device *dev) = NULL; |
29 | int (*platform_notify_remove)(struct device *dev) = NULL; | 30 | int (*platform_notify_remove)(struct device *dev) = NULL; |
31 | static struct kobject *dev_kobj; | ||
32 | struct kobject *sysfs_dev_char_kobj; | ||
33 | struct kobject *sysfs_dev_block_kobj; | ||
30 | 34 | ||
31 | #ifdef CONFIG_BLOCK | 35 | #ifdef CONFIG_BLOCK |
32 | static inline int device_is_not_partition(struct device *dev) | 36 | static inline int device_is_not_partition(struct device *dev) |
@@ -548,7 +552,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
548 | { | 552 | { |
549 | /* class devices without a parent live in /sys/class/<classname>/ */ | 553 | /* class devices without a parent live in /sys/class/<classname>/ */ |
550 | if (dev->class && (!parent || parent->class != dev->class)) | 554 | if (dev->class && (!parent || parent->class != dev->class)) |
551 | return &dev->class->subsys.kobj; | 555 | return &dev->class->p->class_subsys.kobj; |
552 | /* all other devices keep their parent */ | 556 | /* all other devices keep their parent */ |
553 | else if (parent) | 557 | else if (parent) |
554 | return &parent->kobj; | 558 | return &parent->kobj; |
@@ -594,13 +598,13 @@ static struct kobject *get_device_parent(struct device *dev, | |||
594 | parent_kobj = &parent->kobj; | 598 | parent_kobj = &parent->kobj; |
595 | 599 | ||
596 | /* find our class-directory at the parent and reference it */ | 600 | /* find our class-directory at the parent and reference it */ |
597 | spin_lock(&dev->class->class_dirs.list_lock); | 601 | spin_lock(&dev->class->p->class_dirs.list_lock); |
598 | list_for_each_entry(k, &dev->class->class_dirs.list, entry) | 602 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) |
599 | if (k->parent == parent_kobj) { | 603 | if (k->parent == parent_kobj) { |
600 | kobj = kobject_get(k); | 604 | kobj = kobject_get(k); |
601 | break; | 605 | break; |
602 | } | 606 | } |
603 | spin_unlock(&dev->class->class_dirs.list_lock); | 607 | spin_unlock(&dev->class->p->class_dirs.list_lock); |
604 | if (kobj) | 608 | if (kobj) |
605 | return kobj; | 609 | return kobj; |
606 | 610 | ||
@@ -608,7 +612,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
608 | k = kobject_create(); | 612 | k = kobject_create(); |
609 | if (!k) | 613 | if (!k) |
610 | return NULL; | 614 | return NULL; |
611 | k->kset = &dev->class->class_dirs; | 615 | k->kset = &dev->class->p->class_dirs; |
612 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | 616 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); |
613 | if (retval < 0) { | 617 | if (retval < 0) { |
614 | kobject_put(k); | 618 | kobject_put(k); |
@@ -627,7 +631,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) | |||
627 | { | 631 | { |
628 | /* see if we live in a "glue" directory */ | 632 | /* see if we live in a "glue" directory */ |
629 | if (!glue_dir || !dev->class || | 633 | if (!glue_dir || !dev->class || |
630 | glue_dir->kset != &dev->class->class_dirs) | 634 | glue_dir->kset != &dev->class->p->class_dirs) |
631 | return; | 635 | return; |
632 | 636 | ||
633 | kobject_put(glue_dir); | 637 | kobject_put(glue_dir); |
@@ -654,17 +658,18 @@ static int device_add_class_symlinks(struct device *dev) | |||
654 | if (!dev->class) | 658 | if (!dev->class) |
655 | return 0; | 659 | return 0; |
656 | 660 | ||
657 | error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, | 661 | error = sysfs_create_link(&dev->kobj, |
662 | &dev->class->p->class_subsys.kobj, | ||
658 | "subsystem"); | 663 | "subsystem"); |
659 | if (error) | 664 | if (error) |
660 | goto out; | 665 | goto out; |
661 | 666 | ||
662 | #ifdef CONFIG_SYSFS_DEPRECATED | 667 | #ifdef CONFIG_SYSFS_DEPRECATED |
663 | /* stacked class devices need a symlink in the class directory */ | 668 | /* stacked class devices need a symlink in the class directory */ |
664 | if (dev->kobj.parent != &dev->class->subsys.kobj && | 669 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && |
665 | device_is_not_partition(dev)) { | 670 | device_is_not_partition(dev)) { |
666 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 671 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, |
667 | dev->bus_id); | 672 | &dev->kobj, dev->bus_id); |
668 | if (error) | 673 | if (error) |
669 | goto out_subsys; | 674 | goto out_subsys; |
670 | } | 675 | } |
@@ -701,13 +706,14 @@ out_device: | |||
701 | if (dev->parent && device_is_not_partition(dev)) | 706 | if (dev->parent && device_is_not_partition(dev)) |
702 | sysfs_remove_link(&dev->kobj, "device"); | 707 | sysfs_remove_link(&dev->kobj, "device"); |
703 | out_busid: | 708 | out_busid: |
704 | if (dev->kobj.parent != &dev->class->subsys.kobj && | 709 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && |
705 | device_is_not_partition(dev)) | 710 | device_is_not_partition(dev)) |
706 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 711 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, |
712 | dev->bus_id); | ||
707 | #else | 713 | #else |
708 | /* link in the class directory pointing to the device */ | 714 | /* link in the class directory pointing to the device */ |
709 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 715 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, |
710 | dev->bus_id); | 716 | &dev->kobj, dev->bus_id); |
711 | if (error) | 717 | if (error) |
712 | goto out_subsys; | 718 | goto out_subsys; |
713 | 719 | ||
@@ -720,7 +726,7 @@ out_busid: | |||
720 | return 0; | 726 | return 0; |
721 | 727 | ||
722 | out_busid: | 728 | out_busid: |
723 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 729 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id); |
724 | #endif | 730 | #endif |
725 | 731 | ||
726 | out_subsys: | 732 | out_subsys: |
@@ -746,14 +752,15 @@ static void device_remove_class_symlinks(struct device *dev) | |||
746 | sysfs_remove_link(&dev->kobj, "device"); | 752 | sysfs_remove_link(&dev->kobj, "device"); |
747 | } | 753 | } |
748 | 754 | ||
749 | if (dev->kobj.parent != &dev->class->subsys.kobj && | 755 | if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && |
750 | device_is_not_partition(dev)) | 756 | device_is_not_partition(dev)) |
751 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 757 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, |
758 | dev->bus_id); | ||
752 | #else | 759 | #else |
753 | if (dev->parent && device_is_not_partition(dev)) | 760 | if (dev->parent && device_is_not_partition(dev)) |
754 | sysfs_remove_link(&dev->kobj, "device"); | 761 | sysfs_remove_link(&dev->kobj, "device"); |
755 | 762 | ||
756 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 763 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id); |
757 | #endif | 764 | #endif |
758 | 765 | ||
759 | sysfs_remove_link(&dev->kobj, "subsystem"); | 766 | sysfs_remove_link(&dev->kobj, "subsystem"); |
@@ -776,6 +783,54 @@ int dev_set_name(struct device *dev, const char *fmt, ...) | |||
776 | EXPORT_SYMBOL_GPL(dev_set_name); | 783 | EXPORT_SYMBOL_GPL(dev_set_name); |
777 | 784 | ||
778 | /** | 785 | /** |
786 | * device_to_dev_kobj - select a /sys/dev/ directory for the device | ||
787 | * @dev: device | ||
788 | * | ||
789 | * By default we select char/ for new entries. Setting class->dev_obj | ||
790 | * to NULL prevents an entry from being created. class->dev_kobj must | ||
791 | * be set (or cleared) before any devices are registered to the class | ||
792 | * otherwise device_create_sys_dev_entry() and | ||
793 | * device_remove_sys_dev_entry() will disagree about the the presence | ||
794 | * of the link. | ||
795 | */ | ||
796 | static struct kobject *device_to_dev_kobj(struct device *dev) | ||
797 | { | ||
798 | struct kobject *kobj; | ||
799 | |||
800 | if (dev->class) | ||
801 | kobj = dev->class->dev_kobj; | ||
802 | else | ||
803 | kobj = sysfs_dev_char_kobj; | ||
804 | |||
805 | return kobj; | ||
806 | } | ||
807 | |||
808 | static int device_create_sys_dev_entry(struct device *dev) | ||
809 | { | ||
810 | struct kobject *kobj = device_to_dev_kobj(dev); | ||
811 | int error = 0; | ||
812 | char devt_str[15]; | ||
813 | |||
814 | if (kobj) { | ||
815 | format_dev_t(devt_str, dev->devt); | ||
816 | error = sysfs_create_link(kobj, &dev->kobj, devt_str); | ||
817 | } | ||
818 | |||
819 | return error; | ||
820 | } | ||
821 | |||
822 | static void device_remove_sys_dev_entry(struct device *dev) | ||
823 | { | ||
824 | struct kobject *kobj = device_to_dev_kobj(dev); | ||
825 | char devt_str[15]; | ||
826 | |||
827 | if (kobj) { | ||
828 | format_dev_t(devt_str, dev->devt); | ||
829 | sysfs_remove_link(kobj, devt_str); | ||
830 | } | ||
831 | } | ||
832 | |||
833 | /** | ||
779 | * device_add - add device to device hierarchy. | 834 | * device_add - add device to device hierarchy. |
780 | * @dev: device. | 835 | * @dev: device. |
781 | * | 836 | * |
@@ -829,6 +884,10 @@ int device_add(struct device *dev) | |||
829 | error = device_create_file(dev, &devt_attr); | 884 | error = device_create_file(dev, &devt_attr); |
830 | if (error) | 885 | if (error) |
831 | goto ueventattrError; | 886 | goto ueventattrError; |
887 | |||
888 | error = device_create_sys_dev_entry(dev); | ||
889 | if (error) | ||
890 | goto devtattrError; | ||
832 | } | 891 | } |
833 | 892 | ||
834 | error = device_add_class_symlinks(dev); | 893 | error = device_add_class_symlinks(dev); |
@@ -849,15 +908,16 @@ int device_add(struct device *dev) | |||
849 | klist_add_tail(&dev->knode_parent, &parent->klist_children); | 908 | klist_add_tail(&dev->knode_parent, &parent->klist_children); |
850 | 909 | ||
851 | if (dev->class) { | 910 | if (dev->class) { |
852 | down(&dev->class->sem); | 911 | mutex_lock(&dev->class->p->class_mutex); |
853 | /* tie the class to the device */ | 912 | /* tie the class to the device */ |
854 | list_add_tail(&dev->node, &dev->class->devices); | 913 | list_add_tail(&dev->node, &dev->class->p->class_devices); |
855 | 914 | ||
856 | /* notify any interfaces that the device is here */ | 915 | /* notify any interfaces that the device is here */ |
857 | list_for_each_entry(class_intf, &dev->class->interfaces, node) | 916 | list_for_each_entry(class_intf, |
917 | &dev->class->p->class_interfaces, node) | ||
858 | if (class_intf->add_dev) | 918 | if (class_intf->add_dev) |
859 | class_intf->add_dev(dev, class_intf); | 919 | class_intf->add_dev(dev, class_intf); |
860 | up(&dev->class->sem); | 920 | mutex_unlock(&dev->class->p->class_mutex); |
861 | } | 921 | } |
862 | Done: | 922 | Done: |
863 | put_device(dev); | 923 | put_device(dev); |
@@ -873,6 +933,9 @@ int device_add(struct device *dev) | |||
873 | device_remove_class_symlinks(dev); | 933 | device_remove_class_symlinks(dev); |
874 | SymlinkError: | 934 | SymlinkError: |
875 | if (MAJOR(dev->devt)) | 935 | if (MAJOR(dev->devt)) |
936 | device_remove_sys_dev_entry(dev); | ||
937 | devtattrError: | ||
938 | if (MAJOR(dev->devt)) | ||
876 | device_remove_file(dev, &devt_attr); | 939 | device_remove_file(dev, &devt_attr); |
877 | ueventattrError: | 940 | ueventattrError: |
878 | device_remove_file(dev, &uevent_attr); | 941 | device_remove_file(dev, &uevent_attr); |
@@ -948,19 +1011,22 @@ void device_del(struct device *dev) | |||
948 | device_pm_remove(dev); | 1011 | device_pm_remove(dev); |
949 | if (parent) | 1012 | if (parent) |
950 | klist_del(&dev->knode_parent); | 1013 | klist_del(&dev->knode_parent); |
951 | if (MAJOR(dev->devt)) | 1014 | if (MAJOR(dev->devt)) { |
1015 | device_remove_sys_dev_entry(dev); | ||
952 | device_remove_file(dev, &devt_attr); | 1016 | device_remove_file(dev, &devt_attr); |
1017 | } | ||
953 | if (dev->class) { | 1018 | if (dev->class) { |
954 | device_remove_class_symlinks(dev); | 1019 | device_remove_class_symlinks(dev); |
955 | 1020 | ||
956 | down(&dev->class->sem); | 1021 | mutex_lock(&dev->class->p->class_mutex); |
957 | /* notify any interfaces that the device is now gone */ | 1022 | /* notify any interfaces that the device is now gone */ |
958 | list_for_each_entry(class_intf, &dev->class->interfaces, node) | 1023 | list_for_each_entry(class_intf, |
1024 | &dev->class->p->class_interfaces, node) | ||
959 | if (class_intf->remove_dev) | 1025 | if (class_intf->remove_dev) |
960 | class_intf->remove_dev(dev, class_intf); | 1026 | class_intf->remove_dev(dev, class_intf); |
961 | /* remove the device from the class list */ | 1027 | /* remove the device from the class list */ |
962 | list_del_init(&dev->node); | 1028 | list_del_init(&dev->node); |
963 | up(&dev->class->sem); | 1029 | mutex_unlock(&dev->class->p->class_mutex); |
964 | } | 1030 | } |
965 | device_remove_file(dev, &uevent_attr); | 1031 | device_remove_file(dev, &uevent_attr); |
966 | device_remove_attrs(dev); | 1032 | device_remove_attrs(dev); |
@@ -1074,7 +1140,25 @@ int __init devices_init(void) | |||
1074 | devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); | 1140 | devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); |
1075 | if (!devices_kset) | 1141 | if (!devices_kset) |
1076 | return -ENOMEM; | 1142 | return -ENOMEM; |
1143 | dev_kobj = kobject_create_and_add("dev", NULL); | ||
1144 | if (!dev_kobj) | ||
1145 | goto dev_kobj_err; | ||
1146 | sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); | ||
1147 | if (!sysfs_dev_block_kobj) | ||
1148 | goto block_kobj_err; | ||
1149 | sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); | ||
1150 | if (!sysfs_dev_char_kobj) | ||
1151 | goto char_kobj_err; | ||
1152 | |||
1077 | return 0; | 1153 | return 0; |
1154 | |||
1155 | char_kobj_err: | ||
1156 | kobject_put(sysfs_dev_block_kobj); | ||
1157 | block_kobj_err: | ||
1158 | kobject_put(dev_kobj); | ||
1159 | dev_kobj_err: | ||
1160 | kset_unregister(devices_kset); | ||
1161 | return -ENOMEM; | ||
1078 | } | 1162 | } |
1079 | 1163 | ||
1080 | EXPORT_SYMBOL_GPL(device_for_each_child); | 1164 | EXPORT_SYMBOL_GPL(device_for_each_child); |
@@ -1158,48 +1242,11 @@ error: | |||
1158 | EXPORT_SYMBOL_GPL(device_create_vargs); | 1242 | EXPORT_SYMBOL_GPL(device_create_vargs); |
1159 | 1243 | ||
1160 | /** | 1244 | /** |
1161 | * device_create_drvdata - creates a device and registers it with sysfs | ||
1162 | * @class: pointer to the struct class that this device should be registered to | ||
1163 | * @parent: pointer to the parent struct device of this new device, if any | ||
1164 | * @devt: the dev_t for the char device to be added | ||
1165 | * @drvdata: the data to be added to the device for callbacks | ||
1166 | * @fmt: string for the device's name | ||
1167 | * | ||
1168 | * This function can be used by char device classes. A struct device | ||
1169 | * will be created in sysfs, registered to the specified class. | ||
1170 | * | ||
1171 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1172 | * the dev_t is not 0,0. | ||
1173 | * If a pointer to a parent struct device is passed in, the newly created | ||
1174 | * struct device will be a child of that device in sysfs. | ||
1175 | * The pointer to the struct device will be returned from the call. | ||
1176 | * Any further sysfs files that might be required can be created using this | ||
1177 | * pointer. | ||
1178 | * | ||
1179 | * Note: the struct class passed to this function must have previously | ||
1180 | * been created with a call to class_create(). | ||
1181 | */ | ||
1182 | struct device *device_create_drvdata(struct class *class, | ||
1183 | struct device *parent, | ||
1184 | dev_t devt, | ||
1185 | void *drvdata, | ||
1186 | const char *fmt, ...) | ||
1187 | { | ||
1188 | va_list vargs; | ||
1189 | struct device *dev; | ||
1190 | |||
1191 | va_start(vargs, fmt); | ||
1192 | dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); | ||
1193 | va_end(vargs); | ||
1194 | return dev; | ||
1195 | } | ||
1196 | EXPORT_SYMBOL_GPL(device_create_drvdata); | ||
1197 | |||
1198 | /** | ||
1199 | * device_create - creates a device and registers it with sysfs | 1245 | * device_create - creates a device and registers it with sysfs |
1200 | * @class: pointer to the struct class that this device should be registered to | 1246 | * @class: pointer to the struct class that this device should be registered to |
1201 | * @parent: pointer to the parent struct device of this new device, if any | 1247 | * @parent: pointer to the parent struct device of this new device, if any |
1202 | * @devt: the dev_t for the char device to be added | 1248 | * @devt: the dev_t for the char device to be added |
1249 | * @drvdata: the data to be added to the device for callbacks | ||
1203 | * @fmt: string for the device's name | 1250 | * @fmt: string for the device's name |
1204 | * | 1251 | * |
1205 | * This function can be used by char device classes. A struct device | 1252 | * This function can be used by char device classes. A struct device |
@@ -1217,13 +1264,13 @@ EXPORT_SYMBOL_GPL(device_create_drvdata); | |||
1217 | * been created with a call to class_create(). | 1264 | * been created with a call to class_create(). |
1218 | */ | 1265 | */ |
1219 | struct device *device_create(struct class *class, struct device *parent, | 1266 | struct device *device_create(struct class *class, struct device *parent, |
1220 | dev_t devt, const char *fmt, ...) | 1267 | dev_t devt, void *drvdata, const char *fmt, ...) |
1221 | { | 1268 | { |
1222 | va_list vargs; | 1269 | va_list vargs; |
1223 | struct device *dev; | 1270 | struct device *dev; |
1224 | 1271 | ||
1225 | va_start(vargs, fmt); | 1272 | va_start(vargs, fmt); |
1226 | dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs); | 1273 | dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); |
1227 | va_end(vargs); | 1274 | va_end(vargs); |
1228 | return dev; | 1275 | return dev; |
1229 | } | 1276 | } |
@@ -1248,7 +1295,7 @@ void device_destroy(struct class *class, dev_t devt) | |||
1248 | { | 1295 | { |
1249 | struct device *dev; | 1296 | struct device *dev; |
1250 | 1297 | ||
1251 | dev = class_find_device(class, &devt, __match_devt); | 1298 | dev = class_find_device(class, NULL, &devt, __match_devt); |
1252 | if (dev) { | 1299 | if (dev) { |
1253 | put_device(dev); | 1300 | put_device(dev); |
1254 | device_unregister(dev); | 1301 | device_unregister(dev); |
@@ -1298,8 +1345,9 @@ int device_rename(struct device *dev, char *new_name) | |||
1298 | if (old_class_name) { | 1345 | if (old_class_name) { |
1299 | new_class_name = make_class_name(dev->class->name, &dev->kobj); | 1346 | new_class_name = make_class_name(dev->class->name, &dev->kobj); |
1300 | if (new_class_name) { | 1347 | if (new_class_name) { |
1301 | error = sysfs_create_link(&dev->parent->kobj, | 1348 | error = sysfs_create_link_nowarn(&dev->parent->kobj, |
1302 | &dev->kobj, new_class_name); | 1349 | &dev->kobj, |
1350 | new_class_name); | ||
1303 | if (error) | 1351 | if (error) |
1304 | goto out; | 1352 | goto out; |
1305 | sysfs_remove_link(&dev->parent->kobj, old_class_name); | 1353 | sysfs_remove_link(&dev->parent->kobj, old_class_name); |
@@ -1307,11 +1355,12 @@ int device_rename(struct device *dev, char *new_name) | |||
1307 | } | 1355 | } |
1308 | #else | 1356 | #else |
1309 | if (dev->class) { | 1357 | if (dev->class) { |
1310 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 1358 | error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj, |
1311 | dev->bus_id); | 1359 | &dev->kobj, dev->bus_id); |
1312 | if (error) | 1360 | if (error) |
1313 | goto out; | 1361 | goto out; |
1314 | sysfs_remove_link(&dev->class->subsys.kobj, old_device_name); | 1362 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, |
1363 | old_device_name); | ||
1315 | } | 1364 | } |
1316 | #endif | 1365 | #endif |
1317 | 1366 | ||
@@ -1447,4 +1496,7 @@ void device_shutdown(void) | |||
1447 | dev->driver->shutdown(dev); | 1496 | dev->driver->shutdown(dev); |
1448 | } | 1497 | } |
1449 | } | 1498 | } |
1499 | kobject_put(sysfs_dev_char_kobj); | ||
1500 | kobject_put(sysfs_dev_block_kobj); | ||
1501 | kobject_put(dev_kobj); | ||
1450 | } | 1502 | } |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 5000402ae092..64f5d54f7edc 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -21,15 +21,16 @@ EXPORT_SYMBOL(cpu_sysdev_class); | |||
21 | static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices); | 21 | static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices); |
22 | 22 | ||
23 | #ifdef CONFIG_HOTPLUG_CPU | 23 | #ifdef CONFIG_HOTPLUG_CPU |
24 | static ssize_t show_online(struct sys_device *dev, char *buf) | 24 | static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr, |
25 | char *buf) | ||
25 | { | 26 | { |
26 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); | 27 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); |
27 | 28 | ||
28 | return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id)); | 29 | return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id)); |
29 | } | 30 | } |
30 | 31 | ||
31 | static ssize_t __ref store_online(struct sys_device *dev, const char *buf, | 32 | static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribute *attr, |
32 | size_t count) | 33 | const char *buf, size_t count) |
33 | { | 34 | { |
34 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); | 35 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); |
35 | ssize_t ret; | 36 | ssize_t ret; |
@@ -80,7 +81,8 @@ static inline void register_cpu_control(struct cpu *cpu) | |||
80 | #ifdef CONFIG_KEXEC | 81 | #ifdef CONFIG_KEXEC |
81 | #include <linux/kexec.h> | 82 | #include <linux/kexec.h> |
82 | 83 | ||
83 | static ssize_t show_crash_notes(struct sys_device *dev, char *buf) | 84 | static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute *attr, |
85 | char *buf) | ||
84 | { | 86 | { |
85 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); | 87 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); |
86 | ssize_t rc; | 88 | ssize_t rc; |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 937e8258981d..4d4e0e7b6e92 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -92,7 +92,8 @@ unregister_memory(struct memory_block *memory, struct mem_section *section) | |||
92 | * uses. | 92 | * uses. |
93 | */ | 93 | */ |
94 | 94 | ||
95 | static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf) | 95 | static ssize_t show_mem_phys_index(struct sys_device *dev, |
96 | struct sysdev_attribute *attr, char *buf) | ||
96 | { | 97 | { |
97 | struct memory_block *mem = | 98 | struct memory_block *mem = |
98 | container_of(dev, struct memory_block, sysdev); | 99 | container_of(dev, struct memory_block, sysdev); |
@@ -102,7 +103,8 @@ static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf) | |||
102 | /* | 103 | /* |
103 | * online, offline, going offline, etc. | 104 | * online, offline, going offline, etc. |
104 | */ | 105 | */ |
105 | static ssize_t show_mem_state(struct sys_device *dev, char *buf) | 106 | static ssize_t show_mem_state(struct sys_device *dev, |
107 | struct sysdev_attribute *attr, char *buf) | ||
106 | { | 108 | { |
107 | struct memory_block *mem = | 109 | struct memory_block *mem = |
108 | container_of(dev, struct memory_block, sysdev); | 110 | container_of(dev, struct memory_block, sysdev); |
@@ -217,7 +219,8 @@ out: | |||
217 | } | 219 | } |
218 | 220 | ||
219 | static ssize_t | 221 | static ssize_t |
220 | store_mem_state(struct sys_device *dev, const char *buf, size_t count) | 222 | store_mem_state(struct sys_device *dev, |
223 | struct sysdev_attribute *attr, const char *buf, size_t count) | ||
221 | { | 224 | { |
222 | struct memory_block *mem; | 225 | struct memory_block *mem; |
223 | unsigned int phys_section_nr; | 226 | unsigned int phys_section_nr; |
@@ -248,7 +251,8 @@ out: | |||
248 | * s.t. if I offline all of these sections I can then | 251 | * s.t. if I offline all of these sections I can then |
249 | * remove the physical device? | 252 | * remove the physical device? |
250 | */ | 253 | */ |
251 | static ssize_t show_phys_device(struct sys_device *dev, char *buf) | 254 | static ssize_t show_phys_device(struct sys_device *dev, |
255 | struct sysdev_attribute *attr, char *buf) | ||
252 | { | 256 | { |
253 | struct memory_block *mem = | 257 | struct memory_block *mem = |
254 | container_of(dev, struct memory_block, sysdev); | 258 | container_of(dev, struct memory_block, sysdev); |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 0f867a083338..5116b78c6325 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -36,11 +36,13 @@ static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf) | |||
36 | return len; | 36 | return len; |
37 | } | 37 | } |
38 | 38 | ||
39 | static inline ssize_t node_read_cpumask(struct sys_device *dev, char *buf) | 39 | static inline ssize_t node_read_cpumask(struct sys_device *dev, |
40 | struct sysdev_attribute *attr, char *buf) | ||
40 | { | 41 | { |
41 | return node_read_cpumap(dev, 0, buf); | 42 | return node_read_cpumap(dev, 0, buf); |
42 | } | 43 | } |
43 | static inline ssize_t node_read_cpulist(struct sys_device *dev, char *buf) | 44 | static inline ssize_t node_read_cpulist(struct sys_device *dev, |
45 | struct sysdev_attribute *attr, char *buf) | ||
44 | { | 46 | { |
45 | return node_read_cpumap(dev, 1, buf); | 47 | return node_read_cpumap(dev, 1, buf); |
46 | } | 48 | } |
@@ -49,7 +51,8 @@ static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL); | |||
49 | static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL); | 51 | static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL); |
50 | 52 | ||
51 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 53 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
52 | static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | 54 | static ssize_t node_read_meminfo(struct sys_device * dev, |
55 | struct sysdev_attribute *attr, char * buf) | ||
53 | { | 56 | { |
54 | int n; | 57 | int n; |
55 | int nid = dev->id; | 58 | int nid = dev->id; |
@@ -112,7 +115,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | |||
112 | #undef K | 115 | #undef K |
113 | static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL); | 116 | static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL); |
114 | 117 | ||
115 | static ssize_t node_read_numastat(struct sys_device * dev, char * buf) | 118 | static ssize_t node_read_numastat(struct sys_device * dev, |
119 | struct sysdev_attribute *attr, char * buf) | ||
116 | { | 120 | { |
117 | return sprintf(buf, | 121 | return sprintf(buf, |
118 | "numa_hit %lu\n" | 122 | "numa_hit %lu\n" |
@@ -130,7 +134,8 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf) | |||
130 | } | 134 | } |
131 | static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); | 135 | static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); |
132 | 136 | ||
133 | static ssize_t node_read_distance(struct sys_device * dev, char * buf) | 137 | static ssize_t node_read_distance(struct sys_device * dev, |
138 | struct sysdev_attribute *attr, char * buf) | ||
134 | { | 139 | { |
135 | int nid = dev->id; | 140 | int nid = dev->id; |
136 | int len = 0; | 141 | int len = 0; |
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index 9b1b20b59e0a..2aa6e8fc4def 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
@@ -194,7 +194,7 @@ static int show_dev_hash(unsigned int value) | |||
194 | struct device * dev = to_device(entry); | 194 | struct device * dev = to_device(entry); |
195 | unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH); | 195 | unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH); |
196 | if (hash == value) { | 196 | if (hash == value) { |
197 | printk(" hash matches device %s\n", dev->bus_id); | 197 | dev_info(dev, "hash matches\n"); |
198 | match++; | 198 | match++; |
199 | } | 199 | } |
200 | entry = entry->prev; | 200 | entry = entry->prev; |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 358bb0be3c08..40fc14f03540 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -36,7 +36,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | |||
36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); |
37 | 37 | ||
38 | if (sysdev_attr->show) | 38 | if (sysdev_attr->show) |
39 | return sysdev_attr->show(sysdev, buffer); | 39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); |
40 | return -EIO; | 40 | return -EIO; |
41 | } | 41 | } |
42 | 42 | ||
@@ -49,7 +49,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr, | |||
49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); |
50 | 50 | ||
51 | if (sysdev_attr->store) | 51 | if (sysdev_attr->store) |
52 | return sysdev_attr->store(sysdev, buffer, count); | 52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); |
53 | return -EIO; | 53 | return -EIO; |
54 | } | 54 | } |
55 | 55 | ||
@@ -130,8 +130,8 @@ static struct kset *system_kset; | |||
130 | 130 | ||
131 | int sysdev_class_register(struct sysdev_class * cls) | 131 | int sysdev_class_register(struct sysdev_class * cls) |
132 | { | 132 | { |
133 | pr_debug("Registering sysdev class '%s'\n", | 133 | pr_debug("Registering sysdev class '%s'\n", cls->name); |
134 | kobject_name(&cls->kset.kobj)); | 134 | |
135 | INIT_LIST_HEAD(&cls->drivers); | 135 | INIT_LIST_HEAD(&cls->drivers); |
136 | memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); | 136 | memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); |
137 | cls->kset.kobj.parent = &system_kset->kobj; | 137 | cls->kset.kobj.parent = &system_kset->kobj; |
@@ -241,7 +241,8 @@ int sysdev_register(struct sys_device * sysdev) | |||
241 | if (!cls) | 241 | if (!cls) |
242 | return -EINVAL; | 242 | return -EINVAL; |
243 | 243 | ||
244 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | 244 | pr_debug("Registering sys device of class '%s'\n", |
245 | kobject_name(&cls->kset.kobj)); | ||
245 | 246 | ||
246 | /* initialize the kobject to 0, in case it had previously been used */ | 247 | /* initialize the kobject to 0, in case it had previously been used */ |
247 | memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); | 248 | memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); |
@@ -257,6 +258,9 @@ int sysdev_register(struct sys_device * sysdev) | |||
257 | if (!error) { | 258 | if (!error) { |
258 | struct sysdev_driver * drv; | 259 | struct sysdev_driver * drv; |
259 | 260 | ||
261 | pr_debug("Registering sys device '%s'\n", | ||
262 | kobject_name(&sysdev->kobj)); | ||
263 | |||
260 | mutex_lock(&sysdev_drivers_lock); | 264 | mutex_lock(&sysdev_drivers_lock); |
261 | /* Generic notification is implicit, because it's that | 265 | /* Generic notification is implicit, because it's that |
262 | * code that should have called us. | 266 | * code that should have called us. |
@@ -269,6 +273,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
269 | } | 273 | } |
270 | mutex_unlock(&sysdev_drivers_lock); | 274 | mutex_unlock(&sysdev_drivers_lock); |
271 | } | 275 | } |
276 | |||
272 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | 277 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); |
273 | return error; | 278 | return error; |
274 | } | 279 | } |
@@ -474,3 +479,52 @@ int __init system_bus_init(void) | |||
474 | 479 | ||
475 | EXPORT_SYMBOL_GPL(sysdev_register); | 480 | EXPORT_SYMBOL_GPL(sysdev_register); |
476 | EXPORT_SYMBOL_GPL(sysdev_unregister); | 481 | EXPORT_SYMBOL_GPL(sysdev_unregister); |
482 | |||
483 | #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) | ||
484 | |||
485 | ssize_t sysdev_store_ulong(struct sys_device *sysdev, | ||
486 | struct sysdev_attribute *attr, | ||
487 | const char *buf, size_t size) | ||
488 | { | ||
489 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
490 | char *end; | ||
491 | unsigned long new = simple_strtoul(buf, &end, 0); | ||
492 | if (end == buf) | ||
493 | return -EINVAL; | ||
494 | *(unsigned long *)(ea->var) = new; | ||
495 | return end - buf; | ||
496 | } | ||
497 | EXPORT_SYMBOL_GPL(sysdev_store_ulong); | ||
498 | |||
499 | ssize_t sysdev_show_ulong(struct sys_device *sysdev, | ||
500 | struct sysdev_attribute *attr, | ||
501 | char *buf) | ||
502 | { | ||
503 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
504 | return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); | ||
505 | } | ||
506 | EXPORT_SYMBOL_GPL(sysdev_show_ulong); | ||
507 | |||
508 | ssize_t sysdev_store_int(struct sys_device *sysdev, | ||
509 | struct sysdev_attribute *attr, | ||
510 | const char *buf, size_t size) | ||
511 | { | ||
512 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
513 | char *end; | ||
514 | long new = simple_strtol(buf, &end, 0); | ||
515 | if (end == buf || new > INT_MAX || new < INT_MIN) | ||
516 | return -EINVAL; | ||
517 | *(int *)(ea->var) = new; | ||
518 | return end - buf; | ||
519 | } | ||
520 | EXPORT_SYMBOL_GPL(sysdev_store_int); | ||
521 | |||
522 | ssize_t sysdev_show_int(struct sys_device *sysdev, | ||
523 | struct sysdev_attribute *attr, | ||
524 | char *buf) | ||
525 | { | ||
526 | struct sysdev_ext_attribute *ea = to_ext_attr(attr); | ||
527 | return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); | ||
528 | } | ||
529 | EXPORT_SYMBOL_GPL(sysdev_show_int); | ||
530 | |||
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 3f6d9b0a6abe..199cd97e32e6 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -34,7 +34,8 @@ | |||
34 | static SYSDEV_ATTR(_name, 0444, show_##_name, NULL) | 34 | static SYSDEV_ATTR(_name, 0444, show_##_name, NULL) |
35 | 35 | ||
36 | #define define_id_show_func(name) \ | 36 | #define define_id_show_func(name) \ |
37 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | 37 | static ssize_t show_##name(struct sys_device *dev, \ |
38 | struct sysdev_attribute *attr, char *buf) \ | ||
38 | { \ | 39 | { \ |
39 | unsigned int cpu = dev->id; \ | 40 | unsigned int cpu = dev->id; \ |
40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | 41 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ |
@@ -59,14 +60,17 @@ static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf) | |||
59 | 60 | ||
60 | #ifdef arch_provides_topology_pointers | 61 | #ifdef arch_provides_topology_pointers |
61 | #define define_siblings_show_map(name) \ | 62 | #define define_siblings_show_map(name) \ |
62 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | 63 | static ssize_t show_##name(struct sys_device *dev, \ |
64 | struct sysdev_attribute *attr, char *buf) \ | ||
63 | { \ | 65 | { \ |
64 | unsigned int cpu = dev->id; \ | 66 | unsigned int cpu = dev->id; \ |
65 | return show_cpumap(0, &(topology_##name(cpu)), buf); \ | 67 | return show_cpumap(0, &(topology_##name(cpu)), buf); \ |
66 | } | 68 | } |
67 | 69 | ||
68 | #define define_siblings_show_list(name) \ | 70 | #define define_siblings_show_list(name) \ |
69 | static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ | 71 | static ssize_t show_##name##_list(struct sys_device *dev, \ |
72 | struct sysdev_attribute *attr, \ | ||
73 | char *buf) \ | ||
70 | { \ | 74 | { \ |
71 | unsigned int cpu = dev->id; \ | 75 | unsigned int cpu = dev->id; \ |
72 | return show_cpumap(1, &(topology_##name(cpu)), buf); \ | 76 | return show_cpumap(1, &(topology_##name(cpu)), buf); \ |
@@ -74,7 +78,8 @@ static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ | |||
74 | 78 | ||
75 | #else | 79 | #else |
76 | #define define_siblings_show_map(name) \ | 80 | #define define_siblings_show_map(name) \ |
77 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | 81 | static ssize_t show_##name(struct sys_device *dev, \ |
82 | struct sysdev_attribute *attr, char *buf) \ | ||
78 | { \ | 83 | { \ |
79 | unsigned int cpu = dev->id; \ | 84 | unsigned int cpu = dev->id; \ |
80 | cpumask_t mask = topology_##name(cpu); \ | 85 | cpumask_t mask = topology_##name(cpu); \ |
@@ -82,7 +87,9 @@ static ssize_t show_##name(struct sys_device *dev, char *buf) \ | |||
82 | } | 87 | } |
83 | 88 | ||
84 | #define define_siblings_show_list(name) \ | 89 | #define define_siblings_show_list(name) \ |
85 | static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ | 90 | static ssize_t show_##name##_list(struct sys_device *dev, \ |
91 | struct sysdev_attribute *attr, \ | ||
92 | char *buf) \ | ||
86 | { \ | 93 | { \ |
87 | unsigned int cpu = dev->id; \ | 94 | unsigned int cpu = dev->id; \ |
88 | cpumask_t mask = topology_##name(cpu); \ | 95 | cpumask_t mask = topology_##name(cpu); \ |