diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/base.h | 1 | ||||
-rw-r--r-- | drivers/base/bus.c | 117 | ||||
-rw-r--r-- | drivers/base/core.c | 2 | ||||
-rw-r--r-- | drivers/base/dd.c | 2 | ||||
-rw-r--r-- | drivers/base/driver.c | 35 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.c | 2 | ||||
-rw-r--r-- | drivers/ide/legacy/hd.c | 4 | ||||
-rw-r--r-- | drivers/input/gameport/gameport.c | 3 | ||||
-rw-r--r-- | drivers/input/joystick/analog.c | 4 | ||||
-rw-r--r-- | drivers/pcmcia/ds.c | 2 | ||||
-rw-r--r-- | drivers/serial/8250.c | 3 |
11 files changed, 149 insertions, 26 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 c3fac7fd555e..96fe2f956754 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -133,6 +133,58 @@ static struct kobj_type ktype_bus = { | |||
133 | decl_subsys(bus, &ktype_bus, NULL); | 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 | static struct device * next_device(struct klist_iter * i) | 188 | static struct device * next_device(struct klist_iter * i) |
137 | { | 189 | { |
138 | struct klist_node * n = klist_next(i); | 190 | struct klist_node * n = klist_next(i); |
@@ -177,6 +229,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, | |||
177 | return error; | 229 | return error; |
178 | } | 230 | } |
179 | 231 | ||
232 | /** | ||
233 | * bus_find_device - device iterator for locating a particular device. | ||
234 | * @bus: bus type | ||
235 | * @start: Device to begin with | ||
236 | * @data: Data to pass to match function | ||
237 | * @match: Callback function to check device | ||
238 | * | ||
239 | * This is similar to the bus_for_each_dev() function above, but it | ||
240 | * returns a reference to a device that is 'found' for later use, as | ||
241 | * determined by the @match callback. | ||
242 | * | ||
243 | * The callback should return 0 if the device doesn't match and non-zero | ||
244 | * if it does. If the callback returns non-zero, this function will | ||
245 | * return to the caller and not iterate over any more devices. | ||
246 | */ | ||
247 | struct device * bus_find_device(struct bus_type *bus, | ||
248 | struct device *start, void *data, | ||
249 | int (*match)(struct device *, void *)) | ||
250 | { | ||
251 | struct klist_iter i; | ||
252 | struct device *dev; | ||
253 | |||
254 | if (!bus) | ||
255 | return NULL; | ||
256 | |||
257 | klist_iter_init_node(&bus->klist_devices, &i, | ||
258 | (start ? &start->knode_bus : NULL)); | ||
259 | while ((dev = next_device(&i))) | ||
260 | if (match(dev, data) && get_device(dev)) | ||
261 | break; | ||
262 | klist_iter_exit(&i); | ||
263 | return dev; | ||
264 | } | ||
180 | 265 | ||
181 | 266 | ||
182 | static struct device_driver * next_driver(struct klist_iter * i) | 267 | static struct device_driver * next_driver(struct klist_iter * i) |
@@ -363,6 +448,8 @@ int bus_add_driver(struct device_driver * drv) | |||
363 | module_add_driver(drv->owner, drv); | 448 | module_add_driver(drv->owner, drv); |
364 | 449 | ||
365 | driver_add_attrs(bus, drv); | 450 | driver_add_attrs(bus, drv); |
451 | driver_create_file(drv, &driver_attr_unbind); | ||
452 | driver_create_file(drv, &driver_attr_bind); | ||
366 | } | 453 | } |
367 | return error; | 454 | return error; |
368 | } | 455 | } |
@@ -380,6 +467,8 @@ int bus_add_driver(struct device_driver * drv) | |||
380 | void bus_remove_driver(struct device_driver * drv) | 467 | void bus_remove_driver(struct device_driver * drv) |
381 | { | 468 | { |
382 | if (drv->bus) { | 469 | if (drv->bus) { |
470 | driver_remove_file(drv, &driver_attr_bind); | ||
471 | driver_remove_file(drv, &driver_attr_unbind); | ||
383 | driver_remove_attrs(drv->bus, drv); | 472 | driver_remove_attrs(drv->bus, drv); |
384 | klist_remove(&drv->knode_bus); | 473 | klist_remove(&drv->knode_bus); |
385 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 474 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); |
@@ -394,31 +483,22 @@ void bus_remove_driver(struct device_driver * drv) | |||
394 | /* Helper for bus_rescan_devices's iter */ | 483 | /* Helper for bus_rescan_devices's iter */ |
395 | static int bus_rescan_devices_helper(struct device *dev, void *data) | 484 | static int bus_rescan_devices_helper(struct device *dev, void *data) |
396 | { | 485 | { |
397 | int *count = data; | 486 | if (!dev->driver) |
398 | 487 | device_attach(dev); | |
399 | if (!dev->driver && (device_attach(dev) > 0)) | ||
400 | (*count)++; | ||
401 | |||
402 | return 0; | 488 | return 0; |
403 | } | 489 | } |
404 | 490 | ||
405 | |||
406 | /** | 491 | /** |
407 | * bus_rescan_devices - rescan devices on the bus for possible drivers | 492 | * bus_rescan_devices - rescan devices on the bus for possible drivers |
408 | * @bus: the bus to scan. | 493 | * @bus: the bus to scan. |
409 | * | 494 | * |
410 | * This function will look for devices on the bus with no driver | 495 | * This function will look for devices on the bus with no driver |
411 | * attached and rescan it against existing drivers to see if it | 496 | * attached and rescan it against existing drivers to see if it matches |
412 | * matches any. Calls device_attach(). Returns the number of devices | 497 | * any by calling device_attach() for the unbound devices. |
413 | * that were sucessfully bound to a driver. | ||
414 | */ | 498 | */ |
415 | int bus_rescan_devices(struct bus_type * bus) | 499 | void bus_rescan_devices(struct bus_type * bus) |
416 | { | 500 | { |
417 | int count = 0; | 501 | bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); |
418 | |||
419 | bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); | ||
420 | |||
421 | return count; | ||
422 | } | 502 | } |
423 | 503 | ||
424 | 504 | ||
@@ -557,6 +637,7 @@ int __init buses_init(void) | |||
557 | 637 | ||
558 | 638 | ||
559 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | 639 | EXPORT_SYMBOL_GPL(bus_for_each_dev); |
640 | EXPORT_SYMBOL_GPL(bus_find_device); | ||
560 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | 641 | EXPORT_SYMBOL_GPL(bus_for_each_drv); |
561 | 642 | ||
562 | EXPORT_SYMBOL_GPL(bus_add_device); | 643 | EXPORT_SYMBOL_GPL(bus_add_device); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 86d79755fbfb..efe03a024a5b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -333,7 +333,7 @@ void device_del(struct device * dev) | |||
333 | struct device * parent = dev->parent; | 333 | struct device * parent = dev->parent; |
334 | 334 | ||
335 | if (parent) | 335 | if (parent) |
336 | klist_remove(&dev->knode_parent); | 336 | klist_del(&dev->knode_parent); |
337 | 337 | ||
338 | /* Notify the platform of the removal, in case they | 338 | /* Notify the platform of the removal, in case they |
339 | * need to do anything... | 339 | * need to do anything... |
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 | ||
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 1b645886e9eb..291c5954a3af 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -56,6 +56,41 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); | |||
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 | * driver_create_file - create sysfs file for driver. | 94 | * driver_create_file - create sysfs file for driver. |
60 | * @drv: driver. | 95 | * @drv: driver. |
61 | * @attr: driver attribute descriptor. | 96 | * @attr: driver attribute descriptor. |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 854475c54f0e..049d128ae7f0 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -464,7 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) | |||
464 | 464 | ||
465 | pci_set_drvdata(pci_dev, NULL); | 465 | pci_set_drvdata(pci_dev, NULL); |
466 | misc_deregister(&chip->vendor->miscdev); | 466 | misc_deregister(&chip->vendor->miscdev); |
467 | kfree(&chip->vendor->miscdev.name); | 467 | kfree(chip->vendor->miscdev.name); |
468 | 468 | ||
469 | sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); | 469 | sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); |
470 | 470 | ||
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index e884cd4b22fd..242029c9c0ca 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c | |||
@@ -156,11 +156,13 @@ else \ | |||
156 | 156 | ||
157 | 157 | ||
158 | #if (HD_DELAY > 0) | 158 | #if (HD_DELAY > 0) |
159 | |||
160 | #include <asm/i8253.h> | ||
161 | |||
159 | unsigned long last_req; | 162 | unsigned long last_req; |
160 | 163 | ||
161 | unsigned long read_timer(void) | 164 | unsigned long read_timer(void) |
162 | { | 165 | { |
163 | extern spinlock_t i8253_lock; | ||
164 | unsigned long t, flags; | 166 | unsigned long t, flags; |
165 | int i; | 167 | int i; |
166 | 168 | ||
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 3e72c9b1461e..ab09cf4093e3 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -60,12 +60,13 @@ static void gameport_disconnect_port(struct gameport *gameport); | |||
60 | 60 | ||
61 | #if defined(__i386__) | 61 | #if defined(__i386__) |
62 | 62 | ||
63 | #include <asm/i8253.h> | ||
64 | |||
63 | #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) | 65 | #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) |
64 | #define GET_TIME(x) do { x = get_time_pit(); } while (0) | 66 | #define GET_TIME(x) do { x = get_time_pit(); } while (0) |
65 | 67 | ||
66 | static unsigned int get_time_pit(void) | 68 | static unsigned int get_time_pit(void) |
67 | { | 69 | { |
68 | extern spinlock_t i8253_lock; | ||
69 | unsigned long flags; | 70 | unsigned long flags; |
70 | unsigned int count; | 71 | unsigned int count; |
71 | 72 | ||
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 504b7d550567..c3a5739030c3 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -140,12 +140,14 @@ struct analog_port { | |||
140 | */ | 140 | */ |
141 | 141 | ||
142 | #ifdef __i386__ | 142 | #ifdef __i386__ |
143 | |||
144 | #include <asm/i8253.h> | ||
145 | |||
143 | #define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) | 146 | #define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) |
144 | #define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0))) | 147 | #define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0))) |
145 | #define TIME_NAME (cpu_has_tsc?"TSC":"PIT") | 148 | #define TIME_NAME (cpu_has_tsc?"TSC":"PIT") |
146 | static unsigned int get_time_pit(void) | 149 | static unsigned int get_time_pit(void) |
147 | { | 150 | { |
148 | extern spinlock_t i8253_lock; | ||
149 | unsigned long flags; | 151 | unsigned long flags; |
150 | unsigned int count; | 152 | unsigned int count; |
151 | 153 | ||
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cabddd49f6ff..d5afd557fe37 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -847,7 +847,7 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); | |||
847 | pcmcia_device_stringattr(prod_id3, prod_id[2]); | 847 | pcmcia_device_stringattr(prod_id3, prod_id[2]); |
848 | pcmcia_device_stringattr(prod_id4, prod_id[3]); | 848 | pcmcia_device_stringattr(prod_id4, prod_id[3]); |
849 | 849 | ||
850 | static ssize_t modalias_show(struct device *dev, char *buf) | 850 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) |
851 | { | 851 | { |
852 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 852 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
853 | int i; | 853 | int i; |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 9224fc3184ea..7e8fc7c1d4cc 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2061,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void) | |||
2061 | up->port.ops = &serial8250_pops; | 2061 | up->port.ops = &serial8250_pops; |
2062 | } | 2062 | } |
2063 | 2063 | ||
2064 | for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); | 2064 | for (i = 0, up = serial8250_ports; |
2065 | i < ARRAY_SIZE(old_serial_port) && i < UART_NR; | ||
2065 | i++, up++) { | 2066 | i++, up++) { |
2066 | up->port.iobase = old_serial_port[i].port; | 2067 | up->port.iobase = old_serial_port[i].port; |
2067 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 2068 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |