aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c62
1 files changed, 21 insertions, 41 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index fbc223486f81..86d79755fbfb 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -36,10 +36,10 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
36{ 36{
37 struct device_attribute * dev_attr = to_dev_attr(attr); 37 struct device_attribute * dev_attr = to_dev_attr(attr);
38 struct device * dev = to_dev(kobj); 38 struct device * dev = to_dev(kobj);
39 ssize_t ret = 0; 39 ssize_t ret = -EIO;
40 40
41 if (dev_attr->show) 41 if (dev_attr->show)
42 ret = dev_attr->show(dev, buf); 42 ret = dev_attr->show(dev, dev_attr, buf);
43 return ret; 43 return ret;
44} 44}
45 45
@@ -49,10 +49,10 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr,
49{ 49{
50 struct device_attribute * dev_attr = to_dev_attr(attr); 50 struct device_attribute * dev_attr = to_dev_attr(attr);
51 struct device * dev = to_dev(kobj); 51 struct device * dev = to_dev(kobj);
52 ssize_t ret = 0; 52 ssize_t ret = -EIO;
53 53
54 if (dev_attr->store) 54 if (dev_attr->store)
55 ret = dev_attr->store(dev, buf, count); 55 ret = dev_attr->store(dev, dev_attr, buf, count);
56 return ret; 56 return ret;
57} 57}
58 58
@@ -102,7 +102,7 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
102 return 0; 102 return 0;
103} 103}
104 104
105static char *dev_hotplug_name(struct kset *kset, struct kobject *kobj) 105static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
106{ 106{
107 struct device *dev = to_dev(kobj); 107 struct device *dev = to_dev(kobj);
108 108
@@ -207,11 +207,9 @@ void device_initialize(struct device *dev)
207{ 207{
208 kobj_set_kset_s(dev, devices_subsys); 208 kobj_set_kset_s(dev, devices_subsys);
209 kobject_init(&dev->kobj); 209 kobject_init(&dev->kobj);
210 INIT_LIST_HEAD(&dev->node); 210 klist_init(&dev->klist_children);
211 INIT_LIST_HEAD(&dev->children);
212 INIT_LIST_HEAD(&dev->driver_list);
213 INIT_LIST_HEAD(&dev->bus_list);
214 INIT_LIST_HEAD(&dev->dma_pools); 211 INIT_LIST_HEAD(&dev->dma_pools);
212 init_MUTEX(&dev->sem);
215} 213}
216 214
217/** 215/**
@@ -250,10 +248,8 @@ int device_add(struct device *dev)
250 goto PMError; 248 goto PMError;
251 if ((error = bus_add_device(dev))) 249 if ((error = bus_add_device(dev)))
252 goto BusError; 250 goto BusError;
253 down_write(&devices_subsys.rwsem);
254 if (parent) 251 if (parent)
255 list_add_tail(&dev->node, &parent->children); 252 klist_add_tail(&parent->klist_children, &dev->knode_parent);
256 up_write(&devices_subsys.rwsem);
257 253
258 /* notify platform of device entry */ 254 /* notify platform of device entry */
259 if (platform_notify) 255 if (platform_notify)
@@ -336,10 +332,8 @@ void device_del(struct device * dev)
336{ 332{
337 struct device * parent = dev->parent; 333 struct device * parent = dev->parent;
338 334
339 down_write(&devices_subsys.rwsem);
340 if (parent) 335 if (parent)
341 list_del_init(&dev->node); 336 klist_remove(&dev->knode_parent);
342 up_write(&devices_subsys.rwsem);
343 337
344 /* Notify the platform of the removal, in case they 338 /* Notify the platform of the removal, in case they
345 * need to do anything... 339 * need to do anything...
@@ -373,6 +367,12 @@ void device_unregister(struct device * dev)
373} 367}
374 368
375 369
370static struct device * next_device(struct klist_iter * i)
371{
372 struct klist_node * n = klist_next(i);
373 return n ? container_of(n, struct device, knode_parent) : NULL;
374}
375
376/** 376/**
377 * device_for_each_child - device child iterator. 377 * device_for_each_child - device child iterator.
378 * @dev: parent struct device. 378 * @dev: parent struct device.
@@ -385,39 +385,20 @@ void device_unregister(struct device * dev)
385 * We check the return of @fn each time. If it returns anything 385 * We check the return of @fn each time. If it returns anything
386 * other than 0, we break out and return that value. 386 * other than 0, we break out and return that value.
387 */ 387 */
388int device_for_each_child(struct device * dev, void * data, 388int device_for_each_child(struct device * parent, void * data,
389 int (*fn)(struct device *, void *)) 389 int (*fn)(struct device *, void *))
390{ 390{
391 struct klist_iter i;
391 struct device * child; 392 struct device * child;
392 int error = 0; 393 int error = 0;
393 394
394 down_read(&devices_subsys.rwsem); 395 klist_iter_init(&parent->klist_children, &i);
395 list_for_each_entry(child, &dev->children, node) { 396 while ((child = next_device(&i)) && !error)
396 if((error = fn(child, data))) 397 error = fn(child, data);
397 break; 398 klist_iter_exit(&i);
398 }
399 up_read(&devices_subsys.rwsem);
400 return error; 399 return error;
401} 400}
402 401
403/**
404 * device_find - locate device on a bus by name.
405 * @name: name of the device.
406 * @bus: bus to scan for the device.
407 *
408 * Call kset_find_obj() to iterate over list of devices on
409 * a bus to find device by name. Return device if found.
410 *
411 * Note that kset_find_obj increments device's reference count.
412 */
413struct device *device_find(const char *name, struct bus_type *bus)
414{
415 struct kobject *k = kset_find_obj(&bus->devices, name);
416 if (k)
417 return to_dev(k);
418 return NULL;
419}
420
421int __init devices_init(void) 402int __init devices_init(void)
422{ 403{
423 return subsystem_register(&devices_subsys); 404 return subsystem_register(&devices_subsys);
@@ -433,7 +414,6 @@ EXPORT_SYMBOL_GPL(device_del);
433EXPORT_SYMBOL_GPL(device_unregister); 414EXPORT_SYMBOL_GPL(device_unregister);
434EXPORT_SYMBOL_GPL(get_device); 415EXPORT_SYMBOL_GPL(get_device);
435EXPORT_SYMBOL_GPL(put_device); 416EXPORT_SYMBOL_GPL(put_device);
436EXPORT_SYMBOL_GPL(device_find);
437 417
438EXPORT_SYMBOL_GPL(device_create_file); 418EXPORT_SYMBOL_GPL(device_create_file);
439EXPORT_SYMBOL_GPL(device_remove_file); 419EXPORT_SYMBOL_GPL(device_remove_file);