diff options
-rw-r--r-- | drivers/base/base.h | 12 | ||||
-rw-r--r-- | drivers/base/bus.c | 293 | ||||
-rw-r--r-- | drivers/base/class.c | 14 | ||||
-rw-r--r-- | drivers/base/core.c | 85 | ||||
-rw-r--r-- | drivers/base/init.c | 1 | ||||
-rw-r--r-- | drivers/base/sys.c | 10 | ||||
-rw-r--r-- | include/linux/device.h | 78 |
7 files changed, 431 insertions, 62 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index 21c1b96c34c6..7a6ae4228761 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -4,7 +4,9 @@ | |||
4 | * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure. | 4 | * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure. |
5 | * | 5 | * |
6 | * @subsys - the struct kset that defines this subsystem | 6 | * @subsys - the struct kset that defines this subsystem |
7 | * @devices_kset - the list of devices associated | 7 | * @devices_kset - the subsystem's 'devices' directory |
8 | * @interfaces - list of subsystem interfaces associated | ||
9 | * @mutex - protect the devices, and interfaces lists. | ||
8 | * | 10 | * |
9 | * @drivers_kset - the list of drivers associated | 11 | * @drivers_kset - the list of drivers associated |
10 | * @klist_devices - the klist to iterate over the @devices_kset | 12 | * @klist_devices - the klist to iterate over the @devices_kset |
@@ -14,10 +16,8 @@ | |||
14 | * @bus - pointer back to the struct bus_type that this structure is associated | 16 | * @bus - pointer back to the struct bus_type that this structure is associated |
15 | * with. | 17 | * with. |
16 | * | 18 | * |
17 | * @class_interfaces - list of class_interfaces associated | ||
18 | * @glue_dirs - "glue" directory to put in-between the parent device to | 19 | * @glue_dirs - "glue" directory to put in-between the parent device to |
19 | * avoid namespace conflicts | 20 | * avoid namespace conflicts |
20 | * @class_mutex - mutex to protect the children, devices, and interfaces lists. | ||
21 | * @class - pointer back to the struct class that this structure is associated | 21 | * @class - pointer back to the struct class that this structure is associated |
22 | * with. | 22 | * with. |
23 | * | 23 | * |
@@ -28,6 +28,8 @@ | |||
28 | struct subsys_private { | 28 | struct subsys_private { |
29 | struct kset subsys; | 29 | struct kset subsys; |
30 | struct kset *devices_kset; | 30 | struct kset *devices_kset; |
31 | struct list_head interfaces; | ||
32 | struct mutex mutex; | ||
31 | 33 | ||
32 | struct kset *drivers_kset; | 34 | struct kset *drivers_kset; |
33 | struct klist klist_devices; | 35 | struct klist klist_devices; |
@@ -36,9 +38,7 @@ struct subsys_private { | |||
36 | unsigned int drivers_autoprobe:1; | 38 | unsigned int drivers_autoprobe:1; |
37 | struct bus_type *bus; | 39 | struct bus_type *bus; |
38 | 40 | ||
39 | struct list_head class_interfaces; | ||
40 | struct kset glue_dirs; | 41 | struct kset glue_dirs; |
41 | struct mutex class_mutex; | ||
42 | struct class *class; | 42 | struct class *class; |
43 | }; | 43 | }; |
44 | #define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj) | 44 | #define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj) |
@@ -94,7 +94,6 @@ extern int hypervisor_init(void); | |||
94 | static inline int hypervisor_init(void) { return 0; } | 94 | static inline int hypervisor_init(void) { return 0; } |
95 | #endif | 95 | #endif |
96 | extern int platform_bus_init(void); | 96 | extern int platform_bus_init(void); |
97 | extern int system_bus_init(void); | ||
98 | extern int cpu_dev_init(void); | 97 | extern int cpu_dev_init(void); |
99 | 98 | ||
100 | extern int bus_add_device(struct device *dev); | 99 | extern int bus_add_device(struct device *dev); |
@@ -116,6 +115,7 @@ extern char *make_class_name(const char *name, struct kobject *kobj); | |||
116 | 115 | ||
117 | extern int devres_release_all(struct device *dev); | 116 | extern int devres_release_all(struct device *dev); |
118 | 117 | ||
118 | /* /sys/devices directory */ | ||
119 | extern struct kset *devices_kset; | 119 | extern struct kset *devices_kset; |
120 | 120 | ||
121 | #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) | 121 | #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 000e7b2006f8..99dc5921e1dd 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -16,9 +16,14 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/mutex.h> | ||
19 | #include "base.h" | 20 | #include "base.h" |
20 | #include "power/power.h" | 21 | #include "power/power.h" |
21 | 22 | ||
23 | /* /sys/devices/system */ | ||
24 | /* FIXME: make static after drivers/base/sys.c is deleted */ | ||
25 | struct kset *system_kset; | ||
26 | |||
22 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 27 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
23 | 28 | ||
24 | /* | 29 | /* |
@@ -360,6 +365,47 @@ struct device *bus_find_device_by_name(struct bus_type *bus, | |||
360 | } | 365 | } |
361 | EXPORT_SYMBOL_GPL(bus_find_device_by_name); | 366 | EXPORT_SYMBOL_GPL(bus_find_device_by_name); |
362 | 367 | ||
368 | /** | ||
369 | * subsys_find_device_by_id - find a device with a specific enumeration number | ||
370 | * @subsys: subsystem | ||
371 | * @id: index 'id' in struct device | ||
372 | * @hint: device to check first | ||
373 | * | ||
374 | * Check the hint's next object and if it is a match return it directly, | ||
375 | * otherwise, fall back to a full list search. Either way a reference for | ||
376 | * the returned object is taken. | ||
377 | */ | ||
378 | struct device *subsys_find_device_by_id(struct bus_type *subsys, unsigned int id, | ||
379 | struct device *hint) | ||
380 | { | ||
381 | struct klist_iter i; | ||
382 | struct device *dev; | ||
383 | |||
384 | if (!subsys) | ||
385 | return NULL; | ||
386 | |||
387 | if (hint) { | ||
388 | klist_iter_init_node(&subsys->p->klist_devices, &i, &hint->p->knode_bus); | ||
389 | dev = next_device(&i); | ||
390 | if (dev && dev->id == id && get_device(dev)) { | ||
391 | klist_iter_exit(&i); | ||
392 | return dev; | ||
393 | } | ||
394 | klist_iter_exit(&i); | ||
395 | } | ||
396 | |||
397 | klist_iter_init_node(&subsys->p->klist_devices, &i, NULL); | ||
398 | while ((dev = next_device(&i))) { | ||
399 | if (dev->id == id && get_device(dev)) { | ||
400 | klist_iter_exit(&i); | ||
401 | return dev; | ||
402 | } | ||
403 | } | ||
404 | klist_iter_exit(&i); | ||
405 | return NULL; | ||
406 | } | ||
407 | EXPORT_SYMBOL_GPL(subsys_find_device_by_id); | ||
408 | |||
363 | static struct device_driver *next_driver(struct klist_iter *i) | 409 | static struct device_driver *next_driver(struct klist_iter *i) |
364 | { | 410 | { |
365 | struct klist_node *n = klist_next(i); | 411 | struct klist_node *n = klist_next(i); |
@@ -487,38 +533,59 @@ out_put: | |||
487 | void bus_probe_device(struct device *dev) | 533 | void bus_probe_device(struct device *dev) |
488 | { | 534 | { |
489 | struct bus_type *bus = dev->bus; | 535 | struct bus_type *bus = dev->bus; |
536 | struct subsys_interface *sif; | ||
490 | int ret; | 537 | int ret; |
491 | 538 | ||
492 | if (bus && bus->p->drivers_autoprobe) { | 539 | if (!bus) |
540 | return; | ||
541 | |||
542 | if (bus->p->drivers_autoprobe) { | ||
493 | ret = device_attach(dev); | 543 | ret = device_attach(dev); |
494 | WARN_ON(ret < 0); | 544 | WARN_ON(ret < 0); |
495 | } | 545 | } |
546 | |||
547 | mutex_lock(&bus->p->mutex); | ||
548 | list_for_each_entry(sif, &bus->p->interfaces, node) | ||
549 | if (sif->add_dev) | ||
550 | sif->add_dev(dev, sif); | ||
551 | mutex_unlock(&bus->p->mutex); | ||
496 | } | 552 | } |
497 | 553 | ||
498 | /** | 554 | /** |
499 | * bus_remove_device - remove device from bus | 555 | * bus_remove_device - remove device from bus |
500 | * @dev: device to be removed | 556 | * @dev: device to be removed |
501 | * | 557 | * |
502 | * - Remove symlink from bus's directory. | 558 | * - Remove device from all interfaces. |
559 | * - Remove symlink from bus' directory. | ||
503 | * - Delete device from bus's list. | 560 | * - Delete device from bus's list. |
504 | * - Detach from its driver. | 561 | * - Detach from its driver. |
505 | * - Drop reference taken in bus_add_device(). | 562 | * - Drop reference taken in bus_add_device(). |
506 | */ | 563 | */ |
507 | void bus_remove_device(struct device *dev) | 564 | void bus_remove_device(struct device *dev) |
508 | { | 565 | { |
509 | if (dev->bus) { | 566 | struct bus_type *bus = dev->bus; |
510 | sysfs_remove_link(&dev->kobj, "subsystem"); | 567 | struct subsys_interface *sif; |
511 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 568 | |
512 | dev_name(dev)); | 569 | if (!bus) |
513 | device_remove_attrs(dev->bus, dev); | 570 | return; |
514 | if (klist_node_attached(&dev->p->knode_bus)) | 571 | |
515 | klist_del(&dev->p->knode_bus); | 572 | mutex_lock(&bus->p->mutex); |
516 | 573 | list_for_each_entry(sif, &bus->p->interfaces, node) | |
517 | pr_debug("bus: '%s': remove device %s\n", | 574 | if (sif->remove_dev) |
518 | dev->bus->name, dev_name(dev)); | 575 | sif->remove_dev(dev, sif); |
519 | device_release_driver(dev); | 576 | mutex_unlock(&bus->p->mutex); |
520 | bus_put(dev->bus); | 577 | |
521 | } | 578 | sysfs_remove_link(&dev->kobj, "subsystem"); |
579 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | ||
580 | dev_name(dev)); | ||
581 | device_remove_attrs(dev->bus, dev); | ||
582 | if (klist_node_attached(&dev->p->knode_bus)) | ||
583 | klist_del(&dev->p->knode_bus); | ||
584 | |||
585 | pr_debug("bus: '%s': remove device %s\n", | ||
586 | dev->bus->name, dev_name(dev)); | ||
587 | device_release_driver(dev); | ||
588 | bus_put(dev->bus); | ||
522 | } | 589 | } |
523 | 590 | ||
524 | static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) | 591 | static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) |
@@ -847,14 +914,14 @@ static ssize_t bus_uevent_store(struct bus_type *bus, | |||
847 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | 914 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); |
848 | 915 | ||
849 | /** | 916 | /** |
850 | * bus_register - register a bus with the system. | 917 | * __bus_register - register a driver-core subsystem |
851 | * @bus: bus. | 918 | * @bus: bus. |
852 | * | 919 | * |
853 | * Once we have that, we registered the bus with the kobject | 920 | * Once we have that, we registered the bus with the kobject |
854 | * infrastructure, then register the children subsystems it has: | 921 | * infrastructure, then register the children subsystems it has: |
855 | * the devices and drivers that belong to the bus. | 922 | * the devices and drivers that belong to the subsystem. |
856 | */ | 923 | */ |
857 | int bus_register(struct bus_type *bus) | 924 | int __bus_register(struct bus_type *bus, struct lock_class_key *key) |
858 | { | 925 | { |
859 | int retval; | 926 | int retval; |
860 | struct subsys_private *priv; | 927 | struct subsys_private *priv; |
@@ -898,6 +965,8 @@ int bus_register(struct bus_type *bus) | |||
898 | goto bus_drivers_fail; | 965 | goto bus_drivers_fail; |
899 | } | 966 | } |
900 | 967 | ||
968 | INIT_LIST_HEAD(&priv->interfaces); | ||
969 | __mutex_init(&priv->mutex, "subsys mutex", key); | ||
901 | klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); | 970 | klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); |
902 | klist_init(&priv->klist_drivers, NULL, NULL); | 971 | klist_init(&priv->klist_drivers, NULL, NULL); |
903 | 972 | ||
@@ -927,7 +996,7 @@ out: | |||
927 | bus->p = NULL; | 996 | bus->p = NULL; |
928 | return retval; | 997 | return retval; |
929 | } | 998 | } |
930 | EXPORT_SYMBOL_GPL(bus_register); | 999 | EXPORT_SYMBOL_GPL(__bus_register); |
931 | 1000 | ||
932 | /** | 1001 | /** |
933 | * bus_unregister - remove a bus from the system | 1002 | * bus_unregister - remove a bus from the system |
@@ -939,6 +1008,8 @@ EXPORT_SYMBOL_GPL(bus_register); | |||
939 | void bus_unregister(struct bus_type *bus) | 1008 | void bus_unregister(struct bus_type *bus) |
940 | { | 1009 | { |
941 | pr_debug("bus: '%s': unregistering\n", bus->name); | 1010 | pr_debug("bus: '%s': unregistering\n", bus->name); |
1011 | if (bus->dev_root) | ||
1012 | device_unregister(bus->dev_root); | ||
942 | bus_remove_attrs(bus); | 1013 | bus_remove_attrs(bus); |
943 | remove_probe_files(bus); | 1014 | remove_probe_files(bus); |
944 | kset_unregister(bus->p->drivers_kset); | 1015 | kset_unregister(bus->p->drivers_kset); |
@@ -1028,10 +1099,194 @@ void bus_sort_breadthfirst(struct bus_type *bus, | |||
1028 | } | 1099 | } |
1029 | EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); | 1100 | EXPORT_SYMBOL_GPL(bus_sort_breadthfirst); |
1030 | 1101 | ||
1102 | /** | ||
1103 | * subsys_dev_iter_init - initialize subsys device iterator | ||
1104 | * @iter: subsys iterator to initialize | ||
1105 | * @subsys: the subsys we wanna iterate over | ||
1106 | * @start: the device to start iterating from, if any | ||
1107 | * @type: device_type of the devices to iterate over, NULL for all | ||
1108 | * | ||
1109 | * Initialize subsys iterator @iter such that it iterates over devices | ||
1110 | * of @subsys. If @start is set, the list iteration will start there, | ||
1111 | * otherwise if it is NULL, the iteration starts at the beginning of | ||
1112 | * the list. | ||
1113 | */ | ||
1114 | void subsys_dev_iter_init(struct subsys_dev_iter *iter, struct bus_type *subsys, | ||
1115 | struct device *start, const struct device_type *type) | ||
1116 | { | ||
1117 | struct klist_node *start_knode = NULL; | ||
1118 | |||
1119 | if (start) | ||
1120 | start_knode = &start->p->knode_bus; | ||
1121 | klist_iter_init_node(&subsys->p->klist_devices, &iter->ki, start_knode); | ||
1122 | iter->type = type; | ||
1123 | } | ||
1124 | EXPORT_SYMBOL_GPL(subsys_dev_iter_init); | ||
1125 | |||
1126 | /** | ||
1127 | * subsys_dev_iter_next - iterate to the next device | ||
1128 | * @iter: subsys iterator to proceed | ||
1129 | * | ||
1130 | * Proceed @iter to the next device and return it. Returns NULL if | ||
1131 | * iteration is complete. | ||
1132 | * | ||
1133 | * The returned device is referenced and won't be released till | ||
1134 | * iterator is proceed to the next device or exited. The caller is | ||
1135 | * free to do whatever it wants to do with the device including | ||
1136 | * calling back into subsys code. | ||
1137 | */ | ||
1138 | struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter) | ||
1139 | { | ||
1140 | struct klist_node *knode; | ||
1141 | struct device *dev; | ||
1142 | |||
1143 | for (;;) { | ||
1144 | knode = klist_next(&iter->ki); | ||
1145 | if (!knode) | ||
1146 | return NULL; | ||
1147 | dev = container_of(knode, struct device_private, knode_bus)->device; | ||
1148 | if (!iter->type || iter->type == dev->type) | ||
1149 | return dev; | ||
1150 | } | ||
1151 | } | ||
1152 | EXPORT_SYMBOL_GPL(subsys_dev_iter_next); | ||
1153 | |||
1154 | /** | ||
1155 | * subsys_dev_iter_exit - finish iteration | ||
1156 | * @iter: subsys iterator to finish | ||
1157 | * | ||
1158 | * Finish an iteration. Always call this function after iteration is | ||
1159 | * complete whether the iteration ran till the end or not. | ||
1160 | */ | ||
1161 | void subsys_dev_iter_exit(struct subsys_dev_iter *iter) | ||
1162 | { | ||
1163 | klist_iter_exit(&iter->ki); | ||
1164 | } | ||
1165 | EXPORT_SYMBOL_GPL(subsys_dev_iter_exit); | ||
1166 | |||
1167 | int subsys_interface_register(struct subsys_interface *sif) | ||
1168 | { | ||
1169 | struct bus_type *subsys; | ||
1170 | struct subsys_dev_iter iter; | ||
1171 | struct device *dev; | ||
1172 | |||
1173 | if (!sif || !sif->subsys) | ||
1174 | return -ENODEV; | ||
1175 | |||
1176 | subsys = bus_get(sif->subsys); | ||
1177 | if (!subsys) | ||
1178 | return -EINVAL; | ||
1179 | |||
1180 | mutex_lock(&subsys->p->mutex); | ||
1181 | list_add_tail(&sif->node, &subsys->p->interfaces); | ||
1182 | if (sif->add_dev) { | ||
1183 | subsys_dev_iter_init(&iter, subsys, NULL, NULL); | ||
1184 | while ((dev = subsys_dev_iter_next(&iter))) | ||
1185 | sif->add_dev(dev, sif); | ||
1186 | subsys_dev_iter_exit(&iter); | ||
1187 | } | ||
1188 | mutex_unlock(&subsys->p->mutex); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | EXPORT_SYMBOL_GPL(subsys_interface_register); | ||
1193 | |||
1194 | void subsys_interface_unregister(struct subsys_interface *sif) | ||
1195 | { | ||
1196 | struct bus_type *subsys = sif->subsys; | ||
1197 | struct subsys_dev_iter iter; | ||
1198 | struct device *dev; | ||
1199 | |||
1200 | if (!sif) | ||
1201 | return; | ||
1202 | |||
1203 | mutex_lock(&subsys->p->mutex); | ||
1204 | list_del_init(&sif->node); | ||
1205 | if (sif->remove_dev) { | ||
1206 | subsys_dev_iter_init(&iter, subsys, NULL, NULL); | ||
1207 | while ((dev = subsys_dev_iter_next(&iter))) | ||
1208 | sif->remove_dev(dev, sif); | ||
1209 | subsys_dev_iter_exit(&iter); | ||
1210 | } | ||
1211 | mutex_unlock(&subsys->p->mutex); | ||
1212 | |||
1213 | bus_put(subsys); | ||
1214 | } | ||
1215 | EXPORT_SYMBOL_GPL(subsys_interface_unregister); | ||
1216 | |||
1217 | static void system_root_device_release(struct device *dev) | ||
1218 | { | ||
1219 | kfree(dev); | ||
1220 | } | ||
1221 | /** | ||
1222 | * subsys_system_register - register a subsystem at /sys/devices/system/ | ||
1223 | * @subsys - system subsystem | ||
1224 | * @groups - default attributes for the root device | ||
1225 | * | ||
1226 | * All 'system' subsystems have a /sys/devices/system/<name> root device | ||
1227 | * with the name of the subsystem. The root device can carry subsystem- | ||
1228 | * wide attributes. All registered devices are below this single root | ||
1229 | * device and are named after the subsystem with a simple enumeration | ||
1230 | * number appended. The registered devices are not explicitely named; | ||
1231 | * only 'id' in the device needs to be set. | ||
1232 | * | ||
1233 | * Do not use this interface for anything new, it exists for compatibility | ||
1234 | * with bad ideas only. New subsystems should use plain subsystems; and | ||
1235 | * add the subsystem-wide attributes should be added to the subsystem | ||
1236 | * directory itself and not some create fake root-device placed in | ||
1237 | * /sys/devices/system/<name>. | ||
1238 | */ | ||
1239 | int subsys_system_register(struct bus_type *subsys, | ||
1240 | const struct attribute_group **groups) | ||
1241 | { | ||
1242 | struct device *dev; | ||
1243 | int err; | ||
1244 | |||
1245 | err = bus_register(subsys); | ||
1246 | if (err < 0) | ||
1247 | return err; | ||
1248 | |||
1249 | dev = kzalloc(sizeof(struct device), GFP_KERNEL); | ||
1250 | if (!dev) { | ||
1251 | err = -ENOMEM; | ||
1252 | goto err_dev; | ||
1253 | } | ||
1254 | |||
1255 | err = dev_set_name(dev, "%s", subsys->name); | ||
1256 | if (err < 0) | ||
1257 | goto err_name; | ||
1258 | |||
1259 | dev->kobj.parent = &system_kset->kobj; | ||
1260 | dev->groups = groups; | ||
1261 | dev->release = system_root_device_release; | ||
1262 | |||
1263 | err = device_register(dev); | ||
1264 | if (err < 0) | ||
1265 | goto err_dev_reg; | ||
1266 | |||
1267 | subsys->dev_root = dev; | ||
1268 | return 0; | ||
1269 | |||
1270 | err_dev_reg: | ||
1271 | put_device(dev); | ||
1272 | dev = NULL; | ||
1273 | err_name: | ||
1274 | kfree(dev); | ||
1275 | err_dev: | ||
1276 | bus_unregister(subsys); | ||
1277 | return err; | ||
1278 | } | ||
1279 | EXPORT_SYMBOL_GPL(subsys_system_register); | ||
1280 | |||
1031 | int __init buses_init(void) | 1281 | int __init buses_init(void) |
1032 | { | 1282 | { |
1033 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); | 1283 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); |
1034 | if (!bus_kset) | 1284 | if (!bus_kset) |
1035 | return -ENOMEM; | 1285 | return -ENOMEM; |
1286 | |||
1287 | system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); | ||
1288 | if (!system_kset) | ||
1289 | return -ENOMEM; | ||
1290 | |||
1036 | return 0; | 1291 | return 0; |
1037 | } | 1292 | } |
diff --git a/drivers/base/class.c b/drivers/base/class.c index b80d91cc8c3a..03243d4002fd 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -184,9 +184,9 @@ int __class_register(struct class *cls, struct lock_class_key *key) | |||
184 | if (!cp) | 184 | if (!cp) |
185 | return -ENOMEM; | 185 | return -ENOMEM; |
186 | klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put); | 186 | klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put); |
187 | INIT_LIST_HEAD(&cp->class_interfaces); | 187 | INIT_LIST_HEAD(&cp->interfaces); |
188 | kset_init(&cp->glue_dirs); | 188 | kset_init(&cp->glue_dirs); |
189 | __mutex_init(&cp->class_mutex, "struct class mutex", key); | 189 | __mutex_init(&cp->mutex, "subsys mutex", key); |
190 | error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); | 190 | error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); |
191 | if (error) { | 191 | if (error) { |
192 | kfree(cp); | 192 | kfree(cp); |
@@ -460,15 +460,15 @@ int class_interface_register(struct class_interface *class_intf) | |||
460 | if (!parent) | 460 | if (!parent) |
461 | return -EINVAL; | 461 | return -EINVAL; |
462 | 462 | ||
463 | mutex_lock(&parent->p->class_mutex); | 463 | mutex_lock(&parent->p->mutex); |
464 | list_add_tail(&class_intf->node, &parent->p->class_interfaces); | 464 | list_add_tail(&class_intf->node, &parent->p->interfaces); |
465 | if (class_intf->add_dev) { | 465 | if (class_intf->add_dev) { |
466 | class_dev_iter_init(&iter, parent, NULL, NULL); | 466 | class_dev_iter_init(&iter, parent, NULL, NULL); |
467 | while ((dev = class_dev_iter_next(&iter))) | 467 | while ((dev = class_dev_iter_next(&iter))) |
468 | class_intf->add_dev(dev, class_intf); | 468 | class_intf->add_dev(dev, class_intf); |
469 | class_dev_iter_exit(&iter); | 469 | class_dev_iter_exit(&iter); |
470 | } | 470 | } |
471 | mutex_unlock(&parent->p->class_mutex); | 471 | mutex_unlock(&parent->p->mutex); |
472 | 472 | ||
473 | return 0; | 473 | return 0; |
474 | } | 474 | } |
@@ -482,7 +482,7 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
482 | if (!parent) | 482 | if (!parent) |
483 | return; | 483 | return; |
484 | 484 | ||
485 | mutex_lock(&parent->p->class_mutex); | 485 | mutex_lock(&parent->p->mutex); |
486 | list_del_init(&class_intf->node); | 486 | list_del_init(&class_intf->node); |
487 | if (class_intf->remove_dev) { | 487 | if (class_intf->remove_dev) { |
488 | class_dev_iter_init(&iter, parent, NULL, NULL); | 488 | class_dev_iter_init(&iter, parent, NULL, NULL); |
@@ -490,7 +490,7 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
490 | class_intf->remove_dev(dev, class_intf); | 490 | class_intf->remove_dev(dev, class_intf); |
491 | class_dev_iter_exit(&iter); | 491 | class_dev_iter_exit(&iter); |
492 | } | 492 | } |
493 | mutex_unlock(&parent->p->class_mutex); | 493 | mutex_unlock(&parent->p->mutex); |
494 | 494 | ||
495 | class_put(parent); | 495 | class_put(parent); |
496 | } | 496 | } |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 82c865452c70..a31ea193fba0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -117,6 +117,56 @@ static const struct sysfs_ops dev_sysfs_ops = { | |||
117 | .store = dev_attr_store, | 117 | .store = dev_attr_store, |
118 | }; | 118 | }; |
119 | 119 | ||
120 | #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr) | ||
121 | |||
122 | ssize_t device_store_ulong(struct device *dev, | ||
123 | struct device_attribute *attr, | ||
124 | const char *buf, size_t size) | ||
125 | { | ||
126 | struct dev_ext_attribute *ea = to_ext_attr(attr); | ||
127 | char *end; | ||
128 | unsigned long new = simple_strtoul(buf, &end, 0); | ||
129 | if (end == buf) | ||
130 | return -EINVAL; | ||
131 | *(unsigned long *)(ea->var) = new; | ||
132 | /* Always return full write size even if we didn't consume all */ | ||
133 | return size; | ||
134 | } | ||
135 | EXPORT_SYMBOL_GPL(device_store_ulong); | ||
136 | |||
137 | ssize_t device_show_ulong(struct device *dev, | ||
138 | struct device_attribute *attr, | ||
139 | char *buf) | ||
140 | { | ||
141 | struct dev_ext_attribute *ea = to_ext_attr(attr); | ||
142 | return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); | ||
143 | } | ||
144 | EXPORT_SYMBOL_GPL(device_show_ulong); | ||
145 | |||
146 | ssize_t device_store_int(struct device *dev, | ||
147 | struct device_attribute *attr, | ||
148 | const char *buf, size_t size) | ||
149 | { | ||
150 | struct dev_ext_attribute *ea = to_ext_attr(attr); | ||
151 | char *end; | ||
152 | long new = simple_strtol(buf, &end, 0); | ||
153 | if (end == buf || new > INT_MAX || new < INT_MIN) | ||
154 | return -EINVAL; | ||
155 | *(int *)(ea->var) = new; | ||
156 | /* Always return full write size even if we didn't consume all */ | ||
157 | return size; | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(device_store_int); | ||
160 | |||
161 | ssize_t device_show_int(struct device *dev, | ||
162 | struct device_attribute *attr, | ||
163 | char *buf) | ||
164 | { | ||
165 | struct dev_ext_attribute *ea = to_ext_attr(attr); | ||
166 | |||
167 | return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); | ||
168 | } | ||
169 | EXPORT_SYMBOL_GPL(device_show_int); | ||
120 | 170 | ||
121 | /** | 171 | /** |
122 | * device_release - free device structure. | 172 | * device_release - free device structure. |
@@ -463,7 +513,7 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | |||
463 | static struct device_attribute devt_attr = | 513 | static struct device_attribute devt_attr = |
464 | __ATTR(dev, S_IRUGO, show_dev, NULL); | 514 | __ATTR(dev, S_IRUGO, show_dev, NULL); |
465 | 515 | ||
466 | /* kset to create /sys/devices/ */ | 516 | /* /sys/devices/ */ |
467 | struct kset *devices_kset; | 517 | struct kset *devices_kset; |
468 | 518 | ||
469 | /** | 519 | /** |
@@ -710,6 +760,10 @@ static struct kobject *get_device_parent(struct device *dev, | |||
710 | return k; | 760 | return k; |
711 | } | 761 | } |
712 | 762 | ||
763 | /* subsystems can specify a default root directory for their devices */ | ||
764 | if (!parent && dev->bus && dev->bus->dev_root) | ||
765 | return &dev->bus->dev_root->kobj; | ||
766 | |||
713 | if (parent) | 767 | if (parent) |
714 | return &parent->kobj; | 768 | return &parent->kobj; |
715 | return NULL; | 769 | return NULL; |
@@ -730,14 +784,6 @@ static void cleanup_device_parent(struct device *dev) | |||
730 | cleanup_glue_dir(dev, dev->kobj.parent); | 784 | cleanup_glue_dir(dev, dev->kobj.parent); |
731 | } | 785 | } |
732 | 786 | ||
733 | static void setup_parent(struct device *dev, struct device *parent) | ||
734 | { | ||
735 | struct kobject *kobj; | ||
736 | kobj = get_device_parent(dev, parent); | ||
737 | if (kobj) | ||
738 | dev->kobj.parent = kobj; | ||
739 | } | ||
740 | |||
741 | static int device_add_class_symlinks(struct device *dev) | 787 | static int device_add_class_symlinks(struct device *dev) |
742 | { | 788 | { |
743 | int error; | 789 | int error; |
@@ -890,6 +936,7 @@ int device_private_init(struct device *dev) | |||
890 | int device_add(struct device *dev) | 936 | int device_add(struct device *dev) |
891 | { | 937 | { |
892 | struct device *parent = NULL; | 938 | struct device *parent = NULL; |
939 | struct kobject *kobj; | ||
893 | struct class_interface *class_intf; | 940 | struct class_interface *class_intf; |
894 | int error = -EINVAL; | 941 | int error = -EINVAL; |
895 | 942 | ||
@@ -913,6 +960,10 @@ int device_add(struct device *dev) | |||
913 | dev->init_name = NULL; | 960 | dev->init_name = NULL; |
914 | } | 961 | } |
915 | 962 | ||
963 | /* subsystems can specify simple device enumeration */ | ||
964 | if (!dev_name(dev) && dev->bus && dev->bus->dev_name) | ||
965 | dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); | ||
966 | |||
916 | if (!dev_name(dev)) { | 967 | if (!dev_name(dev)) { |
917 | error = -EINVAL; | 968 | error = -EINVAL; |
918 | goto name_error; | 969 | goto name_error; |
@@ -921,7 +972,9 @@ int device_add(struct device *dev) | |||
921 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 972 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
922 | 973 | ||
923 | parent = get_device(dev->parent); | 974 | parent = get_device(dev->parent); |
924 | setup_parent(dev, parent); | 975 | kobj = get_device_parent(dev, parent); |
976 | if (kobj) | ||
977 | dev->kobj.parent = kobj; | ||
925 | 978 | ||
926 | /* use parent numa_node */ | 979 | /* use parent numa_node */ |
927 | if (parent) | 980 | if (parent) |
@@ -981,17 +1034,17 @@ int device_add(struct device *dev) | |||
981 | &parent->p->klist_children); | 1034 | &parent->p->klist_children); |
982 | 1035 | ||
983 | if (dev->class) { | 1036 | if (dev->class) { |
984 | mutex_lock(&dev->class->p->class_mutex); | 1037 | mutex_lock(&dev->class->p->mutex); |
985 | /* tie the class to the device */ | 1038 | /* tie the class to the device */ |
986 | klist_add_tail(&dev->knode_class, | 1039 | klist_add_tail(&dev->knode_class, |
987 | &dev->class->p->klist_devices); | 1040 | &dev->class->p->klist_devices); |
988 | 1041 | ||
989 | /* notify any interfaces that the device is here */ | 1042 | /* notify any interfaces that the device is here */ |
990 | list_for_each_entry(class_intf, | 1043 | list_for_each_entry(class_intf, |
991 | &dev->class->p->class_interfaces, node) | 1044 | &dev->class->p->interfaces, node) |
992 | if (class_intf->add_dev) | 1045 | if (class_intf->add_dev) |
993 | class_intf->add_dev(dev, class_intf); | 1046 | class_intf->add_dev(dev, class_intf); |
994 | mutex_unlock(&dev->class->p->class_mutex); | 1047 | mutex_unlock(&dev->class->p->mutex); |
995 | } | 1048 | } |
996 | done: | 1049 | done: |
997 | put_device(dev); | 1050 | put_device(dev); |
@@ -1106,15 +1159,15 @@ void device_del(struct device *dev) | |||
1106 | if (dev->class) { | 1159 | if (dev->class) { |
1107 | device_remove_class_symlinks(dev); | 1160 | device_remove_class_symlinks(dev); |
1108 | 1161 | ||
1109 | mutex_lock(&dev->class->p->class_mutex); | 1162 | mutex_lock(&dev->class->p->mutex); |
1110 | /* notify any interfaces that the device is now gone */ | 1163 | /* notify any interfaces that the device is now gone */ |
1111 | list_for_each_entry(class_intf, | 1164 | list_for_each_entry(class_intf, |
1112 | &dev->class->p->class_interfaces, node) | 1165 | &dev->class->p->interfaces, node) |
1113 | if (class_intf->remove_dev) | 1166 | if (class_intf->remove_dev) |
1114 | class_intf->remove_dev(dev, class_intf); | 1167 | class_intf->remove_dev(dev, class_intf); |
1115 | /* remove the device from the class list */ | 1168 | /* remove the device from the class list */ |
1116 | klist_del(&dev->knode_class); | 1169 | klist_del(&dev->knode_class); |
1117 | mutex_unlock(&dev->class->p->class_mutex); | 1170 | mutex_unlock(&dev->class->p->mutex); |
1118 | } | 1171 | } |
1119 | device_remove_file(dev, &uevent_attr); | 1172 | device_remove_file(dev, &uevent_attr); |
1120 | device_remove_attrs(dev); | 1173 | device_remove_attrs(dev); |
diff --git a/drivers/base/init.c b/drivers/base/init.c index c8a934e79421..c16f0b808a17 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c | |||
@@ -31,7 +31,6 @@ void __init driver_init(void) | |||
31 | * core core pieces. | 31 | * core core pieces. |
32 | */ | 32 | */ |
33 | platform_bus_init(); | 33 | platform_bus_init(); |
34 | system_bus_init(); | ||
35 | cpu_dev_init(); | 34 | cpu_dev_init(); |
36 | memory_dev_init(); | 35 | memory_dev_init(); |
37 | } | 36 | } |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 9dff77bfe1e3..409f5ce78829 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -126,7 +126,7 @@ void sysdev_class_remove_file(struct sysdev_class *c, | |||
126 | } | 126 | } |
127 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | 127 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); |
128 | 128 | ||
129 | static struct kset *system_kset; | 129 | extern 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 | { |
@@ -331,14 +331,6 @@ void sysdev_unregister(struct sys_device *sysdev) | |||
331 | EXPORT_SYMBOL_GPL(sysdev_register); | 331 | EXPORT_SYMBOL_GPL(sysdev_register); |
332 | EXPORT_SYMBOL_GPL(sysdev_unregister); | 332 | EXPORT_SYMBOL_GPL(sysdev_unregister); |
333 | 333 | ||
334 | int __init system_bus_init(void) | ||
335 | { | ||
336 | system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); | ||
337 | if (!system_kset) | ||
338 | return -ENOMEM; | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) | 334 | #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) |
343 | 335 | ||
344 | ssize_t sysdev_store_ulong(struct sys_device *sysdev, | 336 | ssize_t sysdev_store_ulong(struct sys_device *sysdev, |
diff --git a/include/linux/device.h b/include/linux/device.h index 341fb740d851..7f9fc1505e94 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -53,6 +53,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); | |||
53 | * struct bus_type - The bus type of the device | 53 | * struct bus_type - The bus type of the device |
54 | * | 54 | * |
55 | * @name: The name of the bus. | 55 | * @name: The name of the bus. |
56 | * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id). | ||
57 | * @dev_root: Default device to use as the parent. | ||
56 | * @bus_attrs: Default attributes of the bus. | 58 | * @bus_attrs: Default attributes of the bus. |
57 | * @dev_attrs: Default attributes of the devices on the bus. | 59 | * @dev_attrs: Default attributes of the devices on the bus. |
58 | * @drv_attrs: Default attributes of the device drivers on the bus. | 60 | * @drv_attrs: Default attributes of the device drivers on the bus. |
@@ -86,6 +88,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); | |||
86 | */ | 88 | */ |
87 | struct bus_type { | 89 | struct bus_type { |
88 | const char *name; | 90 | const char *name; |
91 | const char *dev_name; | ||
92 | struct device *dev_root; | ||
89 | struct bus_attribute *bus_attrs; | 93 | struct bus_attribute *bus_attrs; |
90 | struct device_attribute *dev_attrs; | 94 | struct device_attribute *dev_attrs; |
91 | struct driver_attribute *drv_attrs; | 95 | struct driver_attribute *drv_attrs; |
@@ -106,12 +110,30 @@ struct bus_type { | |||
106 | struct subsys_private *p; | 110 | struct subsys_private *p; |
107 | }; | 111 | }; |
108 | 112 | ||
109 | extern int __must_check bus_register(struct bus_type *bus); | 113 | /* This is a #define to keep the compiler from merging different |
114 | * instances of the __key variable */ | ||
115 | #define bus_register(subsys) \ | ||
116 | ({ \ | ||
117 | static struct lock_class_key __key; \ | ||
118 | __bus_register(subsys, &__key); \ | ||
119 | }) | ||
120 | extern int __must_check __bus_register(struct bus_type *bus, | ||
121 | struct lock_class_key *key); | ||
110 | extern void bus_unregister(struct bus_type *bus); | 122 | extern void bus_unregister(struct bus_type *bus); |
111 | 123 | ||
112 | extern int __must_check bus_rescan_devices(struct bus_type *bus); | 124 | extern int __must_check bus_rescan_devices(struct bus_type *bus); |
113 | 125 | ||
114 | /* iterator helpers for buses */ | 126 | /* iterator helpers for buses */ |
127 | struct subsys_dev_iter { | ||
128 | struct klist_iter ki; | ||
129 | const struct device_type *type; | ||
130 | }; | ||
131 | void subsys_dev_iter_init(struct subsys_dev_iter *iter, | ||
132 | struct bus_type *subsys, | ||
133 | struct device *start, | ||
134 | const struct device_type *type); | ||
135 | struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter); | ||
136 | void subsys_dev_iter_exit(struct subsys_dev_iter *iter); | ||
115 | 137 | ||
116 | int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, | 138 | int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, |
117 | int (*fn)(struct device *dev, void *data)); | 139 | int (*fn)(struct device *dev, void *data)); |
@@ -121,10 +143,10 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start, | |||
121 | struct device *bus_find_device_by_name(struct bus_type *bus, | 143 | struct device *bus_find_device_by_name(struct bus_type *bus, |
122 | struct device *start, | 144 | struct device *start, |
123 | const char *name); | 145 | const char *name); |
124 | 146 | struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id, | |
147 | struct device *hint); | ||
125 | int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, | 148 | int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, |
126 | void *data, int (*fn)(struct device_driver *, void *)); | 149 | void *data, int (*fn)(struct device_driver *, void *)); |
127 | |||
128 | void bus_sort_breadthfirst(struct bus_type *bus, | 150 | void bus_sort_breadthfirst(struct bus_type *bus, |
129 | int (*compare)(const struct device *a, | 151 | int (*compare)(const struct device *a, |
130 | const struct device *b)); | 152 | const struct device *b)); |
@@ -256,6 +278,33 @@ struct device *driver_find_device(struct device_driver *drv, | |||
256 | int (*match)(struct device *dev, void *data)); | 278 | int (*match)(struct device *dev, void *data)); |
257 | 279 | ||
258 | /** | 280 | /** |
281 | * struct subsys_interface - interfaces to device functions | ||
282 | * @name name of the device function | ||
283 | * @subsystem subsytem of the devices to attach to | ||
284 | * @node the list of functions registered at the subsystem | ||
285 | * @add device hookup to device function handler | ||
286 | * @remove device hookup to device function handler | ||
287 | * | ||
288 | * Simple interfaces attached to a subsystem. Multiple interfaces can | ||
289 | * attach to a subsystem and its devices. Unlike drivers, they do not | ||
290 | * exclusively claim or control devices. Interfaces usually represent | ||
291 | * a specific functionality of a subsystem/class of devices. | ||
292 | */ | ||
293 | struct subsys_interface { | ||
294 | const char *name; | ||
295 | struct bus_type *subsys; | ||
296 | struct list_head node; | ||
297 | int (*add_dev)(struct device *dev, struct subsys_interface *sif); | ||
298 | int (*remove_dev)(struct device *dev, struct subsys_interface *sif); | ||
299 | }; | ||
300 | |||
301 | int subsys_interface_register(struct subsys_interface *sif); | ||
302 | void subsys_interface_unregister(struct subsys_interface *sif); | ||
303 | |||
304 | int subsys_system_register(struct bus_type *subsys, | ||
305 | const struct attribute_group **groups); | ||
306 | |||
307 | /** | ||
259 | * struct class - device classes | 308 | * struct class - device classes |
260 | * @name: Name of the class. | 309 | * @name: Name of the class. |
261 | * @owner: The module owner. | 310 | * @owner: The module owner. |
@@ -438,8 +487,28 @@ struct device_attribute { | |||
438 | const char *buf, size_t count); | 487 | const char *buf, size_t count); |
439 | }; | 488 | }; |
440 | 489 | ||
490 | struct dev_ext_attribute { | ||
491 | struct device_attribute attr; | ||
492 | void *var; | ||
493 | }; | ||
494 | |||
495 | ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr, | ||
496 | char *buf); | ||
497 | ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr, | ||
498 | const char *buf, size_t count); | ||
499 | ssize_t device_show_int(struct device *dev, struct device_attribute *attr, | ||
500 | char *buf); | ||
501 | ssize_t device_store_int(struct device *dev, struct device_attribute *attr, | ||
502 | const char *buf, size_t count); | ||
503 | |||
441 | #define DEVICE_ATTR(_name, _mode, _show, _store) \ | 504 | #define DEVICE_ATTR(_name, _mode, _show, _store) \ |
442 | struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) | 505 | struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) |
506 | #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ | ||
507 | struct dev_ext_attribute dev_attr_##_name = \ | ||
508 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } | ||
509 | #define DEVICE_INT_ATTR(_name, _mode, _var) \ | ||
510 | struct dev_ext_attribute dev_attr_##_name = \ | ||
511 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } | ||
443 | 512 | ||
444 | extern int __must_check device_create_file(struct device *device, | 513 | extern int __must_check device_create_file(struct device *device, |
445 | const struct device_attribute *entry); | 514 | const struct device_attribute *entry); |
@@ -603,6 +672,7 @@ struct device { | |||
603 | struct device_node *of_node; /* associated device tree node */ | 672 | struct device_node *of_node; /* associated device tree node */ |
604 | 673 | ||
605 | dev_t devt; /* dev_t, creates the sysfs "dev" */ | 674 | dev_t devt; /* dev_t, creates the sysfs "dev" */ |
675 | u32 id; /* device instance */ | ||
606 | 676 | ||
607 | spinlock_t devres_lock; | 677 | spinlock_t devres_lock; |
608 | struct list_head devres_head; | 678 | struct list_head devres_head; |