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 | ||
