Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6

+143 -21
+1
drivers/base/base.h
··· 5 5 extern void bus_remove_driver(struct device_driver *); 6 6 7 7 extern void driver_detach(struct device_driver * drv); 8 + extern int driver_probe_device(struct device_driver *, struct device *); 8 9 9 10 static inline struct class_device *to_class_dev(struct kobject *obj) 10 11 {
+99 -18
drivers/base/bus.c
··· 133 133 decl_subsys(bus, &ktype_bus, NULL); 134 134 135 135 136 + /* Manually detach a device from it's associated driver. */ 137 + static int driver_helper(struct device *dev, void *data) 138 + { 139 + const char *name = data; 140 + 141 + if (strcmp(name, dev->bus_id) == 0) 142 + return 1; 143 + return 0; 144 + } 145 + 146 + static ssize_t driver_unbind(struct device_driver *drv, 147 + const char *buf, size_t count) 148 + { 149 + struct bus_type *bus = get_bus(drv->bus); 150 + struct device *dev; 151 + int err = -ENODEV; 152 + 153 + dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); 154 + if ((dev) && 155 + (dev->driver == drv)) { 156 + device_release_driver(dev); 157 + err = count; 158 + } 159 + return err; 160 + } 161 + static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 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 + 187 + 136 188 static struct device * next_device(struct klist_iter * i) 137 189 { 138 190 struct klist_node * n = klist_next(i); ··· 229 177 return error; 230 178 } 231 179 180 + /** 181 + * bus_find_device - device iterator for locating a particular device. 182 + * @bus: bus type 183 + * @start: Device to begin with 184 + * @data: Data to pass to match function 185 + * @match: Callback function to check device 186 + * 187 + * This is similar to the bus_for_each_dev() function above, but it 188 + * returns a reference to a device that is 'found' for later use, as 189 + * determined by the @match callback. 190 + * 191 + * The callback should return 0 if the device doesn't match and non-zero 192 + * if it does. If the callback returns non-zero, this function will 193 + * return to the caller and not iterate over any more devices. 194 + */ 195 + struct device * bus_find_device(struct bus_type *bus, 196 + struct device *start, void *data, 197 + int (*match)(struct device *, void *)) 198 + { 199 + struct klist_iter i; 200 + struct device *dev; 201 + 202 + if (!bus) 203 + return NULL; 204 + 205 + klist_iter_init_node(&bus->klist_devices, &i, 206 + (start ? &start->knode_bus : NULL)); 207 + while ((dev = next_device(&i))) 208 + if (match(dev, data) && get_device(dev)) 209 + break; 210 + klist_iter_exit(&i); 211 + return dev; 212 + } 232 213 233 214 234 215 static struct device_driver * next_driver(struct klist_iter * i) ··· 448 363 module_add_driver(drv->owner, drv); 449 364 450 365 driver_add_attrs(bus, drv); 366 + driver_create_file(drv, &driver_attr_unbind); 367 + driver_create_file(drv, &driver_attr_bind); 451 368 } 452 369 return error; 453 370 } ··· 467 380 void bus_remove_driver(struct device_driver * drv) 468 381 { 469 382 if (drv->bus) { 383 + driver_remove_file(drv, &driver_attr_bind); 384 + driver_remove_file(drv, &driver_attr_unbind); 470 385 driver_remove_attrs(drv->bus, drv); 471 386 klist_remove(&drv->knode_bus); 472 387 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); ··· 483 394 /* Helper for bus_rescan_devices's iter */ 484 395 static int bus_rescan_devices_helper(struct device *dev, void *data) 485 396 { 486 - int *count = data; 487 - 488 - if (!dev->driver && (device_attach(dev) > 0)) 489 - (*count)++; 490 - 397 + if (!dev->driver) 398 + device_attach(dev); 491 399 return 0; 492 400 } 493 401 494 - 495 402 /** 496 - * bus_rescan_devices - rescan devices on the bus for possible drivers 497 - * @bus: the bus to scan. 403 + * bus_rescan_devices - rescan devices on the bus for possible drivers 404 + * @bus: the bus to scan. 498 405 * 499 - * This function will look for devices on the bus with no driver 500 - * attached and rescan it against existing drivers to see if it 501 - * matches any. Calls device_attach(). Returns the number of devices 502 - * that were sucessfully bound to a driver. 406 + * This function will look for devices on the bus with no driver 407 + * attached and rescan it against existing drivers to see if it matches 408 + * any by calling device_attach() for the unbound devices. 503 409 */ 504 - int bus_rescan_devices(struct bus_type * bus) 410 + void bus_rescan_devices(struct bus_type * bus) 505 411 { 506 - int count = 0; 507 - 508 - bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); 509 - 510 - return count; 412 + bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); 511 413 } 512 414 513 415 ··· 637 557 638 558 639 559 EXPORT_SYMBOL_GPL(bus_for_each_dev); 560 + EXPORT_SYMBOL_GPL(bus_find_device); 640 561 EXPORT_SYMBOL_GPL(bus_for_each_drv); 641 562 642 563 EXPORT_SYMBOL_GPL(bus_add_device);
+1 -1
drivers/base/core.c
··· 333 333 struct device * parent = dev->parent; 334 334 335 335 if (parent) 336 - klist_remove(&dev->knode_parent); 336 + klist_del(&dev->knode_parent); 337 337 338 338 /* Notify the platform of the removal, in case they 339 339 * need to do anything...
+1 -1
drivers/base/dd.c
··· 65 65 * 66 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 70 int ret = 0; 71 71
+35
drivers/base/driver.c
··· 56 56 57 57 58 58 /** 59 + * driver_find_device - device iterator for locating a particular device. 60 + * @driver: The device's driver 61 + * @start: Device to begin with 62 + * @data: Data to pass to match function 63 + * @match: Callback function to check device 64 + * 65 + * This is similar to the driver_for_each_device() function above, but 66 + * it returns a reference to a device that is 'found' for later use, as 67 + * determined by the @match callback. 68 + * 69 + * The callback should return 0 if the device doesn't match and non-zero 70 + * if it does. If the callback returns non-zero, this function will 71 + * return to the caller and not iterate over any more devices. 72 + */ 73 + struct device * driver_find_device(struct device_driver *drv, 74 + struct device * start, void * data, 75 + int (*match)(struct device *, void *)) 76 + { 77 + struct klist_iter i; 78 + struct device *dev; 79 + 80 + if (!drv) 81 + return NULL; 82 + 83 + klist_iter_init_node(&drv->klist_devices, &i, 84 + (start ? &start->knode_driver : NULL)); 85 + while ((dev = next_device(&i))) 86 + if (match(dev, data) && get_device(dev)) 87 + break; 88 + klist_iter_exit(&i); 89 + return dev; 90 + } 91 + EXPORT_SYMBOL_GPL(driver_find_device); 92 + 93 + /** 59 94 * driver_create_file - create sysfs file for driver. 60 95 * @drv: driver. 61 96 * @attr: driver attribute descriptor.
+6 -1
include/linux/device.h
··· 69 69 extern int bus_register(struct bus_type * bus); 70 70 extern void bus_unregister(struct bus_type * bus); 71 71 72 - extern int bus_rescan_devices(struct bus_type * bus); 72 + extern void bus_rescan_devices(struct bus_type * bus); 73 73 74 74 extern struct bus_type * get_bus(struct bus_type * bus); 75 75 extern void put_bus(struct bus_type * bus); ··· 80 80 81 81 int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, 82 82 int (*fn)(struct device *, void *)); 83 + struct device * bus_find_device(struct bus_type *bus, struct device *start, 84 + void *data, int (*match)(struct device *, void *)); 83 85 84 86 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 85 87 void * data, int (*fn)(struct device_driver *, void *)); ··· 144 142 145 143 extern int driver_for_each_device(struct device_driver * drv, struct device * start, 146 144 void * data, int (*fn)(struct device *, void *)); 145 + struct device * driver_find_device(struct device_driver *drv, 146 + struct device *start, void *data, 147 + int (*match)(struct device *, void *)); 147 148 148 149 149 150 /*