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 e38dfed41d80..20537d507909 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); \ |
