aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/dd.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9c88b1e34bc..510e7884975 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -26,28 +26,12 @@
26#define to_drv(node) container_of(node, struct device_driver, kobj.entry) 26#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
27 27
28 28
29/** 29static void driver_bound(struct device *dev)
30 * device_bind_driver - bind a driver to one device.
31 * @dev: device.
32 *
33 * Allow manual attachment of a driver to a device.
34 * Caller must have already set @dev->driver.
35 *
36 * Note that this does not modify the bus reference count
37 * nor take the bus's rwsem. Please verify those are accounted
38 * for before calling this. (It is ok to call with no other effort
39 * from a driver's probe() method.)
40 *
41 * This function must be called with @dev->sem held.
42 */
43int device_bind_driver(struct device *dev)
44{ 30{
45 int ret;
46
47 if (klist_node_attached(&dev->knode_driver)) { 31 if (klist_node_attached(&dev->knode_driver)) {
48 printk(KERN_WARNING "%s: device %s already bound\n", 32 printk(KERN_WARNING "%s: device %s already bound\n",
49 __FUNCTION__, kobject_name(&dev->kobj)); 33 __FUNCTION__, kobject_name(&dev->kobj));
50 return 0; 34 return;
51 } 35 }
52 36
53 pr_debug("bound device '%s' to driver '%s'\n", 37 pr_debug("bound device '%s' to driver '%s'\n",
@@ -58,6 +42,12 @@ int device_bind_driver(struct device *dev)
58 BUS_NOTIFY_BOUND_DRIVER, dev); 42 BUS_NOTIFY_BOUND_DRIVER, dev);
59 43
60 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); 44 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
45}
46
47static int driver_sysfs_add(struct device *dev)
48{
49 int ret;
50
61 ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, 51 ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
62 kobject_name(&dev->kobj)); 52 kobject_name(&dev->kobj));
63 if (ret == 0) { 53 if (ret == 0) {
@@ -70,6 +60,36 @@ int device_bind_driver(struct device *dev)
70 return ret; 60 return ret;
71} 61}
72 62
63static void driver_sysfs_remove(struct device *dev)
64{
65 struct device_driver *drv = dev->driver;
66
67 if (drv) {
68 sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
69 sysfs_remove_link(&dev->kobj, "driver");
70 }
71}
72
73/**
74 * device_bind_driver - bind a driver to one device.
75 * @dev: device.
76 *
77 * Allow manual attachment of a driver to a device.
78 * Caller must have already set @dev->driver.
79 *
80 * Note that this does not modify the bus reference count
81 * nor take the bus's rwsem. Please verify those are accounted
82 * for before calling this. (It is ok to call with no other effort
83 * from a driver's probe() method.)
84 *
85 * This function must be called with @dev->sem held.
86 */
87int device_bind_driver(struct device *dev)
88{
89 driver_bound(dev);
90 return driver_sysfs_add(dev);
91}
92
73struct stupid_thread_structure { 93struct stupid_thread_structure {
74 struct device_driver *drv; 94 struct device_driver *drv;
75 struct device *dev; 95 struct device *dev;
@@ -90,30 +110,32 @@ static int really_probe(void *void_data)
90 drv->bus->name, drv->name, dev->bus_id); 110 drv->bus->name, drv->name, dev->bus_id);
91 111
92 dev->driver = drv; 112 dev->driver = drv;
113 if (driver_sysfs_add(dev)) {
114 printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
115 __FUNCTION__, dev->bus_id);
116 goto probe_failed;
117 }
118
93 if (dev->bus->probe) { 119 if (dev->bus->probe) {
94 ret = dev->bus->probe(dev); 120 ret = dev->bus->probe(dev);
95 if (ret) { 121 if (ret)
96 dev->driver = NULL;
97 goto probe_failed; 122 goto probe_failed;
98 }
99 } else if (drv->probe) { 123 } else if (drv->probe) {
100 ret = drv->probe(dev); 124 ret = drv->probe(dev);
101 if (ret) { 125 if (ret)
102 dev->driver = NULL;
103 goto probe_failed; 126 goto probe_failed;
104 }
105 }
106 if (device_bind_driver(dev)) {
107 printk(KERN_ERR "%s: device_bind_driver(%s) failed\n",
108 __FUNCTION__, dev->bus_id);
109 /* How does undo a ->probe? We're screwed. */
110 } 127 }
128
129 driver_bound(dev);
111 ret = 1; 130 ret = 1;
112 pr_debug("%s: Bound Device %s to Driver %s\n", 131 pr_debug("%s: Bound Device %s to Driver %s\n",
113 drv->bus->name, dev->bus_id, drv->name); 132 drv->bus->name, dev->bus_id, drv->name);
114 goto done; 133 goto done;
115 134
116probe_failed: 135probe_failed:
136 driver_sysfs_remove(dev);
137 dev->driver = NULL;
138
117 if (ret == -ENODEV || ret == -ENXIO) { 139 if (ret == -ENODEV || ret == -ENXIO) {
118 /* Driver matched, but didn't support device 140 /* Driver matched, but didn't support device
119 * or device not found. 141 * or device not found.
@@ -289,7 +311,7 @@ static void __device_release_driver(struct device * dev)
289 drv = dev->driver; 311 drv = dev->driver;
290 if (drv) { 312 if (drv) {
291 get_driver(drv); 313 get_driver(drv);
292 sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); 314 driver_sysfs_remove(dev);
293 sysfs_remove_link(&dev->kobj, "driver"); 315 sysfs_remove_link(&dev->kobj, "driver");
294 klist_remove(&dev->knode_driver); 316 klist_remove(&dev->knode_driver);
295 317