diff options
author | Matthew Wilcox <willy@parisc-linux.org> | 2005-10-21 22:58:51 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@parisc-linux.org> | 2005-10-21 22:58:51 -0400 |
commit | 6ab0f5cd364476fe5cb329fd46ee41bea6d4c69c (patch) | |
tree | d89c5f47149b443e05345ed8e7c8c9d8960cfa15 /drivers | |
parent | ae8c75c1c47029a64976690c37336a2be6b49778 (diff) |
[PARISC] Update parisc specific input code from parisc tree
Update drivers to new input layer changes.
Signed-off-by: Helge Deller <deller@parisc-linux.org>
Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
Reorder code in gscps2_interrupt() and only enable ports when opened.
This fixes issues with hangs booting an SMP kernel on my C360.
Previously serio_interrupt() could be called before the lock in
struct serio was initialised.
Signed-off-by: Richard Hirst <rhirst@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/keyboard/hil_kbd.c | 28 | ||||
-rw-r--r-- | drivers/input/keyboard/hilkbd.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/hil_ptr.c | 33 | ||||
-rw-r--r-- | drivers/input/serio/gscps2.c | 13 | ||||
-rw-r--r-- | drivers/input/serio/hil_mlc.c | 14 |
5 files changed, 59 insertions, 31 deletions
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index ef78bffed5e7..0a90962c38e7 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -204,7 +204,7 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio, | |||
204 | hil_packet packet; | 204 | hil_packet packet; |
205 | int idx; | 205 | int idx; |
206 | 206 | ||
207 | kbd = (struct hil_kbd *)serio->private; | 207 | kbd = serio_get_drvdata(serio); |
208 | if (kbd == NULL) { | 208 | if (kbd == NULL) { |
209 | BUG(); | 209 | BUG(); |
210 | return IRQ_HANDLED; | 210 | return IRQ_HANDLED; |
@@ -234,7 +234,7 @@ static void hil_kbd_disconnect(struct serio *serio) | |||
234 | { | 234 | { |
235 | struct hil_kbd *kbd; | 235 | struct hil_kbd *kbd; |
236 | 236 | ||
237 | kbd = (struct hil_kbd *)serio->private; | 237 | kbd = serio_get_drvdata(serio); |
238 | if (kbd == NULL) { | 238 | if (kbd == NULL) { |
239 | BUG(); | 239 | BUG(); |
240 | return; | 240 | return; |
@@ -245,20 +245,20 @@ static void hil_kbd_disconnect(struct serio *serio) | |||
245 | kfree(kbd); | 245 | kfree(kbd); |
246 | } | 246 | } |
247 | 247 | ||
248 | static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | 248 | static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) |
249 | { | 249 | { |
250 | struct hil_kbd *kbd; | 250 | struct hil_kbd *kbd; |
251 | uint8_t did, *idd; | 251 | uint8_t did, *idd; |
252 | int i; | 252 | int i; |
253 | 253 | ||
254 | if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return; | 254 | kbd = kmalloc(sizeof(*kbd), GFP_KERNEL); |
255 | 255 | if (!kbd) | |
256 | if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return; | 256 | return -ENOMEM; |
257 | memset(kbd, 0, sizeof(struct hil_kbd)); | 257 | memset(kbd, 0, sizeof(struct hil_kbd)); |
258 | 258 | ||
259 | if (serio_open(serio, drv)) goto bail0; | 259 | if (serio_open(serio, drv)) goto bail0; |
260 | 260 | ||
261 | serio->private = kbd; | 261 | serio_set_drvdata(serio, kbd); |
262 | kbd->serio = serio; | 262 | kbd->serio = serio; |
263 | kbd->dev.private = kbd; | 263 | kbd->dev.private = kbd; |
264 | 264 | ||
@@ -342,19 +342,31 @@ static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
342 | down(&(kbd->sem)); | 342 | down(&(kbd->sem)); |
343 | up(&(kbd->sem)); | 343 | up(&(kbd->sem)); |
344 | 344 | ||
345 | return; | 345 | return 0; |
346 | bail1: | 346 | bail1: |
347 | serio_close(serio); | 347 | serio_close(serio); |
348 | bail0: | 348 | bail0: |
349 | kfree(kbd); | 349 | kfree(kbd); |
350 | serio_set_drvdata(serio, NULL); | ||
351 | return -EIO; | ||
350 | } | 352 | } |
351 | 353 | ||
354 | static struct serio_device_id hil_kbd_ids[] = { | ||
355 | { | ||
356 | .type = SERIO_HIL_MLC, | ||
357 | .proto = SERIO_HIL, | ||
358 | .id = SERIO_ANY, | ||
359 | .extra = SERIO_ANY, | ||
360 | }, | ||
361 | { 0 } | ||
362 | }; | ||
352 | 363 | ||
353 | struct serio_driver hil_kbd_serio_drv = { | 364 | struct serio_driver hil_kbd_serio_drv = { |
354 | .driver = { | 365 | .driver = { |
355 | .name = "hil_kbd", | 366 | .name = "hil_kbd", |
356 | }, | 367 | }, |
357 | .description = "HP HIL keyboard driver", | 368 | .description = "HP HIL keyboard driver", |
369 | .id_table = hil_kbd_ids, | ||
358 | .connect = hil_kbd_connect, | 370 | .connect = hil_kbd_connect, |
359 | .disconnect = hil_kbd_disconnect, | 371 | .disconnect = hil_kbd_disconnect, |
360 | .interrupt = hil_kbd_interrupt | 372 | .interrupt = hil_kbd_interrupt |
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index e7a1e14f8b0c..e95bc052e32a 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/hil.h> | 26 | #include <linux/hil.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | 28 | ||
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index bc22849c6c79..c2bf2ed07dc6 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c | |||
@@ -196,7 +196,7 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, | |||
196 | hil_packet packet; | 196 | hil_packet packet; |
197 | int idx; | 197 | int idx; |
198 | 198 | ||
199 | ptr = (struct hil_ptr *)serio->private; | 199 | ptr = serio_get_drvdata(serio); |
200 | if (ptr == NULL) { | 200 | if (ptr == NULL) { |
201 | BUG(); | 201 | BUG(); |
202 | return IRQ_HANDLED; | 202 | return IRQ_HANDLED; |
@@ -227,7 +227,7 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
227 | { | 227 | { |
228 | struct hil_ptr *ptr; | 228 | struct hil_ptr *ptr; |
229 | 229 | ||
230 | ptr = (struct hil_ptr *)serio->private; | 230 | ptr = serio_get_drvdata(serio); |
231 | if (ptr == NULL) { | 231 | if (ptr == NULL) { |
232 | BUG(); | 232 | BUG(); |
233 | return; | 233 | return; |
@@ -238,21 +238,19 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
238 | kfree(ptr); | 238 | kfree(ptr); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | 241 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) |
242 | { | 242 | { |
243 | struct hil_ptr *ptr; | 243 | struct hil_ptr *ptr; |
244 | char *txt; | 244 | char *txt; |
245 | unsigned int i, naxsets, btntype; | 245 | unsigned int i, naxsets, btntype; |
246 | uint8_t did, *idd; | 246 | uint8_t did, *idd; |
247 | 247 | ||
248 | if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return; | 248 | if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM; |
249 | |||
250 | if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return; | ||
251 | memset(ptr, 0, sizeof(struct hil_ptr)); | 249 | memset(ptr, 0, sizeof(struct hil_ptr)); |
252 | 250 | ||
253 | if (serio_open(serio, driver)) goto bail0; | 251 | if (serio_open(serio, driver)) goto bail0; |
254 | 252 | ||
255 | serio->private = ptr; | 253 | serio_set_drvdata(serio, ptr); |
256 | ptr->serio = serio; | 254 | ptr->serio = serio; |
257 | ptr->dev.private = ptr; | 255 | ptr->dev.private = ptr; |
258 | 256 | ||
@@ -380,23 +378,34 @@ static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
380 | (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", | 378 | (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", |
381 | did); | 379 | did); |
382 | 380 | ||
383 | return; | 381 | return 0; |
384 | bail1: | 382 | bail1: |
385 | serio_close(serio); | 383 | serio_close(serio); |
386 | bail0: | 384 | bail0: |
387 | kfree(ptr); | 385 | kfree(ptr); |
388 | return; | 386 | serio_set_drvdata(serio, NULL); |
387 | return -ENODEV; | ||
389 | } | 388 | } |
390 | 389 | ||
390 | static struct serio_device_id hil_ptr_ids[] = { | ||
391 | { | ||
392 | .type = SERIO_HIL_MLC, | ||
393 | .proto = SERIO_HIL, | ||
394 | .id = SERIO_ANY, | ||
395 | .extra = SERIO_ANY, | ||
396 | }, | ||
397 | { 0 } | ||
398 | }; | ||
391 | 399 | ||
392 | static struct serio_driver hil_ptr_serio_driver = { | 400 | static struct serio_driver hil_ptr_serio_driver = { |
393 | .driver = { | 401 | .driver = { |
394 | .name = "hil_ptr", | 402 | .name = "hil_ptr", |
395 | }, | 403 | }, |
396 | .description = "HP HIL mouse/tablet driver", | 404 | .description = "HP HIL mouse/tablet driver", |
397 | .connect = hil_ptr_connect, | 405 | .id_table = hil_ptr_ids, |
398 | .disconnect = hil_ptr_disconnect, | 406 | .connect = hil_ptr_connect, |
399 | .interrupt = hil_ptr_interrupt | 407 | .disconnect = hil_ptr_disconnect, |
408 | .interrupt = hil_ptr_interrupt | ||
400 | }; | 409 | }; |
401 | 410 | ||
402 | static int __init hil_ptr_init(void) | 411 | static int __init hil_ptr_init(void) |
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 9790d7169a53..a7b0de0f92b2 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c | |||
@@ -211,9 +211,6 @@ static void gscps2_reset(struct gscps2port *ps2port) | |||
211 | writeb(0xff, addr+GSC_RESET); | 211 | writeb(0xff, addr+GSC_RESET); |
212 | gscps2_flush(ps2port); | 212 | gscps2_flush(ps2port); |
213 | spin_unlock_irqrestore(&ps2port->lock, flags); | 213 | spin_unlock_irqrestore(&ps2port->lock, flags); |
214 | |||
215 | /* enable it */ | ||
216 | gscps2_enable(ps2port, ENABLE); | ||
217 | } | 214 | } |
218 | 215 | ||
219 | static LIST_HEAD(ps2port_list); | 216 | static LIST_HEAD(ps2port_list); |
@@ -307,6 +304,9 @@ static int gscps2_open(struct serio *port) | |||
307 | 304 | ||
308 | gscps2_reset(ps2port); | 305 | gscps2_reset(ps2port); |
309 | 306 | ||
307 | /* enable it */ | ||
308 | gscps2_enable(ps2port, ENABLE); | ||
309 | |||
310 | gscps2_interrupt(0, NULL, NULL); | 310 | gscps2_interrupt(0, NULL, NULL); |
311 | 311 | ||
312 | return 0; | 312 | return 0; |
@@ -370,8 +370,6 @@ static int __init gscps2_probe(struct parisc_device *dev) | |||
370 | serio->port_data = ps2port; | 370 | serio->port_data = ps2port; |
371 | serio->dev.parent = &dev->dev; | 371 | serio->dev.parent = &dev->dev; |
372 | 372 | ||
373 | list_add_tail(&ps2port->node, &ps2port_list); | ||
374 | |||
375 | ret = -EBUSY; | 373 | ret = -EBUSY; |
376 | if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port)) | 374 | if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port)) |
377 | goto fail_miserably; | 375 | goto fail_miserably; |
@@ -396,15 +394,16 @@ static int __init gscps2_probe(struct parisc_device *dev) | |||
396 | 394 | ||
397 | serio_register_port(ps2port->port); | 395 | serio_register_port(ps2port->port); |
398 | 396 | ||
397 | list_add_tail(&ps2port->node, &ps2port_list); | ||
398 | |||
399 | return 0; | 399 | return 0; |
400 | 400 | ||
401 | fail: | 401 | fail: |
402 | free_irq(dev->irq, ps2port); | 402 | free_irq(dev->irq, ps2port); |
403 | 403 | ||
404 | fail_miserably: | 404 | fail_miserably: |
405 | list_del(&ps2port->node); | ||
406 | iounmap(ps2port->addr); | 405 | iounmap(ps2port->addr); |
407 | release_mem_region(dev->hpa, GSC_STATUS + 4); | 406 | release_mem_region(dev->hpa.start, GSC_STATUS + 4); |
408 | 407 | ||
409 | fail_nomem: | 408 | fail_nomem: |
410 | kfree(ps2port); | 409 | kfree(ps2port); |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index c243cb6fdfc4..5704204964a3 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -801,7 +801,8 @@ static int hil_mlc_serio_open(struct serio *serio) { | |||
801 | struct hil_mlc_serio_map *map; | 801 | struct hil_mlc_serio_map *map; |
802 | struct hil_mlc *mlc; | 802 | struct hil_mlc *mlc; |
803 | 803 | ||
804 | if (serio->private != NULL) return -EBUSY; | 804 | if (serio_get_drvdata(serio) != NULL) |
805 | return -EBUSY; | ||
805 | 806 | ||
806 | map = serio->port_data; | 807 | map = serio->port_data; |
807 | if (map == NULL) { | 808 | if (map == NULL) { |
@@ -832,11 +833,18 @@ static void hil_mlc_serio_close(struct serio *serio) { | |||
832 | return; | 833 | return; |
833 | } | 834 | } |
834 | 835 | ||
835 | serio->private = NULL; | 836 | serio_set_drvdata(serio, NULL); |
836 | serio->drv = NULL; | 837 | serio->drv = NULL; |
837 | /* TODO wake up interruptable */ | 838 | /* TODO wake up interruptable */ |
838 | } | 839 | } |
839 | 840 | ||
841 | static struct serio_device_id hil_mlc_serio_id = { | ||
842 | .type = SERIO_HIL_MLC, | ||
843 | .proto = SERIO_HIL, | ||
844 | .extra = SERIO_ANY, | ||
845 | .id = SERIO_ANY, | ||
846 | }; | ||
847 | |||
840 | int hil_mlc_register(hil_mlc *mlc) { | 848 | int hil_mlc_register(hil_mlc *mlc) { |
841 | int i; | 849 | int i; |
842 | unsigned long flags; | 850 | unsigned long flags; |
@@ -867,7 +875,7 @@ int hil_mlc_register(hil_mlc *mlc) { | |||
867 | mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL); | 875 | mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL); |
868 | mlc->serio[i] = mlc_serio; | 876 | mlc->serio[i] = mlc_serio; |
869 | memset(mlc_serio, 0, sizeof(*mlc_serio)); | 877 | memset(mlc_serio, 0, sizeof(*mlc_serio)); |
870 | mlc_serio->type = SERIO_HIL | SERIO_HIL_MLC; | 878 | mlc_serio->id = hil_mlc_serio_id; |
871 | mlc_serio->write = hil_mlc_serio_write; | 879 | mlc_serio->write = hil_mlc_serio_write; |
872 | mlc_serio->open = hil_mlc_serio_open; | 880 | mlc_serio->open = hil_mlc_serio_open; |
873 | mlc_serio->close = hil_mlc_serio_close; | 881 | mlc_serio->close = hil_mlc_serio_close; |