aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/dd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r--drivers/base/dd.c92
1 files changed, 62 insertions, 30 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index c5d6bb4290ad..510e7884975f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -26,33 +26,28 @@
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",
54 dev->bus_id, dev->driver->name); 38 dev->bus_id, dev->driver->name);
39
40 if (dev->bus)
41 blocking_notifier_call_chain(&dev->bus->bus_notifier,
42 BUS_NOTIFY_BOUND_DRIVER, dev);
43
55 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
56 ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, 51 ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
57 kobject_name(&dev->kobj)); 52 kobject_name(&dev->kobj));
58 if (ret == 0) { 53 if (ret == 0) {
@@ -65,6 +60,36 @@ int device_bind_driver(struct device *dev)
65 return ret; 60 return ret;
66} 61}
67 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
68struct stupid_thread_structure { 93struct stupid_thread_structure {
69 struct device_driver *drv; 94 struct device_driver *drv;
70 struct device *dev; 95 struct device *dev;
@@ -85,30 +110,32 @@ static int really_probe(void *void_data)
85 drv->bus->name, drv->name, dev->bus_id); 110 drv->bus->name, drv->name, dev->bus_id);
86 111
87 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
88 if (dev->bus->probe) { 119 if (dev->bus->probe) {
89 ret = dev->bus->probe(dev); 120 ret = dev->bus->probe(dev);
90 if (ret) { 121 if (ret)
91 dev->driver = NULL;
92 goto probe_failed; 122 goto probe_failed;
93 }
94 } else if (drv->probe) { 123 } else if (drv->probe) {
95 ret = drv->probe(dev); 124 ret = drv->probe(dev);
96 if (ret) { 125 if (ret)
97 dev->driver = NULL;
98 goto probe_failed; 126 goto probe_failed;
99 }
100 }
101 if (device_bind_driver(dev)) {
102 printk(KERN_ERR "%s: device_bind_driver(%s) failed\n",
103 __FUNCTION__, dev->bus_id);
104 /* How does undo a ->probe? We're screwed. */
105 } 127 }
128
129 driver_bound(dev);
106 ret = 1; 130 ret = 1;
107 pr_debug("%s: Bound Device %s to Driver %s\n", 131 pr_debug("%s: Bound Device %s to Driver %s\n",
108 drv->bus->name, dev->bus_id, drv->name); 132 drv->bus->name, dev->bus_id, drv->name);
109 goto done; 133 goto done;
110 134
111probe_failed: 135probe_failed:
136 driver_sysfs_remove(dev);
137 dev->driver = NULL;
138
112 if (ret == -ENODEV || ret == -ENXIO) { 139 if (ret == -ENODEV || ret == -ENXIO) {
113 /* Driver matched, but didn't support device 140 /* Driver matched, but didn't support device
114 * or device not found. 141 * or device not found.
@@ -284,10 +311,15 @@ static void __device_release_driver(struct device * dev)
284 drv = dev->driver; 311 drv = dev->driver;
285 if (drv) { 312 if (drv) {
286 get_driver(drv); 313 get_driver(drv);
287 sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); 314 driver_sysfs_remove(dev);
288 sysfs_remove_link(&dev->kobj, "driver"); 315 sysfs_remove_link(&dev->kobj, "driver");
289 klist_remove(&dev->knode_driver); 316 klist_remove(&dev->knode_driver);
290 317
318 if (dev->bus)
319 blocking_notifier_call_chain(&dev->bus->bus_notifier,
320 BUS_NOTIFY_UNBIND_DRIVER,
321 dev);
322
291 if (dev->bus && dev->bus->remove) 323 if (dev->bus && dev->bus->remove)
292 dev->bus->remove(dev); 324 dev->bus->remove(dev);
293 else if (drv->remove) 325 else if (drv->remove)