diff options
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r-- | drivers/base/bus.c | 26 |
1 files changed, 26 insertions, 0 deletions
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); |