diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 107 |
1 files changed, 39 insertions, 68 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 8856d74545d9..c7b0925f627a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/async.h> | 26 | #include <linux/async.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
29 | #include <linux/sysfs.h> | ||
29 | 30 | ||
30 | #include "base.h" | 31 | #include "base.h" |
31 | #include "power/power.h" | 32 | #include "power/power.h" |
@@ -36,9 +37,9 @@ long sysfs_deprecated = 1; | |||
36 | #else | 37 | #else |
37 | long sysfs_deprecated = 0; | 38 | long sysfs_deprecated = 0; |
38 | #endif | 39 | #endif |
39 | static __init int sysfs_deprecated_setup(char *arg) | 40 | static int __init sysfs_deprecated_setup(char *arg) |
40 | { | 41 | { |
41 | return strict_strtol(arg, 10, &sysfs_deprecated); | 42 | return kstrtol(arg, 10, &sysfs_deprecated); |
42 | } | 43 | } |
43 | early_param("sysfs.deprecated", sysfs_deprecated_setup); | 44 | early_param("sysfs.deprecated", sysfs_deprecated_setup); |
44 | #endif | 45 | #endif |
@@ -345,7 +346,7 @@ static const struct kset_uevent_ops device_uevent_ops = { | |||
345 | .uevent = dev_uevent, | 346 | .uevent = dev_uevent, |
346 | }; | 347 | }; |
347 | 348 | ||
348 | static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, | 349 | static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, |
349 | char *buf) | 350 | char *buf) |
350 | { | 351 | { |
351 | struct kobject *top_kobj; | 352 | struct kobject *top_kobj; |
@@ -388,7 +389,7 @@ out: | |||
388 | return count; | 389 | return count; |
389 | } | 390 | } |
390 | 391 | ||
391 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | 392 | static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, |
392 | const char *buf, size_t count) | 393 | const char *buf, size_t count) |
393 | { | 394 | { |
394 | enum kobject_action action; | 395 | enum kobject_action action; |
@@ -399,11 +400,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
399 | dev_err(dev, "uevent: unknown action-string\n"); | 400 | dev_err(dev, "uevent: unknown action-string\n"); |
400 | return count; | 401 | return count; |
401 | } | 402 | } |
403 | static DEVICE_ATTR_RW(uevent); | ||
402 | 404 | ||
403 | static struct device_attribute uevent_attr = | 405 | static ssize_t online_show(struct device *dev, struct device_attribute *attr, |
404 | __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); | ||
405 | |||
406 | static ssize_t show_online(struct device *dev, struct device_attribute *attr, | ||
407 | char *buf) | 406 | char *buf) |
408 | { | 407 | { |
409 | bool val; | 408 | bool val; |
@@ -414,7 +413,7 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr, | |||
414 | return sprintf(buf, "%u\n", val); | 413 | return sprintf(buf, "%u\n", val); |
415 | } | 414 | } |
416 | 415 | ||
417 | static ssize_t store_online(struct device *dev, struct device_attribute *attr, | 416 | static ssize_t online_store(struct device *dev, struct device_attribute *attr, |
418 | const char *buf, size_t count) | 417 | const char *buf, size_t count) |
419 | { | 418 | { |
420 | bool val; | 419 | bool val; |
@@ -429,9 +428,7 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr, | |||
429 | unlock_device_hotplug(); | 428 | unlock_device_hotplug(); |
430 | return ret < 0 ? ret : count; | 429 | return ret < 0 ? ret : count; |
431 | } | 430 | } |
432 | 431 | static DEVICE_ATTR_RW(online); | |
433 | static struct device_attribute online_attr = | ||
434 | __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online); | ||
435 | 432 | ||
436 | static int device_add_attributes(struct device *dev, | 433 | static int device_add_attributes(struct device *dev, |
437 | struct device_attribute *attrs) | 434 | struct device_attribute *attrs) |
@@ -440,7 +437,7 @@ static int device_add_attributes(struct device *dev, | |||
440 | int i; | 437 | int i; |
441 | 438 | ||
442 | if (attrs) { | 439 | if (attrs) { |
443 | for (i = 0; attr_name(attrs[i]); i++) { | 440 | for (i = 0; attrs[i].attr.name; i++) { |
444 | error = device_create_file(dev, &attrs[i]); | 441 | error = device_create_file(dev, &attrs[i]); |
445 | if (error) | 442 | if (error) |
446 | break; | 443 | break; |
@@ -458,7 +455,7 @@ static void device_remove_attributes(struct device *dev, | |||
458 | int i; | 455 | int i; |
459 | 456 | ||
460 | if (attrs) | 457 | if (attrs) |
461 | for (i = 0; attr_name(attrs[i]); i++) | 458 | for (i = 0; attrs[i].attr.name; i++) |
462 | device_remove_file(dev, &attrs[i]); | 459 | device_remove_file(dev, &attrs[i]); |
463 | } | 460 | } |
464 | 461 | ||
@@ -469,7 +466,7 @@ static int device_add_bin_attributes(struct device *dev, | |||
469 | int i; | 466 | int i; |
470 | 467 | ||
471 | if (attrs) { | 468 | if (attrs) { |
472 | for (i = 0; attr_name(attrs[i]); i++) { | 469 | for (i = 0; attrs[i].attr.name; i++) { |
473 | error = device_create_bin_file(dev, &attrs[i]); | 470 | error = device_create_bin_file(dev, &attrs[i]); |
474 | if (error) | 471 | if (error) |
475 | break; | 472 | break; |
@@ -487,38 +484,19 @@ static void device_remove_bin_attributes(struct device *dev, | |||
487 | int i; | 484 | int i; |
488 | 485 | ||
489 | if (attrs) | 486 | if (attrs) |
490 | for (i = 0; attr_name(attrs[i]); i++) | 487 | for (i = 0; attrs[i].attr.name; i++) |
491 | device_remove_bin_file(dev, &attrs[i]); | 488 | device_remove_bin_file(dev, &attrs[i]); |
492 | } | 489 | } |
493 | 490 | ||
494 | static int device_add_groups(struct device *dev, | 491 | int device_add_groups(struct device *dev, const struct attribute_group **groups) |
495 | const struct attribute_group **groups) | ||
496 | { | 492 | { |
497 | int error = 0; | 493 | return sysfs_create_groups(&dev->kobj, groups); |
498 | int i; | ||
499 | |||
500 | if (groups) { | ||
501 | for (i = 0; groups[i]; i++) { | ||
502 | error = sysfs_create_group(&dev->kobj, groups[i]); | ||
503 | if (error) { | ||
504 | while (--i >= 0) | ||
505 | sysfs_remove_group(&dev->kobj, | ||
506 | groups[i]); | ||
507 | break; | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | return error; | ||
512 | } | 494 | } |
513 | 495 | ||
514 | static void device_remove_groups(struct device *dev, | 496 | void device_remove_groups(struct device *dev, |
515 | const struct attribute_group **groups) | 497 | const struct attribute_group **groups) |
516 | { | 498 | { |
517 | int i; | 499 | sysfs_remove_groups(&dev->kobj, groups); |
518 | |||
519 | if (groups) | ||
520 | for (i = 0; groups[i]; i++) | ||
521 | sysfs_remove_group(&dev->kobj, groups[i]); | ||
522 | } | 500 | } |
523 | 501 | ||
524 | static int device_add_attrs(struct device *dev) | 502 | static int device_add_attrs(struct device *dev) |
@@ -550,7 +528,7 @@ static int device_add_attrs(struct device *dev) | |||
550 | goto err_remove_type_groups; | 528 | goto err_remove_type_groups; |
551 | 529 | ||
552 | if (device_supports_offline(dev) && !dev->offline_disabled) { | 530 | if (device_supports_offline(dev) && !dev->offline_disabled) { |
553 | error = device_create_file(dev, &online_attr); | 531 | error = device_create_file(dev, &dev_attr_online); |
554 | if (error) | 532 | if (error) |
555 | goto err_remove_type_groups; | 533 | goto err_remove_type_groups; |
556 | } | 534 | } |
@@ -578,7 +556,7 @@ static void device_remove_attrs(struct device *dev) | |||
578 | struct class *class = dev->class; | 556 | struct class *class = dev->class; |
579 | const struct device_type *type = dev->type; | 557 | const struct device_type *type = dev->type; |
580 | 558 | ||
581 | device_remove_file(dev, &online_attr); | 559 | device_remove_file(dev, &dev_attr_online); |
582 | device_remove_groups(dev, dev->groups); | 560 | device_remove_groups(dev, dev->groups); |
583 | 561 | ||
584 | if (type) | 562 | if (type) |
@@ -591,15 +569,12 @@ static void device_remove_attrs(struct device *dev) | |||
591 | } | 569 | } |
592 | } | 570 | } |
593 | 571 | ||
594 | 572 | static ssize_t dev_show(struct device *dev, struct device_attribute *attr, | |
595 | static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | ||
596 | char *buf) | 573 | char *buf) |
597 | { | 574 | { |
598 | return print_dev_t(buf, dev->devt); | 575 | return print_dev_t(buf, dev->devt); |
599 | } | 576 | } |
600 | 577 | static DEVICE_ATTR_RO(dev); | |
601 | static struct device_attribute devt_attr = | ||
602 | __ATTR(dev, S_IRUGO, show_dev, NULL); | ||
603 | 578 | ||
604 | /* /sys/devices/ */ | 579 | /* /sys/devices/ */ |
605 | struct kset *devices_kset; | 580 | struct kset *devices_kset; |
@@ -626,6 +601,7 @@ int device_create_file(struct device *dev, | |||
626 | 601 | ||
627 | return error; | 602 | return error; |
628 | } | 603 | } |
604 | EXPORT_SYMBOL_GPL(device_create_file); | ||
629 | 605 | ||
630 | /** | 606 | /** |
631 | * device_remove_file - remove sysfs attribute file. | 607 | * device_remove_file - remove sysfs attribute file. |
@@ -638,6 +614,7 @@ void device_remove_file(struct device *dev, | |||
638 | if (dev) | 614 | if (dev) |
639 | sysfs_remove_file(&dev->kobj, &attr->attr); | 615 | sysfs_remove_file(&dev->kobj, &attr->attr); |
640 | } | 616 | } |
617 | EXPORT_SYMBOL_GPL(device_remove_file); | ||
641 | 618 | ||
642 | /** | 619 | /** |
643 | * device_create_bin_file - create sysfs binary attribute file for device. | 620 | * device_create_bin_file - create sysfs binary attribute file for device. |
@@ -748,6 +725,7 @@ void device_initialize(struct device *dev) | |||
748 | device_pm_init(dev); | 725 | device_pm_init(dev); |
749 | set_dev_node(dev, -1); | 726 | set_dev_node(dev, -1); |
750 | } | 727 | } |
728 | EXPORT_SYMBOL_GPL(device_initialize); | ||
751 | 729 | ||
752 | struct kobject *virtual_device_parent(struct device *dev) | 730 | struct kobject *virtual_device_parent(struct device *dev) |
753 | { | 731 | { |
@@ -1100,12 +1078,12 @@ int device_add(struct device *dev) | |||
1100 | if (platform_notify) | 1078 | if (platform_notify) |
1101 | platform_notify(dev); | 1079 | platform_notify(dev); |
1102 | 1080 | ||
1103 | error = device_create_file(dev, &uevent_attr); | 1081 | error = device_create_file(dev, &dev_attr_uevent); |
1104 | if (error) | 1082 | if (error) |
1105 | goto attrError; | 1083 | goto attrError; |
1106 | 1084 | ||
1107 | if (MAJOR(dev->devt)) { | 1085 | if (MAJOR(dev->devt)) { |
1108 | error = device_create_file(dev, &devt_attr); | 1086 | error = device_create_file(dev, &dev_attr_dev); |
1109 | if (error) | 1087 | if (error) |
1110 | goto ueventattrError; | 1088 | goto ueventattrError; |
1111 | 1089 | ||
@@ -1172,9 +1150,9 @@ done: | |||
1172 | device_remove_sys_dev_entry(dev); | 1150 | device_remove_sys_dev_entry(dev); |
1173 | devtattrError: | 1151 | devtattrError: |
1174 | if (MAJOR(dev->devt)) | 1152 | if (MAJOR(dev->devt)) |
1175 | device_remove_file(dev, &devt_attr); | 1153 | device_remove_file(dev, &dev_attr_dev); |
1176 | ueventattrError: | 1154 | ueventattrError: |
1177 | device_remove_file(dev, &uevent_attr); | 1155 | device_remove_file(dev, &dev_attr_uevent); |
1178 | attrError: | 1156 | attrError: |
1179 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 1157 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
1180 | kobject_del(&dev->kobj); | 1158 | kobject_del(&dev->kobj); |
@@ -1187,6 +1165,7 @@ name_error: | |||
1187 | dev->p = NULL; | 1165 | dev->p = NULL; |
1188 | goto done; | 1166 | goto done; |
1189 | } | 1167 | } |
1168 | EXPORT_SYMBOL_GPL(device_add); | ||
1190 | 1169 | ||
1191 | /** | 1170 | /** |
1192 | * device_register - register a device with the system. | 1171 | * device_register - register a device with the system. |
@@ -1211,6 +1190,7 @@ int device_register(struct device *dev) | |||
1211 | device_initialize(dev); | 1190 | device_initialize(dev); |
1212 | return device_add(dev); | 1191 | return device_add(dev); |
1213 | } | 1192 | } |
1193 | EXPORT_SYMBOL_GPL(device_register); | ||
1214 | 1194 | ||
1215 | /** | 1195 | /** |
1216 | * get_device - increment reference count for device. | 1196 | * get_device - increment reference count for device. |
@@ -1224,6 +1204,7 @@ struct device *get_device(struct device *dev) | |||
1224 | { | 1204 | { |
1225 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; | 1205 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; |
1226 | } | 1206 | } |
1207 | EXPORT_SYMBOL_GPL(get_device); | ||
1227 | 1208 | ||
1228 | /** | 1209 | /** |
1229 | * put_device - decrement reference count. | 1210 | * put_device - decrement reference count. |
@@ -1235,6 +1216,7 @@ void put_device(struct device *dev) | |||
1235 | if (dev) | 1216 | if (dev) |
1236 | kobject_put(&dev->kobj); | 1217 | kobject_put(&dev->kobj); |
1237 | } | 1218 | } |
1219 | EXPORT_SYMBOL_GPL(put_device); | ||
1238 | 1220 | ||
1239 | /** | 1221 | /** |
1240 | * device_del - delete device from system. | 1222 | * device_del - delete device from system. |
@@ -1266,7 +1248,7 @@ void device_del(struct device *dev) | |||
1266 | if (MAJOR(dev->devt)) { | 1248 | if (MAJOR(dev->devt)) { |
1267 | devtmpfs_delete_node(dev); | 1249 | devtmpfs_delete_node(dev); |
1268 | device_remove_sys_dev_entry(dev); | 1250 | device_remove_sys_dev_entry(dev); |
1269 | device_remove_file(dev, &devt_attr); | 1251 | device_remove_file(dev, &dev_attr_dev); |
1270 | } | 1252 | } |
1271 | if (dev->class) { | 1253 | if (dev->class) { |
1272 | device_remove_class_symlinks(dev); | 1254 | device_remove_class_symlinks(dev); |
@@ -1281,7 +1263,7 @@ void device_del(struct device *dev) | |||
1281 | klist_del(&dev->knode_class); | 1263 | klist_del(&dev->knode_class); |
1282 | mutex_unlock(&dev->class->p->mutex); | 1264 | mutex_unlock(&dev->class->p->mutex); |
1283 | } | 1265 | } |
1284 | device_remove_file(dev, &uevent_attr); | 1266 | device_remove_file(dev, &dev_attr_uevent); |
1285 | device_remove_attrs(dev); | 1267 | device_remove_attrs(dev); |
1286 | bus_remove_device(dev); | 1268 | bus_remove_device(dev); |
1287 | device_pm_remove(dev); | 1269 | device_pm_remove(dev); |
@@ -1297,6 +1279,7 @@ void device_del(struct device *dev) | |||
1297 | kobject_del(&dev->kobj); | 1279 | kobject_del(&dev->kobj); |
1298 | put_device(parent); | 1280 | put_device(parent); |
1299 | } | 1281 | } |
1282 | EXPORT_SYMBOL_GPL(device_del); | ||
1300 | 1283 | ||
1301 | /** | 1284 | /** |
1302 | * device_unregister - unregister device from system. | 1285 | * device_unregister - unregister device from system. |
@@ -1315,6 +1298,7 @@ void device_unregister(struct device *dev) | |||
1315 | device_del(dev); | 1298 | device_del(dev); |
1316 | put_device(dev); | 1299 | put_device(dev); |
1317 | } | 1300 | } |
1301 | EXPORT_SYMBOL_GPL(device_unregister); | ||
1318 | 1302 | ||
1319 | static struct device *next_device(struct klist_iter *i) | 1303 | static struct device *next_device(struct klist_iter *i) |
1320 | { | 1304 | { |
@@ -1403,6 +1387,7 @@ int device_for_each_child(struct device *parent, void *data, | |||
1403 | klist_iter_exit(&i); | 1387 | klist_iter_exit(&i); |
1404 | return error; | 1388 | return error; |
1405 | } | 1389 | } |
1390 | EXPORT_SYMBOL_GPL(device_for_each_child); | ||
1406 | 1391 | ||
1407 | /** | 1392 | /** |
1408 | * device_find_child - device iterator for locating a particular device. | 1393 | * device_find_child - device iterator for locating a particular device. |
@@ -1437,6 +1422,7 @@ struct device *device_find_child(struct device *parent, void *data, | |||
1437 | klist_iter_exit(&i); | 1422 | klist_iter_exit(&i); |
1438 | return child; | 1423 | return child; |
1439 | } | 1424 | } |
1425 | EXPORT_SYMBOL_GPL(device_find_child); | ||
1440 | 1426 | ||
1441 | int __init devices_init(void) | 1427 | int __init devices_init(void) |
1442 | { | 1428 | { |
@@ -1464,21 +1450,6 @@ int __init devices_init(void) | |||
1464 | return -ENOMEM; | 1450 | return -ENOMEM; |
1465 | } | 1451 | } |
1466 | 1452 | ||
1467 | EXPORT_SYMBOL_GPL(device_for_each_child); | ||
1468 | EXPORT_SYMBOL_GPL(device_find_child); | ||
1469 | |||
1470 | EXPORT_SYMBOL_GPL(device_initialize); | ||
1471 | EXPORT_SYMBOL_GPL(device_add); | ||
1472 | EXPORT_SYMBOL_GPL(device_register); | ||
1473 | |||
1474 | EXPORT_SYMBOL_GPL(device_del); | ||
1475 | EXPORT_SYMBOL_GPL(device_unregister); | ||
1476 | EXPORT_SYMBOL_GPL(get_device); | ||
1477 | EXPORT_SYMBOL_GPL(put_device); | ||
1478 | |||
1479 | EXPORT_SYMBOL_GPL(device_create_file); | ||
1480 | EXPORT_SYMBOL_GPL(device_remove_file); | ||
1481 | |||
1482 | static DEFINE_MUTEX(device_hotplug_lock); | 1453 | static DEFINE_MUTEX(device_hotplug_lock); |
1483 | 1454 | ||
1484 | void lock_device_hotplug(void) | 1455 | void lock_device_hotplug(void) |