aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/bus.c52
-rw-r--r--include/linux/device.h2
2 files changed, 25 insertions, 29 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index c8da37230b3e..736dc1f5a316 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -135,30 +135,6 @@ static struct kobj_type ktype_bus = {
135decl_subsys(bus, &ktype_bus, NULL); 135decl_subsys(bus, &ktype_bus, NULL);
136 136
137 137
138static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
139 void * data, int (*fn)(struct device_driver *, void *))
140{
141 struct list_head *head;
142 struct device_driver *drv;
143 int error = 0;
144
145 if (!(bus = get_bus(bus)))
146 return -EINVAL;
147
148 head = &bus->drivers.list;
149 drv = list_prepare_entry(start, head, kobj.entry);
150 list_for_each_entry_continue(drv, head, kobj.entry) {
151 get_driver(drv);
152 error = fn(drv, data);
153 put_driver(drv);
154 if (error)
155 break;
156 }
157 put_bus(bus);
158 return error;
159}
160
161
162static struct device * next_device(struct klist_iter * i) 138static struct device * next_device(struct klist_iter * i)
163{ 139{
164 struct klist_node * n = klist_next(i); 140 struct klist_node * n = klist_next(i);
@@ -203,6 +179,14 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
203 return error; 179 return error;
204} 180}
205 181
182
183
184static struct device_driver * next_driver(struct klist_iter * i)
185{
186 struct klist_node * n = klist_next(i);
187 return n ? container_of(n, struct device_driver, knode_bus) : NULL;
188}
189
206/** 190/**
207 * bus_for_each_drv - driver iterator 191 * bus_for_each_drv - driver iterator
208 * @bus: bus we're dealing with. 192 * @bus: bus we're dealing with.
@@ -226,12 +210,19 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
226int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 210int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
227 void * data, int (*fn)(struct device_driver *, void *)) 211 void * data, int (*fn)(struct device_driver *, void *))
228{ 212{
229 int ret; 213 struct klist_iter i;
214 struct device_driver * drv;
215 int error = 0;
230 216
231 down_read(&bus->subsys.rwsem); 217 if (!bus)
232 ret = __bus_for_each_drv(bus, start, data, fn); 218 return -EINVAL;
233 up_read(&bus->subsys.rwsem); 219
234 return ret; 220 klist_iter_init_node(&bus->klist_drivers, &i,
221 start ? &start->knode_bus : NULL);
222 while ((drv = next_driver(&i)) && !error)
223 error = fn(drv, data);
224 klist_iter_exit(&i);
225 return error;
235} 226}
236 227
237static int device_add_attrs(struct bus_type * bus, struct device * dev) 228static int device_add_attrs(struct bus_type * bus, struct device * dev)
@@ -376,6 +367,7 @@ int bus_add_driver(struct device_driver * drv)
376 down_write(&bus->subsys.rwsem); 367 down_write(&bus->subsys.rwsem);
377 driver_attach(drv); 368 driver_attach(drv);
378 up_write(&bus->subsys.rwsem); 369 up_write(&bus->subsys.rwsem);
370 klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
379 module_add_driver(drv->owner, drv); 371 module_add_driver(drv->owner, drv);
380 372
381 driver_add_attrs(bus, drv); 373 driver_add_attrs(bus, drv);
@@ -397,6 +389,7 @@ void bus_remove_driver(struct device_driver * drv)
397{ 389{
398 if (drv->bus) { 390 if (drv->bus) {
399 driver_remove_attrs(drv->bus, drv); 391 driver_remove_attrs(drv->bus, drv);
392 klist_remove(&drv->knode_bus);
400 down_write(&drv->bus->subsys.rwsem); 393 down_write(&drv->bus->subsys.rwsem);
401 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); 394 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
402 driver_detach(drv); 395 driver_detach(drv);
@@ -536,6 +529,7 @@ int bus_register(struct bus_type * bus)
536 goto bus_drivers_fail; 529 goto bus_drivers_fail;
537 530
538 klist_init(&bus->klist_devices); 531 klist_init(&bus->klist_devices);
532 klist_init(&bus->klist_drivers);
539 bus_add_attrs(bus); 533 bus_add_attrs(bus);
540 534
541 pr_debug("bus type '%s' registered\n", bus->name); 535 pr_debug("bus type '%s' registered\n", bus->name);
diff --git a/include/linux/device.h b/include/linux/device.h
index e36953cf7f14..ea9ab33dfe71 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -53,6 +53,7 @@ struct bus_type {
53 struct kset drivers; 53 struct kset drivers;
54 struct kset devices; 54 struct kset devices;
55 struct klist klist_devices; 55 struct klist klist_devices;
56 struct klist klist_drivers;
56 57
57 struct bus_attribute * bus_attrs; 58 struct bus_attribute * bus_attrs;
58 struct device_attribute * dev_attrs; 59 struct device_attribute * dev_attrs;
@@ -105,6 +106,7 @@ struct device_driver {
105 struct completion unloaded; 106 struct completion unloaded;
106 struct kobject kobj; 107 struct kobject kobj;
107 struct list_head devices; 108 struct list_head devices;
109 struct klist_node knode_bus;
108 110
109 struct module * owner; 111 struct module * owner;
110 112