diff options
-rw-r--r-- | drivers/base/base.h | 1 | ||||
-rw-r--r-- | drivers/base/bus.c | 26 | ||||
-rw-r--r-- | drivers/base/dd.c | 2 |
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 *); | |||
5 | extern void bus_remove_driver(struct device_driver *); | 5 | extern void bus_remove_driver(struct device_driver *); |
6 | 6 | ||
7 | extern void driver_detach(struct device_driver * drv); | 7 | extern void driver_detach(struct device_driver * drv); |
8 | extern int driver_probe_device(struct device_driver *, struct device *); | ||
8 | 9 | ||
9 | static inline struct class_device *to_class_dev(struct kobject *obj) | 10 | static 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 | } |
161 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); | 161 | static 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 | */ | ||
168 | static 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 | } | ||
185 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | ||
186 | |||
163 | 187 | ||
164 | static struct device * next_device(struct klist_iter * i) | 188 | static 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) | |||
442 | void bus_remove_driver(struct device_driver * drv) | 467 | void 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 | */ |
68 | static int driver_probe_device(struct device_driver * drv, struct device * dev) | 68 | int driver_probe_device(struct device_driver * drv, struct device * dev) |
69 | { | 69 | { |
70 | int ret = 0; | 70 | int ret = 0; |
71 | 71 | ||