aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r--drivers/base/bus.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 1b05c1399e37..c8da37230b3e 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -134,28 +134,6 @@ static struct kobj_type ktype_bus = {
134 134
135decl_subsys(bus, &ktype_bus, NULL); 135decl_subsys(bus, &ktype_bus, NULL);
136 136
137static int __bus_for_each_dev(struct bus_type *bus, struct device *start,
138 void *data, int (*fn)(struct device *, void *))
139{
140 struct list_head *head;
141 struct device *dev;
142 int error = 0;
143
144 if (!(bus = get_bus(bus)))
145 return -EINVAL;
146
147 head = &bus->devices.list;
148 dev = list_prepare_entry(start, head, bus_list);
149 list_for_each_entry_continue(dev, head, bus_list) {
150 get_device(dev);
151 error = fn(dev, data);
152 put_device(dev);
153 if (error)
154 break;
155 }
156 put_bus(bus);
157 return error;
158}
159 137
160static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start, 138static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
161 void * data, int (*fn)(struct device_driver *, void *)) 139 void * data, int (*fn)(struct device_driver *, void *))
@@ -180,6 +158,13 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
180 return error; 158 return error;
181} 159}
182 160
161
162static struct device * next_device(struct klist_iter * i)
163{
164 struct klist_node * n = klist_next(i);
165 return n ? container_of(n, struct device, knode_bus) : NULL;
166}
167
183/** 168/**
184 * bus_for_each_dev - device iterator. 169 * bus_for_each_dev - device iterator.
185 * @bus: bus type. 170 * @bus: bus type.
@@ -203,12 +188,19 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
203int bus_for_each_dev(struct bus_type * bus, struct device * start, 188int bus_for_each_dev(struct bus_type * bus, struct device * start,
204 void * data, int (*fn)(struct device *, void *)) 189 void * data, int (*fn)(struct device *, void *))
205{ 190{
206 int ret; 191 struct klist_iter i;
192 struct device * dev;
193 int error = 0;
207 194
208 down_read(&bus->subsys.rwsem); 195 if (!bus)
209 ret = __bus_for_each_dev(bus, start, data, fn); 196 return -EINVAL;
210 up_read(&bus->subsys.rwsem); 197
211 return ret; 198 klist_iter_init_node(&bus->klist_devices, &i,
199 (start ? &start->knode_bus : NULL));
200 while ((dev = next_device(&i)) && !error)
201 error = fn(dev, data);
202 klist_iter_exit(&i);
203 return error;
212} 204}
213 205
214/** 206/**
@@ -293,6 +285,7 @@ int bus_add_device(struct device * dev)
293 list_add_tail(&dev->bus_list, &dev->bus->devices.list); 285 list_add_tail(&dev->bus_list, &dev->bus->devices.list);
294 device_attach(dev); 286 device_attach(dev);
295 up_write(&dev->bus->subsys.rwsem); 287 up_write(&dev->bus->subsys.rwsem);
288 klist_add_tail(&bus->klist_devices, &dev->knode_bus);
296 device_add_attrs(bus, dev); 289 device_add_attrs(bus, dev);
297 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); 290 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
298 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); 291 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
@@ -315,6 +308,7 @@ void bus_remove_device(struct device * dev)
315 sysfs_remove_link(&dev->kobj, "bus"); 308 sysfs_remove_link(&dev->kobj, "bus");
316 sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); 309 sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
317 device_remove_attrs(dev->bus, dev); 310 device_remove_attrs(dev->bus, dev);
311 klist_remove(&dev->knode_bus);
318 down_write(&dev->bus->subsys.rwsem); 312 down_write(&dev->bus->subsys.rwsem);
319 pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); 313 pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
320 device_release_driver(dev); 314 device_release_driver(dev);
@@ -439,9 +433,7 @@ int bus_rescan_devices(struct bus_type * bus)
439{ 433{
440 int count = 0; 434 int count = 0;
441 435
442 down_write(&bus->subsys.rwsem); 436 bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
443 __bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
444 up_write(&bus->subsys.rwsem);
445 437
446 return count; 438 return count;
447} 439}
@@ -542,6 +534,8 @@ int bus_register(struct bus_type * bus)
542 retval = kset_register(&bus->drivers); 534 retval = kset_register(&bus->drivers);
543 if (retval) 535 if (retval)
544 goto bus_drivers_fail; 536 goto bus_drivers_fail;
537
538 klist_init(&bus->klist_devices);
545 bus_add_attrs(bus); 539 bus_add_attrs(bus);
546 540
547 pr_debug("bus type '%s' registered\n", bus->name); 541 pr_debug("bus type '%s' registered\n", bus->name);