aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/base.h1
-rw-r--r--drivers/base/bus.c26
-rw-r--r--drivers/base/dd.c2
3 files changed, 28 insertions, 1 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 645f62692920..783752b68a9a 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -5,6 +5,7 @@ extern int bus_add_driver(struct device_driver *);
5extern void bus_remove_driver(struct device_driver *); 5extern void bus_remove_driver(struct device_driver *);
6 6
7extern void driver_detach(struct device_driver * drv); 7extern void driver_detach(struct device_driver * drv);
8extern int driver_probe_device(struct device_driver *, struct device *);
8 9
9static inline struct class_device *to_class_dev(struct kobject *obj) 10static inline struct class_device *to_class_dev(struct kobject *obj)
10{ 11{
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index fa41ee90a53a..7e17488271a8 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -160,6 +160,30 @@ static ssize_t driver_unbind(struct device_driver *drv,
160} 160}
161static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 161static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
162 162
163/*
164 * Manually attach a device to a driver.
165 * Note: the driver must want to bind to the device,
166 * it is not possible to override the driver's id table.
167 */
168static ssize_t driver_bind(struct device_driver *drv,
169 const char *buf, size_t count)
170{
171 struct bus_type *bus = get_bus(drv->bus);
172 struct device *dev;
173 int err = -ENODEV;
174
175 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
176 if ((dev) &&
177 (dev->driver == NULL)) {
178 down(&dev->sem);
179 err = driver_probe_device(drv, dev);
180 up(&dev->sem);
181 put_device(dev);
182 }
183 return err;
184}
185static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
186
163 187
164static struct device * next_device(struct klist_iter * i) 188static struct device * next_device(struct klist_iter * i)
165{ 189{
@@ -425,6 +449,7 @@ int bus_add_driver(struct device_driver * drv)
425 449
426 driver_add_attrs(bus, drv); 450 driver_add_attrs(bus, drv);
427 driver_create_file(drv, &driver_attr_unbind); 451 driver_create_file(drv, &driver_attr_unbind);
452 driver_create_file(drv, &driver_attr_bind);
428 } 453 }
429 return error; 454 return error;
430} 455}
@@ -442,6 +467,7 @@ int bus_add_driver(struct device_driver * drv)
442void bus_remove_driver(struct device_driver * drv) 467void bus_remove_driver(struct device_driver * drv)
443{ 468{
444 if (drv->bus) { 469 if (drv->bus) {
470 driver_remove_file(drv, &driver_attr_bind);
445 driver_remove_file(drv, &driver_attr_unbind); 471 driver_remove_file(drv, &driver_attr_unbind);
446 driver_remove_attrs(drv->bus, drv); 472 driver_remove_attrs(drv->bus, drv);
447 klist_remove(&drv->knode_bus); 473 klist_remove(&drv->knode_bus);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 6db3a789c54f..16323f9cbff0 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -65,7 +65,7 @@ void device_bind_driver(struct device * dev)
65 * 65 *
66 * This function must be called with @dev->sem held. 66 * This function must be called with @dev->sem held.
67 */ 67 */
68static int driver_probe_device(struct device_driver * drv, struct device * dev) 68int driver_probe_device(struct device_driver * drv, struct device * dev)
69{ 69{
70 int ret = 0; 70 int ret = 0;
71 71