diff options
Diffstat (limited to 'drivers/input')
66 files changed, 1694 insertions, 492 deletions
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 35656cadc914..783b3412cead 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -203,7 +203,7 @@ static int erase_effect(struct input_dev *dev, int effect_id, | |||
203 | } | 203 | } |
204 | 204 | ||
205 | /** | 205 | /** |
206 | * input_ff_erase - erase an effect from device | 206 | * input_ff_erase - erase a force-feedback effect from device |
207 | * @dev: input device to erase effect from | 207 | * @dev: input device to erase effect from |
208 | * @effect_id: id of the ffect to be erased | 208 | * @effect_id: id of the ffect to be erased |
209 | * @file: purported owner of the request | 209 | * @file: purported owner of the request |
@@ -347,7 +347,7 @@ EXPORT_SYMBOL_GPL(input_ff_create); | |||
347 | 347 | ||
348 | /** | 348 | /** |
349 | * input_ff_free() - frees force feedback portion of input device | 349 | * input_ff_free() - frees force feedback portion of input device |
350 | * @dev: input device supporintg force feedback | 350 | * @dev: input device supporting force feedback |
351 | * | 351 | * |
352 | * This function is only needed in error path as input core will | 352 | * This function is only needed in error path as input core will |
353 | * automatically free force feedback structures when device is | 353 | * automatically free force feedback structures when device is |
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index cd8b7297e6df..eba18b6ac5e4 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
@@ -460,7 +460,7 @@ static void ml_ff_destroy(struct ff_device *ff) | |||
460 | } | 460 | } |
461 | 461 | ||
462 | /** | 462 | /** |
463 | * input_ff_create_memless() - create memoryless FF device | 463 | * input_ff_create_memless() - create memoryless force-feedback device |
464 | * @dev: input device supporting force-feedback | 464 | * @dev: input device supporting force-feedback |
465 | * @data: driver-specific data to be passed into @play_effect | 465 | * @data: driver-specific data to be passed into @play_effect |
466 | * @play_effect: driver-specific method for playing FF effect | 466 | * @play_effect: driver-specific method for playing FF effect |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 79dfb4b25c97..a00fe470a829 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -731,12 +731,6 @@ static int gameport_driver_remove(struct device *dev) | |||
731 | return 0; | 731 | return 0; |
732 | } | 732 | } |
733 | 733 | ||
734 | static struct bus_type gameport_bus = { | ||
735 | .name = "gameport", | ||
736 | .probe = gameport_driver_probe, | ||
737 | .remove = gameport_driver_remove, | ||
738 | }; | ||
739 | |||
740 | static void gameport_add_driver(struct gameport_driver *drv) | 734 | static void gameport_add_driver(struct gameport_driver *drv) |
741 | { | 735 | { |
742 | int error; | 736 | int error; |
@@ -782,6 +776,15 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv) | |||
782 | return !gameport_drv->ignore; | 776 | return !gameport_drv->ignore; |
783 | } | 777 | } |
784 | 778 | ||
779 | static struct bus_type gameport_bus = { | ||
780 | .name = "gameport", | ||
781 | .dev_attrs = gameport_device_attrs, | ||
782 | .drv_attrs = gameport_driver_attrs, | ||
783 | .match = gameport_bus_match, | ||
784 | .probe = gameport_driver_probe, | ||
785 | .remove = gameport_driver_remove, | ||
786 | }; | ||
787 | |||
785 | static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv) | 788 | static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv) |
786 | { | 789 | { |
787 | mutex_lock(&gameport->drv_mutex); | 790 | mutex_lock(&gameport->drv_mutex); |
@@ -791,7 +794,6 @@ static void gameport_set_drv(struct gameport *gameport, struct gameport_driver * | |||
791 | 794 | ||
792 | int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) | 795 | int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) |
793 | { | 796 | { |
794 | |||
795 | if (gameport->open) { | 797 | if (gameport->open) { |
796 | if (gameport->open(gameport, mode)) { | 798 | if (gameport->open(gameport, mode)) { |
797 | return -1; | 799 | return -1; |
@@ -819,9 +821,6 @@ static int __init gameport_init(void) | |||
819 | { | 821 | { |
820 | int error; | 822 | int error; |
821 | 823 | ||
822 | gameport_bus.dev_attrs = gameport_device_attrs; | ||
823 | gameport_bus.drv_attrs = gameport_driver_attrs; | ||
824 | gameport_bus.match = gameport_bus_match; | ||
825 | error = bus_register(&gameport_bus); | 824 | error = bus_register(&gameport_bus); |
826 | if (error) { | 825 | if (error) { |
827 | printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); | 826 | printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); |
diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c index d65d81080257..6b4d4561d465 100644 --- a/drivers/input/gameport/lightning.c +++ b/drivers/input/gameport/lightning.c | |||
@@ -309,7 +309,7 @@ static int __init l4_init(void) | |||
309 | int i, cards = 0; | 309 | int i, cards = 0; |
310 | 310 | ||
311 | if (!request_region(L4_PORT, 1, "lightning")) | 311 | if (!request_region(L4_PORT, 1, "lightning")) |
312 | return -1; | 312 | return -EBUSY; |
313 | 313 | ||
314 | for (i = 0; i < 2; i++) | 314 | for (i = 0; i < 2; i++) |
315 | if (l4_add_card(i) == 0) | 315 | if (l4_add_card(i) == 0) |
@@ -319,7 +319,7 @@ static int __init l4_init(void) | |||
319 | 319 | ||
320 | if (!cards) { | 320 | if (!cards) { |
321 | release_region(L4_PORT, 1); | 321 | release_region(L4_PORT, 1); |
322 | return -1; | 322 | return -ENODEV; |
323 | } | 323 | } |
324 | 324 | ||
325 | return 0; | 325 | return 0; |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 1c8c8a5bc4a9..7cf2b4f603a3 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -37,7 +37,7 @@ static struct input_handler *input_table[8]; | |||
37 | 37 | ||
38 | /** | 38 | /** |
39 | * input_event() - report new input event | 39 | * input_event() - report new input event |
40 | * @handle: device that generated the event | 40 | * @dev: device that generated the event |
41 | * @type: type of the event | 41 | * @type: type of the event |
42 | * @code: event code | 42 | * @code: event code |
43 | * @value: value of the event | 43 | * @value: value of the event |
@@ -900,6 +900,15 @@ struct class input_class = { | |||
900 | }; | 900 | }; |
901 | EXPORT_SYMBOL_GPL(input_class); | 901 | EXPORT_SYMBOL_GPL(input_class); |
902 | 902 | ||
903 | /** | ||
904 | * input_allocate_device - allocate memory for new input device | ||
905 | * | ||
906 | * Returns prepared struct input_dev or NULL. | ||
907 | * | ||
908 | * NOTE: Use input_free_device() to free devices that have not been | ||
909 | * registered; input_unregister_device() should be used for already | ||
910 | * registered devices. | ||
911 | */ | ||
903 | struct input_dev *input_allocate_device(void) | 912 | struct input_dev *input_allocate_device(void) |
904 | { | 913 | { |
905 | struct input_dev *dev; | 914 | struct input_dev *dev; |
@@ -919,6 +928,20 @@ struct input_dev *input_allocate_device(void) | |||
919 | } | 928 | } |
920 | EXPORT_SYMBOL(input_allocate_device); | 929 | EXPORT_SYMBOL(input_allocate_device); |
921 | 930 | ||
931 | /** | ||
932 | * input_free_device - free memory occupied by input_dev structure | ||
933 | * @dev: input device to free | ||
934 | * | ||
935 | * This function should only be used if input_register_device() | ||
936 | * was not called yet or if it failed. Once device was registered | ||
937 | * use input_unregister_device() and memory will be freed once last | ||
938 | * refrence to the device is dropped. | ||
939 | * | ||
940 | * Device should be allocated by input_allocate_device(). | ||
941 | * | ||
942 | * NOTE: If there are references to the input device then memory | ||
943 | * will not be freed until last reference is dropped. | ||
944 | */ | ||
922 | void input_free_device(struct input_dev *dev) | 945 | void input_free_device(struct input_dev *dev) |
923 | { | 946 | { |
924 | if (dev) { | 947 | if (dev) { |
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 704bf70f1db7..6279ced8a35b 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c | |||
@@ -521,11 +521,19 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
521 | for (i = 0; i < 2; i++) | 521 | for (i = 0; i < 2; i++) |
522 | if (port->adi[i].length > 0) { | 522 | if (port->adi[i].length > 0) { |
523 | adi_init_center(port->adi + i); | 523 | adi_init_center(port->adi + i); |
524 | input_register_device(port->adi[i].dev); | 524 | err = input_register_device(port->adi[i].dev); |
525 | if (err) | ||
526 | goto fail3; | ||
525 | } | 527 | } |
526 | 528 | ||
527 | return 0; | 529 | return 0; |
528 | 530 | ||
531 | fail3: while (--i >= 0) { | ||
532 | if (port->adi[i].length > 0) { | ||
533 | input_unregister_device(port->adi[i].dev); | ||
534 | port->adi[i].dev = NULL; | ||
535 | } | ||
536 | } | ||
529 | fail2: for (i = 0; i < 2; i++) | 537 | fail2: for (i = 0; i < 2; i++) |
530 | if (port->adi[i].dev) | 538 | if (port->adi[i].dev) |
531 | input_free_device(port->adi[i].dev); | 539 | input_free_device(port->adi[i].dev); |
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 650acf3a30b7..e608691b5a61 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c | |||
@@ -147,7 +147,11 @@ static int __init amijoy_init(void) | |||
147 | amijoy_dev[i]->absmax[ABS_X + j] = 1; | 147 | amijoy_dev[i]->absmax[ABS_X + j] = 1; |
148 | } | 148 | } |
149 | 149 | ||
150 | input_register_device(amijoy_dev[i]); | 150 | err = input_register_device(amijoy_dev[i]); |
151 | if (err) { | ||
152 | input_free_device(amijoy_dev[i]); | ||
153 | goto fail; | ||
154 | } | ||
151 | } | 155 | } |
152 | return 0; | 156 | return 0; |
153 | 157 | ||
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index e9a02db36ecc..7ef68456d7d6 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -434,6 +434,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i | |||
434 | { | 434 | { |
435 | struct input_dev *input_dev; | 435 | struct input_dev *input_dev; |
436 | int i, j, t, v, w, x, y, z; | 436 | int i, j, t, v, w, x, y, z; |
437 | int error; | ||
437 | 438 | ||
438 | analog_name(analog); | 439 | analog_name(analog); |
439 | snprintf(analog->phys, sizeof(analog->phys), | 440 | snprintf(analog->phys, sizeof(analog->phys), |
@@ -505,7 +506,11 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i | |||
505 | 506 | ||
506 | analog_decode(analog, port->axes, port->initial, port->buttons); | 507 | analog_decode(analog, port->axes, port->initial, port->buttons); |
507 | 508 | ||
508 | input_register_device(analog->dev); | 509 | error = input_register_device(analog->dev); |
510 | if (error) { | ||
511 | input_free_device(analog->dev); | ||
512 | return error; | ||
513 | } | ||
509 | 514 | ||
510 | return 0; | 515 | return 0; |
511 | } | 516 | } |
@@ -668,7 +673,8 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv | |||
668 | return 0; | 673 | return 0; |
669 | 674 | ||
670 | fail3: while (--i >= 0) | 675 | fail3: while (--i >= 0) |
671 | input_unregister_device(port->analog[i].dev); | 676 | if (port->analog[i].mask) |
677 | input_unregister_device(port->analog[i].dev); | ||
672 | fail2: gameport_close(gameport); | 678 | fail2: gameport_close(gameport); |
673 | fail1: gameport_set_drvdata(gameport, NULL); | 679 | fail1: gameport_set_drvdata(gameport, NULL); |
674 | kfree(port); | 680 | kfree(port); |
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index d5e42eb88a20..034ec39c251d 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c | |||
@@ -223,12 +223,15 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
223 | for (j = 0; cobra_btn[j]; j++) | 223 | for (j = 0; cobra_btn[j]; j++) |
224 | set_bit(cobra_btn[j], input_dev->keybit); | 224 | set_bit(cobra_btn[j], input_dev->keybit); |
225 | 225 | ||
226 | input_register_device(cobra->dev[i]); | 226 | err = input_register_device(cobra->dev[i]); |
227 | if (err) | ||
228 | goto fail4; | ||
227 | } | 229 | } |
228 | 230 | ||
229 | return 0; | 231 | return 0; |
230 | 232 | ||
231 | fail3: for (i = 0; i < 2; i++) | 233 | fail4: input_free_device(cobra->dev[i]); |
234 | fail3: while (--i >= 0) | ||
232 | if (cobra->dev[i]) | 235 | if (cobra->dev[i]) |
233 | input_unregister_device(cobra->dev[i]); | 236 | input_unregister_device(cobra->dev[i]); |
234 | fail2: gameport_close(gameport); | 237 | fail2: gameport_close(gameport); |
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index e4a699f6ec87..bacbab5d1b6f 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -341,7 +341,9 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
341 | input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; | 341 | input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; |
342 | } | 342 | } |
343 | 343 | ||
344 | input_register_device(gf2k->dev); | 344 | err = input_register_device(gf2k->dev); |
345 | if (err) | ||
346 | goto fail2; | ||
345 | 347 | ||
346 | return 0; | 348 | return 0; |
347 | 349 | ||
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 62438944a69a..8120a9c40773 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c | |||
@@ -423,7 +423,10 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) | |||
423 | 423 | ||
424 | if (!port->registered) { | 424 | if (!port->registered) { |
425 | dbg("New Grip pad in multiport slot %d.\n", slot); | 425 | dbg("New Grip pad in multiport slot %d.\n", slot); |
426 | register_slot(slot, grip); | 426 | if (register_slot(slot, grip)) { |
427 | port->mode = GRIP_MODE_RESET; | ||
428 | port->dirty = 0; | ||
429 | } | ||
427 | } | 430 | } |
428 | return flags; | 431 | return flags; |
429 | } | 432 | } |
@@ -585,6 +588,7 @@ static int register_slot(int slot, struct grip_mp *grip) | |||
585 | struct grip_port *port = grip->port[slot]; | 588 | struct grip_port *port = grip->port[slot]; |
586 | struct input_dev *input_dev; | 589 | struct input_dev *input_dev; |
587 | int j, t; | 590 | int j, t; |
591 | int err; | ||
588 | 592 | ||
589 | port->dev = input_dev = input_allocate_device(); | 593 | port->dev = input_dev = input_allocate_device(); |
590 | if (!input_dev) | 594 | if (!input_dev) |
@@ -610,7 +614,12 @@ static int register_slot(int slot, struct grip_mp *grip) | |||
610 | if (t > 0) | 614 | if (t > 0) |
611 | set_bit(t, input_dev->keybit); | 615 | set_bit(t, input_dev->keybit); |
612 | 616 | ||
613 | input_register_device(port->dev); | 617 | err = input_register_device(port->dev); |
618 | if (err) { | ||
619 | input_free_device(port->dev); | ||
620 | return err; | ||
621 | } | ||
622 | |||
614 | port->registered = 1; | 623 | port->registered = 1; |
615 | 624 | ||
616 | if (port->dirty) /* report initial state, if any */ | 625 | if (port->dirty) /* report initial state, if any */ |
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 840ed9b512b2..dbc5d92858b8 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c | |||
@@ -250,7 +250,9 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * | |||
250 | for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++) | 250 | for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++) |
251 | set_bit(t, input_dev->keybit); | 251 | set_bit(t, input_dev->keybit); |
252 | 252 | ||
253 | input_register_device(guillemot->dev); | 253 | err = input_register_device(guillemot->dev); |
254 | if (err) | ||
255 | goto fail2; | ||
254 | 256 | ||
255 | return 0; | 257 | return 0; |
256 | 258 | ||
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 24c684bc6337..3393a37fec39 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -325,8 +325,8 @@ int iforce_init_device(struct iforce *iforce) | |||
325 | 325 | ||
326 | if (i == 20) { /* 5 seconds */ | 326 | if (i == 20) { /* 5 seconds */ |
327 | printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); | 327 | printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); |
328 | input_free_device(input_dev); | 328 | error = -ENODEV; |
329 | return -ENODEV; | 329 | goto fail; |
330 | } | 330 | } |
331 | 331 | ||
332 | /* | 332 | /* |
@@ -439,10 +439,8 @@ int iforce_init_device(struct iforce *iforce) | |||
439 | set_bit(iforce->type->ff[i], input_dev->ffbit); | 439 | set_bit(iforce->type->ff[i], input_dev->ffbit); |
440 | 440 | ||
441 | error = input_ff_create(input_dev, ff_effects); | 441 | error = input_ff_create(input_dev, ff_effects); |
442 | if (error) { | 442 | if (error) |
443 | input_free_device(input_dev); | 443 | goto fail; |
444 | return error; | ||
445 | } | ||
446 | 444 | ||
447 | ff = input_dev->ff; | 445 | ff = input_dev->ff; |
448 | ff->upload = iforce_upload_effect; | 446 | ff->upload = iforce_upload_effect; |
@@ -455,22 +453,35 @@ int iforce_init_device(struct iforce *iforce) | |||
455 | * Register input device. | 453 | * Register input device. |
456 | */ | 454 | */ |
457 | 455 | ||
458 | input_register_device(iforce->dev); | 456 | error = input_register_device(iforce->dev); |
457 | if (error) | ||
458 | goto fail; | ||
459 | 459 | ||
460 | printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); | 460 | printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); |
461 | 461 | ||
462 | return 0; | 462 | return 0; |
463 | |||
464 | fail: input_free_device(input_dev); | ||
465 | return error; | ||
463 | } | 466 | } |
464 | 467 | ||
465 | static int __init iforce_init(void) | 468 | static int __init iforce_init(void) |
466 | { | 469 | { |
470 | int err = 0; | ||
471 | |||
467 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | 472 | #ifdef CONFIG_JOYSTICK_IFORCE_USB |
468 | usb_register(&iforce_usb_driver); | 473 | err = usb_register(&iforce_usb_driver); |
474 | if (err) | ||
475 | return err; | ||
469 | #endif | 476 | #endif |
470 | #ifdef CONFIG_JOYSTICK_IFORCE_232 | 477 | #ifdef CONFIG_JOYSTICK_IFORCE_232 |
471 | serio_register_driver(&iforce_serio_drv); | 478 | err = serio_register_driver(&iforce_serio_drv); |
479 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | ||
480 | if (err) | ||
481 | usb_deregister(&iforce_usb_driver); | ||
472 | #endif | 482 | #endif |
473 | return 0; | 483 | #endif |
484 | return err; | ||
474 | } | 485 | } |
475 | 486 | ||
476 | static void __exit iforce_exit(void) | 487 | static void __exit iforce_exit(void) |
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index ca08f45c2040..ec4be535f483 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c | |||
@@ -141,21 +141,19 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv) | |||
141 | serio_set_drvdata(serio, iforce); | 141 | serio_set_drvdata(serio, iforce); |
142 | 142 | ||
143 | err = serio_open(serio, drv); | 143 | err = serio_open(serio, drv); |
144 | if (err) { | 144 | if (err) |
145 | serio_set_drvdata(serio, NULL); | 145 | goto fail1; |
146 | kfree(iforce); | ||
147 | return err; | ||
148 | } | ||
149 | 146 | ||
150 | err = iforce_init_device(iforce); | 147 | err = iforce_init_device(iforce); |
151 | if (err) { | 148 | if (err) |
152 | serio_close(serio); | 149 | goto fail2; |
153 | serio_set_drvdata(serio, NULL); | ||
154 | kfree(iforce); | ||
155 | return -ENODEV; | ||
156 | } | ||
157 | 150 | ||
158 | return 0; | 151 | return 0; |
152 | |||
153 | fail2: serio_close(serio); | ||
154 | fail1: serio_set_drvdata(serio, NULL); | ||
155 | kfree(iforce); | ||
156 | return err; | ||
159 | } | 157 | } |
160 | 158 | ||
161 | static void iforce_serio_disconnect(struct serio *serio) | 159 | static void iforce_serio_disconnect(struct serio *serio) |
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index bbfeb9c59b87..fec8b3d0967d 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c | |||
@@ -283,7 +283,9 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d | |||
283 | for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) | 283 | for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) |
284 | set_bit(t, input_dev->keybit); | 284 | set_bit(t, input_dev->keybit); |
285 | 285 | ||
286 | input_register_device(interact->dev); | 286 | err = input_register_device(interact->dev); |
287 | if (err) | ||
288 | goto fail2; | ||
287 | 289 | ||
288 | return 0; | 290 | return 0; |
289 | 291 | ||
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index e3d19444ba2e..4112789f1196 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c | |||
@@ -157,7 +157,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) | |||
157 | magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL); | 157 | magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL); |
158 | input_dev = input_allocate_device(); | 158 | input_dev = input_allocate_device(); |
159 | if (!magellan || !input_dev) | 159 | if (!magellan || !input_dev) |
160 | goto fail; | 160 | goto fail1; |
161 | 161 | ||
162 | magellan->dev = input_dev; | 162 | magellan->dev = input_dev; |
163 | snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys); | 163 | snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys); |
@@ -183,13 +183,17 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) | |||
183 | 183 | ||
184 | err = serio_open(serio, drv); | 184 | err = serio_open(serio, drv); |
185 | if (err) | 185 | if (err) |
186 | goto fail; | 186 | goto fail2; |
187 | |||
188 | err = input_register_device(magellan->dev); | ||
189 | if (err) | ||
190 | goto fail3; | ||
187 | 191 | ||
188 | input_register_device(magellan->dev); | ||
189 | return 0; | 192 | return 0; |
190 | 193 | ||
191 | fail: serio_set_drvdata(serio, NULL); | 194 | fail3: serio_close(serio); |
192 | input_free_device(input_dev); | 195 | fail2: serio_set_drvdata(serio, NULL); |
196 | fail1: input_free_device(input_dev); | ||
193 | kfree(magellan); | 197 | kfree(magellan); |
194 | return err; | 198 | return err; |
195 | } | 199 | } |
@@ -227,8 +231,7 @@ static struct serio_driver magellan_drv = { | |||
227 | 231 | ||
228 | static int __init magellan_init(void) | 232 | static int __init magellan_init(void) |
229 | { | 233 | { |
230 | serio_register_driver(&magellan_drv); | 234 | return serio_register_driver(&magellan_drv); |
231 | return 0; | ||
232 | } | 235 | } |
233 | 236 | ||
234 | static void __exit magellan_exit(void) | 237 | static void __exit magellan_exit(void) |
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 2a9808cf826f..08bf113e62eb 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c | |||
@@ -215,7 +215,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) | |||
215 | spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); | 215 | spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); |
216 | input_dev = input_allocate_device(); | 216 | input_dev = input_allocate_device(); |
217 | if (!spaceball || !input_dev) | 217 | if (!spaceball || !input_dev) |
218 | goto fail; | 218 | goto fail1; |
219 | 219 | ||
220 | spaceball->dev = input_dev; | 220 | spaceball->dev = input_dev; |
221 | snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); | 221 | snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); |
@@ -252,13 +252,17 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) | |||
252 | 252 | ||
253 | err = serio_open(serio, drv); | 253 | err = serio_open(serio, drv); |
254 | if (err) | 254 | if (err) |
255 | goto fail; | 255 | goto fail2; |
256 | |||
257 | err = input_register_device(spaceball->dev); | ||
258 | if (err) | ||
259 | goto fail3; | ||
256 | 260 | ||
257 | input_register_device(spaceball->dev); | ||
258 | return 0; | 261 | return 0; |
259 | 262 | ||
260 | fail: serio_set_drvdata(serio, NULL); | 263 | fail3: serio_close(serio); |
261 | input_free_device(input_dev); | 264 | fail2: serio_set_drvdata(serio, NULL); |
265 | fail1: input_free_device(input_dev); | ||
262 | kfree(spaceball); | 266 | kfree(spaceball); |
263 | return err; | 267 | return err; |
264 | } | 268 | } |
@@ -296,8 +300,7 @@ static struct serio_driver spaceball_drv = { | |||
296 | 300 | ||
297 | static int __init spaceball_init(void) | 301 | static int __init spaceball_init(void) |
298 | { | 302 | { |
299 | serio_register_driver(&spaceball_drv); | 303 | return serio_register_driver(&spaceball_drv); |
300 | return 0; | ||
301 | } | 304 | } |
302 | 305 | ||
303 | static void __exit spaceball_exit(void) | 306 | static void __exit spaceball_exit(void) |
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index c4db0247c5fb..c9c79211af71 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c | |||
@@ -172,7 +172,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) | |||
172 | spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL); | 172 | spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL); |
173 | input_dev = input_allocate_device(); | 173 | input_dev = input_allocate_device(); |
174 | if (!spaceorb || !input_dev) | 174 | if (!spaceorb || !input_dev) |
175 | goto fail; | 175 | goto fail1; |
176 | 176 | ||
177 | spaceorb->dev = input_dev; | 177 | spaceorb->dev = input_dev; |
178 | snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys); | 178 | snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys); |
@@ -198,13 +198,17 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) | |||
198 | 198 | ||
199 | err = serio_open(serio, drv); | 199 | err = serio_open(serio, drv); |
200 | if (err) | 200 | if (err) |
201 | goto fail; | 201 | goto fail2; |
202 | |||
203 | err = input_register_device(spaceorb->dev); | ||
204 | if (err) | ||
205 | goto fail3; | ||
202 | 206 | ||
203 | input_register_device(spaceorb->dev); | ||
204 | return 0; | 207 | return 0; |
205 | 208 | ||
206 | fail: serio_set_drvdata(serio, NULL); | 209 | fail3: serio_close(serio); |
207 | input_free_device(input_dev); | 210 | fail2: serio_set_drvdata(serio, NULL); |
211 | fail1: input_free_device(input_dev); | ||
208 | kfree(spaceorb); | 212 | kfree(spaceorb); |
209 | return err; | 213 | return err; |
210 | } | 214 | } |
@@ -242,8 +246,7 @@ static struct serio_driver spaceorb_drv = { | |||
242 | 246 | ||
243 | static int __init spaceorb_init(void) | 247 | static int __init spaceorb_init(void) |
244 | { | 248 | { |
245 | serio_register_driver(&spaceorb_drv); | 249 | return serio_register_driver(&spaceorb_drv); |
246 | return 0; | ||
247 | } | 250 | } |
248 | 251 | ||
249 | static void __exit spaceorb_exit(void) | 252 | static void __exit spaceorb_exit(void) |
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 1ffb03223311..ecb0916215fa 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c | |||
@@ -143,7 +143,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) | |||
143 | stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL); | 143 | stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL); |
144 | input_dev = input_allocate_device(); | 144 | input_dev = input_allocate_device(); |
145 | if (!stinger || !input_dev) | 145 | if (!stinger || !input_dev) |
146 | goto fail; | 146 | goto fail1; |
147 | 147 | ||
148 | stinger->dev = input_dev; | 148 | stinger->dev = input_dev; |
149 | snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); | 149 | snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); |
@@ -168,13 +168,17 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) | |||
168 | 168 | ||
169 | err = serio_open(serio, drv); | 169 | err = serio_open(serio, drv); |
170 | if (err) | 170 | if (err) |
171 | goto fail; | 171 | goto fail2; |
172 | |||
173 | err = input_register_device(stinger->dev); | ||
174 | if (err) | ||
175 | goto fail3; | ||
172 | 176 | ||
173 | input_register_device(stinger->dev); | ||
174 | return 0; | 177 | return 0; |
175 | 178 | ||
176 | fail: serio_set_drvdata(serio, NULL); | 179 | fail3: serio_close(serio); |
177 | input_free_device(input_dev); | 180 | fail2: serio_set_drvdata(serio, NULL); |
181 | fail1: input_free_device(input_dev); | ||
178 | kfree(stinger); | 182 | kfree(stinger); |
179 | return err; | 183 | return err; |
180 | } | 184 | } |
@@ -212,8 +216,7 @@ static struct serio_driver stinger_drv = { | |||
212 | 216 | ||
213 | static int __init stinger_init(void) | 217 | static int __init stinger_init(void) |
214 | { | 218 | { |
215 | serio_register_driver(&stinger_drv); | 219 | return serio_register_driver(&stinger_drv); |
216 | return 0; | ||
217 | } | 220 | } |
218 | 221 | ||
219 | static void __exit stinger_exit(void) | 222 | static void __exit stinger_exit(void) |
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 49085df2d631..9cf17d6ced82 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c | |||
@@ -194,7 +194,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) | |||
194 | twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL); | 194 | twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL); |
195 | input_dev = input_allocate_device(); | 195 | input_dev = input_allocate_device(); |
196 | if (!twidjoy || !input_dev) | 196 | if (!twidjoy || !input_dev) |
197 | goto fail; | 197 | goto fail1; |
198 | 198 | ||
199 | twidjoy->dev = input_dev; | 199 | twidjoy->dev = input_dev; |
200 | snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys); | 200 | snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys); |
@@ -221,13 +221,17 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) | |||
221 | 221 | ||
222 | err = serio_open(serio, drv); | 222 | err = serio_open(serio, drv); |
223 | if (err) | 223 | if (err) |
224 | goto fail; | 224 | goto fail2; |
225 | |||
226 | err = input_register_device(twidjoy->dev); | ||
227 | if (err) | ||
228 | goto fail3; | ||
225 | 229 | ||
226 | input_register_device(twidjoy->dev); | ||
227 | return 0; | 230 | return 0; |
228 | 231 | ||
229 | fail: serio_set_drvdata(serio, NULL); | 232 | fail3: serio_close(serio); |
230 | input_free_device(input_dev); | 233 | fail2: serio_set_drvdata(serio, NULL); |
234 | fail1: input_free_device(input_dev); | ||
231 | kfree(twidjoy); | 235 | kfree(twidjoy); |
232 | return err; | 236 | return err; |
233 | } | 237 | } |
@@ -265,8 +269,7 @@ static struct serio_driver twidjoy_drv = { | |||
265 | 269 | ||
266 | static int __init twidjoy_init(void) | 270 | static int __init twidjoy_init(void) |
267 | { | 271 | { |
268 | serio_register_driver(&twidjoy_drv); | 272 | return serio_register_driver(&twidjoy_drv); |
269 | return 0; | ||
270 | } | 273 | } |
271 | 274 | ||
272 | static void __exit twidjoy_exit(void) | 275 | static void __exit twidjoy_exit(void) |
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 35edea1ab955..29d339acf430 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c | |||
@@ -149,7 +149,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) | |||
149 | warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL); | 149 | warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL); |
150 | input_dev = input_allocate_device(); | 150 | input_dev = input_allocate_device(); |
151 | if (!warrior || !input_dev) | 151 | if (!warrior || !input_dev) |
152 | goto fail; | 152 | goto fail1; |
153 | 153 | ||
154 | warrior->dev = input_dev; | 154 | warrior->dev = input_dev; |
155 | snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys); | 155 | snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys); |
@@ -176,13 +176,17 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) | |||
176 | 176 | ||
177 | err = serio_open(serio, drv); | 177 | err = serio_open(serio, drv); |
178 | if (err) | 178 | if (err) |
179 | goto fail; | 179 | goto fail2; |
180 | |||
181 | err = input_register_device(warrior->dev); | ||
182 | if (err) | ||
183 | goto fail3; | ||
180 | 184 | ||
181 | input_register_device(warrior->dev); | ||
182 | return 0; | 185 | return 0; |
183 | 186 | ||
184 | fail: serio_set_drvdata(serio, NULL); | 187 | fail3: serio_close(serio); |
185 | input_free_device(input_dev); | 188 | fail2: serio_set_drvdata(serio, NULL); |
189 | fail1: input_free_device(input_dev); | ||
186 | kfree(warrior); | 190 | kfree(warrior); |
187 | return err; | 191 | return err; |
188 | } | 192 | } |
@@ -220,8 +224,7 @@ static struct serio_driver warrior_drv = { | |||
220 | 224 | ||
221 | static int __init warrior_init(void) | 225 | static int __init warrior_init(void) |
222 | { | 226 | { |
223 | serio_register_driver(&warrior_drv); | 227 | return serio_register_driver(&warrior_drv); |
224 | return 0; | ||
225 | } | 228 | } |
226 | 229 | ||
227 | static void __exit warrior_exit(void) | 230 | static void __exit warrior_exit(void) |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 81a333f73010..049f2f544e75 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -203,4 +203,15 @@ config KEYBOARD_OMAP | |||
203 | To compile this driver as a module, choose M here: the | 203 | To compile this driver as a module, choose M here: the |
204 | module will be called omap-keypad. | 204 | module will be called omap-keypad. |
205 | 205 | ||
206 | config KEYBOARD_AAED2000 | ||
207 | tristate "AAED-2000 keyboard" | ||
208 | depends on MACH_AAED2000 | ||
209 | default y | ||
210 | help | ||
211 | Say Y here to enable the keyboard on the Agilent AAED-2000 | ||
212 | development board. | ||
213 | |||
214 | To compile this driver as a module, choose M here: the | ||
215 | module will be called aaed2000_kbd. | ||
216 | |||
206 | endif | 217 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 4c79e7bc9d06..568797907347 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -17,4 +17,5 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | |||
17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
18 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
19 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 19 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
20 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | ||
20 | 21 | ||
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c new file mode 100644 index 000000000000..65fcb6af63a8 --- /dev/null +++ b/drivers/input/keyboard/aaed2000_kbd.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * Keyboard driver for the AAED-2000 dev board | ||
3 | * | ||
4 | * Copyright (c) 2006 Nicolas Bellido Y Ortega | ||
5 | * | ||
6 | * Based on corgikbd.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/jiffies.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/workqueue.h> | ||
23 | |||
24 | #include <asm/arch/hardware.h> | ||
25 | #include <asm/arch/aaed2000.h> | ||
26 | |||
27 | #define KB_ROWS 12 | ||
28 | #define KB_COLS 8 | ||
29 | #define KB_ROWMASK(r) (1 << (r)) | ||
30 | #define SCANCODE(r,c) (((c) * KB_ROWS) + (r)) | ||
31 | #define NR_SCANCODES (KB_COLS * KB_ROWS) | ||
32 | |||
33 | #define SCAN_INTERVAL (50) /* ms */ | ||
34 | #define KB_ACTIVATE_DELAY (20) /* us */ | ||
35 | |||
36 | static unsigned char aaedkbd_keycode[NR_SCANCODES] = { | ||
37 | KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, 0, KEY_SPACE, KEY_KP6, 0, KEY_KPDOT, 0, 0, | ||
38 | KEY_K, KEY_M, KEY_O, KEY_DOT, KEY_SLASH, 0, KEY_F, 0, 0, 0, KEY_LEFTSHIFT, 0, | ||
39 | KEY_I, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, 0, 0, 0, 0, KEY_RIGHTSHIFT, 0, | ||
40 | KEY_8, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, | ||
41 | KEY_J, KEY_H, KEY_B, KEY_KP8, KEY_KP4, 0, KEY_C, KEY_D, KEY_S, KEY_A, 0, KEY_CAPSLOCK, | ||
42 | KEY_Y, KEY_U, KEY_N, KEY_T, 0, 0, KEY_R, KEY_E, KEY_W, KEY_Q, 0, KEY_TAB, | ||
43 | KEY_7, KEY_6, KEY_G, 0, KEY_5, 0, KEY_4, KEY_3, KEY_2, KEY_1, 0, KEY_GRAVE, | ||
44 | 0, 0, KEY_COMMA, 0, KEY_KP2, 0, KEY_V, KEY_LEFTALT, KEY_X, KEY_Z, 0, KEY_LEFTCTRL | ||
45 | }; | ||
46 | |||
47 | struct aaedkbd { | ||
48 | unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; | ||
49 | struct input_dev *input; | ||
50 | struct work_struct workq; | ||
51 | int kbdscan_state[KB_COLS]; | ||
52 | int kbdscan_count[KB_COLS]; | ||
53 | }; | ||
54 | |||
55 | #define KBDSCAN_STABLE_COUNT 2 | ||
56 | |||
57 | static void aaedkbd_report_col(struct aaedkbd *aaedkbd, | ||
58 | unsigned int col, unsigned int rowd) | ||
59 | { | ||
60 | unsigned int scancode, pressed; | ||
61 | unsigned int row; | ||
62 | |||
63 | for (row = 0; row < KB_ROWS; row++) { | ||
64 | scancode = SCANCODE(row, col); | ||
65 | pressed = rowd & KB_ROWMASK(row); | ||
66 | |||
67 | input_report_key(aaedkbd->input, aaedkbd->keycode[scancode], pressed); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | /* Scan the hardware keyboard and push any changes up through the input layer */ | ||
72 | static void aaedkbd_work(void *data) | ||
73 | { | ||
74 | struct aaedkbd *aaedkbd = data; | ||
75 | unsigned int col, rowd; | ||
76 | |||
77 | col = 0; | ||
78 | do { | ||
79 | AAEC_GPIO_KSCAN = col + 8; | ||
80 | udelay(KB_ACTIVATE_DELAY); | ||
81 | rowd = AAED_EXT_GPIO & AAED_EGPIO_KBD_SCAN; | ||
82 | |||
83 | if (rowd != aaedkbd->kbdscan_state[col]) { | ||
84 | aaedkbd->kbdscan_count[col] = 0; | ||
85 | aaedkbd->kbdscan_state[col] = rowd; | ||
86 | } else if (++aaedkbd->kbdscan_count[col] >= KBDSCAN_STABLE_COUNT) { | ||
87 | aaedkbd_report_col(aaedkbd, col, rowd); | ||
88 | col++; | ||
89 | } | ||
90 | } while (col < KB_COLS); | ||
91 | |||
92 | AAEC_GPIO_KSCAN = 0x07; | ||
93 | input_sync(aaedkbd->input); | ||
94 | |||
95 | schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); | ||
96 | } | ||
97 | |||
98 | static int aaedkbd_open(struct input_dev *indev) | ||
99 | { | ||
100 | struct aaedkbd *aaedkbd = indev->private; | ||
101 | |||
102 | schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void aaedkbd_close(struct input_dev *indev) | ||
108 | { | ||
109 | struct aaedkbd *aaedkbd = indev->private; | ||
110 | |||
111 | cancel_delayed_work(&aaedkbd->workq); | ||
112 | flush_scheduled_work(); | ||
113 | } | ||
114 | |||
115 | static int __devinit aaedkbd_probe(struct platform_device *pdev) | ||
116 | { | ||
117 | struct aaedkbd *aaedkbd; | ||
118 | struct input_dev *input_dev; | ||
119 | int i; | ||
120 | int error; | ||
121 | |||
122 | aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); | ||
123 | input_dev = input_allocate_device(); | ||
124 | if (!aaedkbd || !input_dev) { | ||
125 | error = -ENOMEM; | ||
126 | goto fail; | ||
127 | } | ||
128 | |||
129 | platform_set_drvdata(pdev, aaedkbd); | ||
130 | |||
131 | aaedkbd->input = input_dev; | ||
132 | |||
133 | /* Init keyboard rescan workqueue */ | ||
134 | INIT_WORK(&aaedkbd->workq, aaedkbd_work, aaedkbd); | ||
135 | |||
136 | memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); | ||
137 | |||
138 | input_dev->name = "AAED-2000 Keyboard"; | ||
139 | input_dev->phys = "aaedkbd/input0"; | ||
140 | input_dev->id.bustype = BUS_HOST; | ||
141 | input_dev->id.vendor = 0x0001; | ||
142 | input_dev->id.product = 0x0001; | ||
143 | input_dev->id.version = 0x0100; | ||
144 | input_dev->cdev.dev = &pdev->dev; | ||
145 | input_dev->private = aaedkbd; | ||
146 | |||
147 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | ||
148 | input_dev->keycode = aaedkbd->keycode; | ||
149 | input_dev->keycodesize = sizeof(unsigned char); | ||
150 | input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode); | ||
151 | |||
152 | for (i = 0; i < ARRAY_SIZE(aaedkbd_keycode); i++) | ||
153 | set_bit(aaedkbd->keycode[i], input_dev->keybit); | ||
154 | clear_bit(0, input_dev->keybit); | ||
155 | |||
156 | input_dev->open = aaedkbd_open; | ||
157 | input_dev->close = aaedkbd_close; | ||
158 | |||
159 | error = input_register_device(aaedkbd->input); | ||
160 | if (error) | ||
161 | goto fail; | ||
162 | |||
163 | return 0; | ||
164 | |||
165 | fail: kfree(aaedkbd); | ||
166 | input_free_device(input_dev); | ||
167 | return error; | ||
168 | } | ||
169 | |||
170 | static int __devexit aaedkbd_remove(struct platform_device *pdev) | ||
171 | { | ||
172 | struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); | ||
173 | |||
174 | input_unregister_device(aaedkbd->input); | ||
175 | kfree(aaedkbd); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static struct platform_driver aaedkbd_driver = { | ||
181 | .probe = aaedkbd_probe, | ||
182 | .remove = __devexit_p(aaedkbd_remove), | ||
183 | .driver = { | ||
184 | .name = "aaed2000-keyboard", | ||
185 | }, | ||
186 | }; | ||
187 | |||
188 | static int __init aaedkbd_init(void) | ||
189 | { | ||
190 | return platform_driver_register(&aaedkbd_driver); | ||
191 | } | ||
192 | |||
193 | static void __exit aaedkbd_exit(void) | ||
194 | { | ||
195 | platform_driver_unregister(&aaedkbd_driver); | ||
196 | } | ||
197 | |||
198 | module_init(aaedkbd_init); | ||
199 | module_exit(aaedkbd_exit); | ||
200 | |||
201 | MODULE_AUTHOR("Nicolas Bellido Y Ortega"); | ||
202 | MODULE_DESCRIPTION("AAED-2000 Keyboard Driver"); | ||
203 | MODULE_LICENSE("GPLv2"); | ||
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 8abdbd0ee8f9..16583d71753b 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c | |||
@@ -190,7 +190,7 @@ static int __init amikbd_init(void) | |||
190 | int i, j; | 190 | int i, j; |
191 | 191 | ||
192 | if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) | 192 | if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) |
193 | return -EIO; | 193 | return -ENODEV; |
194 | 194 | ||
195 | if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) | 195 | if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) |
196 | return -EBUSY; | 196 | return -EBUSY; |
@@ -198,8 +198,8 @@ static int __init amikbd_init(void) | |||
198 | amikbd_dev = input_allocate_device(); | 198 | amikbd_dev = input_allocate_device(); |
199 | if (!amikbd_dev) { | 199 | if (!amikbd_dev) { |
200 | printk(KERN_ERR "amikbd: not enough memory for input device\n"); | 200 | printk(KERN_ERR "amikbd: not enough memory for input device\n"); |
201 | release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); | 201 | err = -ENOMEM; |
202 | return -ENOMEM; | 202 | goto fail1; |
203 | } | 203 | } |
204 | 204 | ||
205 | amikbd_dev->name = "Amiga Keyboard"; | 205 | amikbd_dev->name = "Amiga Keyboard"; |
@@ -231,10 +231,22 @@ static int __init amikbd_init(void) | |||
231 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); | 231 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); |
232 | } | 232 | } |
233 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ | 233 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ |
234 | request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt); | 234 | if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", |
235 | amikbd_interrupt)) { | ||
236 | err = -EBUSY; | ||
237 | goto fail2; | ||
238 | } | ||
239 | |||
240 | err = input_register_device(amikbd_dev); | ||
241 | if (err) | ||
242 | goto fail3; | ||
235 | 243 | ||
236 | input_register_device(amikbd_dev); | ||
237 | return 0; | 244 | return 0; |
245 | |||
246 | fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); | ||
247 | fail2: input_free_device(amikbd_dev); | ||
248 | fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); | ||
249 | return err; | ||
238 | } | 250 | } |
239 | 251 | ||
240 | static void __exit amikbd_exit(void) | 252 | static void __exit amikbd_exit(void) |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 8451b29a3db5..c621a9177a56 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -939,7 +939,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
939 | atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL); | 939 | atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL); |
940 | dev = input_allocate_device(); | 940 | dev = input_allocate_device(); |
941 | if (!atkbd || !dev) | 941 | if (!atkbd || !dev) |
942 | goto fail; | 942 | goto fail1; |
943 | 943 | ||
944 | atkbd->dev = dev; | 944 | atkbd->dev = dev; |
945 | ps2_init(&atkbd->ps2dev, serio); | 945 | ps2_init(&atkbd->ps2dev, serio); |
@@ -967,14 +967,13 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
967 | 967 | ||
968 | err = serio_open(serio, drv); | 968 | err = serio_open(serio, drv); |
969 | if (err) | 969 | if (err) |
970 | goto fail; | 970 | goto fail2; |
971 | 971 | ||
972 | if (atkbd->write) { | 972 | if (atkbd->write) { |
973 | 973 | ||
974 | if (atkbd_probe(atkbd)) { | 974 | if (atkbd_probe(atkbd)) { |
975 | serio_close(serio); | ||
976 | err = -ENODEV; | 975 | err = -ENODEV; |
977 | goto fail; | 976 | goto fail3; |
978 | } | 977 | } |
979 | 978 | ||
980 | atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); | 979 | atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); |
@@ -988,16 +987,22 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
988 | atkbd_set_keycode_table(atkbd); | 987 | atkbd_set_keycode_table(atkbd); |
989 | atkbd_set_device_attrs(atkbd); | 988 | atkbd_set_device_attrs(atkbd); |
990 | 989 | ||
991 | sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); | 990 | err = sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); |
991 | if (err) | ||
992 | goto fail3; | ||
992 | 993 | ||
993 | atkbd_enable(atkbd); | 994 | atkbd_enable(atkbd); |
994 | 995 | ||
995 | input_register_device(atkbd->dev); | 996 | err = input_register_device(atkbd->dev); |
997 | if (err) | ||
998 | goto fail4; | ||
996 | 999 | ||
997 | return 0; | 1000 | return 0; |
998 | 1001 | ||
999 | fail: serio_set_drvdata(serio, NULL); | 1002 | fail4: sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); |
1000 | input_free_device(dev); | 1003 | fail3: serio_close(serio); |
1004 | fail2: serio_set_drvdata(serio, NULL); | ||
1005 | fail1: input_free_device(dev); | ||
1001 | kfree(atkbd); | 1006 | kfree(atkbd); |
1002 | return err; | 1007 | return err; |
1003 | } | 1008 | } |
@@ -1133,9 +1138,11 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf) | |||
1133 | 1138 | ||
1134 | static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) | 1139 | static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) |
1135 | { | 1140 | { |
1136 | struct input_dev *new_dev; | 1141 | struct input_dev *old_dev, *new_dev; |
1137 | unsigned long value; | 1142 | unsigned long value; |
1138 | char *rest; | 1143 | char *rest; |
1144 | int err; | ||
1145 | unsigned char old_extra, old_set; | ||
1139 | 1146 | ||
1140 | if (!atkbd->write) | 1147 | if (!atkbd->write) |
1141 | return -EIO; | 1148 | return -EIO; |
@@ -1147,17 +1154,36 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1147 | if (atkbd->extra != value) { | 1154 | if (atkbd->extra != value) { |
1148 | /* | 1155 | /* |
1149 | * Since device's properties will change we need to | 1156 | * Since device's properties will change we need to |
1150 | * unregister old device. But allocate new one first | 1157 | * unregister old device. But allocate and register |
1151 | * to make sure we have it. | 1158 | * new one first to make sure we have it. |
1152 | */ | 1159 | */ |
1153 | if (!(new_dev = input_allocate_device())) | 1160 | old_dev = atkbd->dev; |
1161 | old_extra = atkbd->extra; | ||
1162 | old_set = atkbd->set; | ||
1163 | |||
1164 | new_dev = input_allocate_device(); | ||
1165 | if (!new_dev) | ||
1154 | return -ENOMEM; | 1166 | return -ENOMEM; |
1155 | input_unregister_device(atkbd->dev); | 1167 | |
1156 | atkbd->dev = new_dev; | 1168 | atkbd->dev = new_dev; |
1157 | atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); | 1169 | atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); |
1158 | atkbd_activate(atkbd); | 1170 | atkbd_activate(atkbd); |
1171 | atkbd_set_keycode_table(atkbd); | ||
1159 | atkbd_set_device_attrs(atkbd); | 1172 | atkbd_set_device_attrs(atkbd); |
1160 | input_register_device(atkbd->dev); | 1173 | |
1174 | err = input_register_device(atkbd->dev); | ||
1175 | if (err) { | ||
1176 | input_free_device(new_dev); | ||
1177 | |||
1178 | atkbd->dev = old_dev; | ||
1179 | atkbd->set = atkbd_select_set(atkbd, old_set, old_extra); | ||
1180 | atkbd_set_keycode_table(atkbd); | ||
1181 | atkbd_set_device_attrs(atkbd); | ||
1182 | |||
1183 | return err; | ||
1184 | } | ||
1185 | input_unregister_device(old_dev); | ||
1186 | |||
1161 | } | 1187 | } |
1162 | return count; | 1188 | return count; |
1163 | } | 1189 | } |
@@ -1169,23 +1195,41 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) | |||
1169 | 1195 | ||
1170 | static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) | 1196 | static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) |
1171 | { | 1197 | { |
1172 | struct input_dev *new_dev; | 1198 | struct input_dev *old_dev, *new_dev; |
1173 | unsigned long value; | 1199 | unsigned long value; |
1174 | char *rest; | 1200 | char *rest; |
1201 | int err; | ||
1202 | unsigned char old_scroll; | ||
1175 | 1203 | ||
1176 | value = simple_strtoul(buf, &rest, 10); | 1204 | value = simple_strtoul(buf, &rest, 10); |
1177 | if (*rest || value > 1) | 1205 | if (*rest || value > 1) |
1178 | return -EINVAL; | 1206 | return -EINVAL; |
1179 | 1207 | ||
1180 | if (atkbd->scroll != value) { | 1208 | if (atkbd->scroll != value) { |
1181 | if (!(new_dev = input_allocate_device())) | 1209 | old_dev = atkbd->dev; |
1210 | old_scroll = atkbd->scroll; | ||
1211 | |||
1212 | new_dev = input_allocate_device(); | ||
1213 | if (!new_dev) | ||
1182 | return -ENOMEM; | 1214 | return -ENOMEM; |
1183 | input_unregister_device(atkbd->dev); | 1215 | |
1184 | atkbd->dev = new_dev; | 1216 | atkbd->dev = new_dev; |
1185 | atkbd->scroll = value; | 1217 | atkbd->scroll = value; |
1186 | atkbd_set_keycode_table(atkbd); | 1218 | atkbd_set_keycode_table(atkbd); |
1187 | atkbd_set_device_attrs(atkbd); | 1219 | atkbd_set_device_attrs(atkbd); |
1188 | input_register_device(atkbd->dev); | 1220 | |
1221 | err = input_register_device(atkbd->dev); | ||
1222 | if (err) { | ||
1223 | input_free_device(new_dev); | ||
1224 | |||
1225 | atkbd->scroll = old_scroll; | ||
1226 | atkbd->dev = old_dev; | ||
1227 | atkbd_set_keycode_table(atkbd); | ||
1228 | atkbd_set_device_attrs(atkbd); | ||
1229 | |||
1230 | return err; | ||
1231 | } | ||
1232 | input_unregister_device(old_dev); | ||
1189 | } | 1233 | } |
1190 | return count; | 1234 | return count; |
1191 | } | 1235 | } |
@@ -1197,9 +1241,11 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf) | |||
1197 | 1241 | ||
1198 | static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | 1242 | static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) |
1199 | { | 1243 | { |
1200 | struct input_dev *new_dev; | 1244 | struct input_dev *old_dev, *new_dev; |
1201 | unsigned long value; | 1245 | unsigned long value; |
1202 | char *rest; | 1246 | char *rest; |
1247 | int err; | ||
1248 | unsigned char old_set, old_extra; | ||
1203 | 1249 | ||
1204 | if (!atkbd->write) | 1250 | if (!atkbd->write) |
1205 | return -EIO; | 1251 | return -EIO; |
@@ -1209,15 +1255,32 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | |||
1209 | return -EINVAL; | 1255 | return -EINVAL; |
1210 | 1256 | ||
1211 | if (atkbd->set != value) { | 1257 | if (atkbd->set != value) { |
1212 | if (!(new_dev = input_allocate_device())) | 1258 | old_dev = atkbd->dev; |
1259 | old_extra = atkbd->extra; | ||
1260 | old_set = atkbd->set; | ||
1261 | |||
1262 | new_dev = input_allocate_device(); | ||
1263 | if (!new_dev) | ||
1213 | return -ENOMEM; | 1264 | return -ENOMEM; |
1214 | input_unregister_device(atkbd->dev); | 1265 | |
1215 | atkbd->dev = new_dev; | 1266 | atkbd->dev = new_dev; |
1216 | atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra); | 1267 | atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra); |
1217 | atkbd_activate(atkbd); | 1268 | atkbd_activate(atkbd); |
1218 | atkbd_set_keycode_table(atkbd); | 1269 | atkbd_set_keycode_table(atkbd); |
1219 | atkbd_set_device_attrs(atkbd); | 1270 | atkbd_set_device_attrs(atkbd); |
1220 | input_register_device(atkbd->dev); | 1271 | |
1272 | err = input_register_device(atkbd->dev); | ||
1273 | if (err) { | ||
1274 | input_free_device(new_dev); | ||
1275 | |||
1276 | atkbd->dev = old_dev; | ||
1277 | atkbd->set = atkbd_select_set(atkbd, old_set, old_extra); | ||
1278 | atkbd_set_keycode_table(atkbd); | ||
1279 | atkbd_set_device_attrs(atkbd); | ||
1280 | |||
1281 | return err; | ||
1282 | } | ||
1283 | input_unregister_device(old_dev); | ||
1221 | } | 1284 | } |
1222 | return count; | 1285 | return count; |
1223 | } | 1286 | } |
@@ -1229,9 +1292,11 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf) | |||
1229 | 1292 | ||
1230 | static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) | 1293 | static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) |
1231 | { | 1294 | { |
1232 | struct input_dev *new_dev; | 1295 | struct input_dev *old_dev, *new_dev; |
1233 | unsigned long value; | 1296 | unsigned long value; |
1234 | char *rest; | 1297 | char *rest; |
1298 | int err; | ||
1299 | unsigned char old_softrepeat, old_softraw; | ||
1235 | 1300 | ||
1236 | if (!atkbd->write) | 1301 | if (!atkbd->write) |
1237 | return -EIO; | 1302 | return -EIO; |
@@ -1241,15 +1306,32 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1241 | return -EINVAL; | 1306 | return -EINVAL; |
1242 | 1307 | ||
1243 | if (atkbd->softrepeat != value) { | 1308 | if (atkbd->softrepeat != value) { |
1244 | if (!(new_dev = input_allocate_device())) | 1309 | old_dev = atkbd->dev; |
1310 | old_softrepeat = atkbd->softrepeat; | ||
1311 | old_softraw = atkbd->softraw; | ||
1312 | |||
1313 | new_dev = input_allocate_device(); | ||
1314 | if (!new_dev) | ||
1245 | return -ENOMEM; | 1315 | return -ENOMEM; |
1246 | input_unregister_device(atkbd->dev); | 1316 | |
1247 | atkbd->dev = new_dev; | 1317 | atkbd->dev = new_dev; |
1248 | atkbd->softrepeat = value; | 1318 | atkbd->softrepeat = value; |
1249 | if (atkbd->softrepeat) | 1319 | if (atkbd->softrepeat) |
1250 | atkbd->softraw = 1; | 1320 | atkbd->softraw = 1; |
1251 | atkbd_set_device_attrs(atkbd); | 1321 | atkbd_set_device_attrs(atkbd); |
1252 | input_register_device(atkbd->dev); | 1322 | |
1323 | err = input_register_device(atkbd->dev); | ||
1324 | if (err) { | ||
1325 | input_free_device(new_dev); | ||
1326 | |||
1327 | atkbd->dev = old_dev; | ||
1328 | atkbd->softrepeat = old_softrepeat; | ||
1329 | atkbd->softraw = old_softraw; | ||
1330 | atkbd_set_device_attrs(atkbd); | ||
1331 | |||
1332 | return err; | ||
1333 | } | ||
1334 | input_unregister_device(old_dev); | ||
1253 | } | 1335 | } |
1254 | return count; | 1336 | return count; |
1255 | } | 1337 | } |
@@ -1262,22 +1344,39 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf) | |||
1262 | 1344 | ||
1263 | static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) | 1345 | static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) |
1264 | { | 1346 | { |
1265 | struct input_dev *new_dev; | 1347 | struct input_dev *old_dev, *new_dev; |
1266 | unsigned long value; | 1348 | unsigned long value; |
1267 | char *rest; | 1349 | char *rest; |
1350 | int err; | ||
1351 | unsigned char old_softraw; | ||
1268 | 1352 | ||
1269 | value = simple_strtoul(buf, &rest, 10); | 1353 | value = simple_strtoul(buf, &rest, 10); |
1270 | if (*rest || value > 1) | 1354 | if (*rest || value > 1) |
1271 | return -EINVAL; | 1355 | return -EINVAL; |
1272 | 1356 | ||
1273 | if (atkbd->softraw != value) { | 1357 | if (atkbd->softraw != value) { |
1274 | if (!(new_dev = input_allocate_device())) | 1358 | old_dev = atkbd->dev; |
1359 | old_softraw = atkbd->softraw; | ||
1360 | |||
1361 | new_dev = input_allocate_device(); | ||
1362 | if (!new_dev) | ||
1275 | return -ENOMEM; | 1363 | return -ENOMEM; |
1276 | input_unregister_device(atkbd->dev); | 1364 | |
1277 | atkbd->dev = new_dev; | 1365 | atkbd->dev = new_dev; |
1278 | atkbd->softraw = value; | 1366 | atkbd->softraw = value; |
1279 | atkbd_set_device_attrs(atkbd); | 1367 | atkbd_set_device_attrs(atkbd); |
1280 | input_register_device(atkbd->dev); | 1368 | |
1369 | err = input_register_device(atkbd->dev); | ||
1370 | if (err) { | ||
1371 | input_free_device(new_dev); | ||
1372 | |||
1373 | atkbd->dev = old_dev; | ||
1374 | atkbd->softraw = old_softraw; | ||
1375 | atkbd_set_device_attrs(atkbd); | ||
1376 | |||
1377 | return err; | ||
1378 | } | ||
1379 | input_unregister_device(old_dev); | ||
1281 | } | 1380 | } |
1282 | return count; | 1381 | return count; |
1283 | } | 1382 | } |
@@ -1290,8 +1389,7 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) | |||
1290 | 1389 | ||
1291 | static int __init atkbd_init(void) | 1390 | static int __init atkbd_init(void) |
1292 | { | 1391 | { |
1293 | serio_register_driver(&atkbd_drv); | 1392 | return serio_register_driver(&atkbd_drv); |
1294 | return 0; | ||
1295 | } | 1393 | } |
1296 | 1394 | ||
1297 | static void __exit atkbd_exit(void) | 1395 | static void __exit atkbd_exit(void) |
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index befdd6006b50..1016c94e65db 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -291,15 +291,12 @@ static int __init corgikbd_probe(struct platform_device *pdev) | |||
291 | { | 291 | { |
292 | struct corgikbd *corgikbd; | 292 | struct corgikbd *corgikbd; |
293 | struct input_dev *input_dev; | 293 | struct input_dev *input_dev; |
294 | int i; | 294 | int i, err = -ENOMEM; |
295 | 295 | ||
296 | corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL); | 296 | corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL); |
297 | input_dev = input_allocate_device(); | 297 | input_dev = input_allocate_device(); |
298 | if (!corgikbd || !input_dev) { | 298 | if (!corgikbd || !input_dev) |
299 | kfree(corgikbd); | 299 | goto fail; |
300 | input_free_device(input_dev); | ||
301 | return -ENOMEM; | ||
302 | } | ||
303 | 300 | ||
304 | platform_set_drvdata(pdev, corgikbd); | 301 | platform_set_drvdata(pdev, corgikbd); |
305 | 302 | ||
@@ -341,7 +338,9 @@ static int __init corgikbd_probe(struct platform_device *pdev) | |||
341 | set_bit(SW_TABLET_MODE, input_dev->swbit); | 338 | set_bit(SW_TABLET_MODE, input_dev->swbit); |
342 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); | 339 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); |
343 | 340 | ||
344 | input_register_device(corgikbd->input); | 341 | err = input_register_device(corgikbd->input); |
342 | if (err) | ||
343 | goto fail; | ||
345 | 344 | ||
346 | mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | 345 | mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); |
347 | 346 | ||
@@ -362,6 +361,10 @@ static int __init corgikbd_probe(struct platform_device *pdev) | |||
362 | pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); | 361 | pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); |
363 | 362 | ||
364 | return 0; | 363 | return 0; |
364 | |||
365 | fail: input_free_device(input_dev); | ||
366 | kfree(corgikbd); | ||
367 | return err; | ||
365 | } | 368 | } |
366 | 369 | ||
367 | static int corgikbd_remove(struct platform_device *pdev) | 370 | static int corgikbd_remove(struct platform_device *pdev) |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index e774dd31e99b..7cc9728b04df 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -381,8 +381,7 @@ struct serio_driver hil_kbd_serio_drv = { | |||
381 | 381 | ||
382 | static int __init hil_kbd_init(void) | 382 | static int __init hil_kbd_init(void) |
383 | { | 383 | { |
384 | serio_register_driver(&hil_kbd_serio_drv); | 384 | return serio_register_driver(&hil_kbd_serio_drv); |
385 | return 0; | ||
386 | } | 385 | } |
387 | 386 | ||
388 | static void __exit hil_kbd_exit(void) | 387 | static void __exit hil_kbd_exit(void) |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index b7f049b45b6b..3d4d0a0ede28 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -646,7 +646,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
646 | input_dev = input_allocate_device (); | 646 | input_dev = input_allocate_device (); |
647 | if (!lk || !input_dev) { | 647 | if (!lk || !input_dev) { |
648 | err = -ENOMEM; | 648 | err = -ENOMEM; |
649 | goto fail; | 649 | goto fail1; |
650 | } | 650 | } |
651 | 651 | ||
652 | lk->serio = serio; | 652 | lk->serio = serio; |
@@ -691,15 +691,19 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
691 | 691 | ||
692 | err = serio_open (serio, drv); | 692 | err = serio_open (serio, drv); |
693 | if (err) | 693 | if (err) |
694 | goto fail; | 694 | goto fail2; |
695 | |||
696 | err = input_register_device (lk->dev); | ||
697 | if (err) | ||
698 | goto fail3; | ||
695 | 699 | ||
696 | input_register_device (lk->dev); | ||
697 | lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET); | 700 | lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET); |
698 | 701 | ||
699 | return 0; | 702 | return 0; |
700 | 703 | ||
701 | fail: serio_set_drvdata (serio, NULL); | 704 | fail3: serio_close (serio); |
702 | input_free_device (input_dev); | 705 | fail2: serio_set_drvdata (serio, NULL); |
706 | fail1: input_free_device (input_dev); | ||
703 | kfree (lk); | 707 | kfree (lk); |
704 | return err; | 708 | return err; |
705 | } | 709 | } |
@@ -749,8 +753,7 @@ static struct serio_driver lkkbd_drv = { | |||
749 | static int __init | 753 | static int __init |
750 | lkkbd_init (void) | 754 | lkkbd_init (void) |
751 | { | 755 | { |
752 | serio_register_driver(&lkkbd_drv); | 756 | return serio_register_driver(&lkkbd_drv); |
753 | return 0; | ||
754 | } | 757 | } |
755 | 758 | ||
756 | static void __exit | 759 | static void __exit |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 5788dbc317bb..2ade5186cc41 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -193,22 +193,22 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
193 | { | 193 | { |
194 | struct locomokbd *locomokbd; | 194 | struct locomokbd *locomokbd; |
195 | struct input_dev *input_dev; | 195 | struct input_dev *input_dev; |
196 | int i, ret; | 196 | int i, err; |
197 | 197 | ||
198 | locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL); | 198 | locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL); |
199 | input_dev = input_allocate_device(); | 199 | input_dev = input_allocate_device(); |
200 | if (!locomokbd || !input_dev) { | 200 | if (!locomokbd || !input_dev) { |
201 | ret = -ENOMEM; | 201 | err = -ENOMEM; |
202 | goto free; | 202 | goto err_free_mem; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* try and claim memory region */ | 205 | /* try and claim memory region */ |
206 | if (!request_mem_region((unsigned long) dev->mapbase, | 206 | if (!request_mem_region((unsigned long) dev->mapbase, |
207 | dev->length, | 207 | dev->length, |
208 | LOCOMO_DRIVER_NAME(dev))) { | 208 | LOCOMO_DRIVER_NAME(dev))) { |
209 | ret = -EBUSY; | 209 | err = -EBUSY; |
210 | printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n"); | 210 | printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n"); |
211 | goto free; | 211 | goto err_free_mem; |
212 | } | 212 | } |
213 | 213 | ||
214 | locomokbd->ldev = dev; | 214 | locomokbd->ldev = dev; |
@@ -244,24 +244,28 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
244 | clear_bit(0, input_dev->keybit); | 244 | clear_bit(0, input_dev->keybit); |
245 | 245 | ||
246 | /* attempt to get the interrupt */ | 246 | /* attempt to get the interrupt */ |
247 | ret = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd); | 247 | err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd); |
248 | if (ret) { | 248 | if (err) { |
249 | printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n"); | 249 | printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n"); |
250 | goto out; | 250 | goto err_release_region; |
251 | } | 251 | } |
252 | 252 | ||
253 | input_register_device(locomokbd->input); | 253 | err = input_register_device(locomokbd->input); |
254 | if (err) | ||
255 | goto err_free_irq; | ||
254 | 256 | ||
255 | return 0; | 257 | return 0; |
256 | 258 | ||
257 | out: | 259 | err_free_irq: |
260 | free_irq(dev->irq[0], locomokbd); | ||
261 | err_release_region: | ||
258 | release_mem_region((unsigned long) dev->mapbase, dev->length); | 262 | release_mem_region((unsigned long) dev->mapbase, dev->length); |
259 | locomo_set_drvdata(dev, NULL); | 263 | locomo_set_drvdata(dev, NULL); |
260 | free: | 264 | err_free_mem: |
261 | input_free_device(input_dev); | 265 | input_free_device(input_dev); |
262 | kfree(locomokbd); | 266 | kfree(locomokbd); |
263 | 267 | ||
264 | return ret; | 268 | return err; |
265 | } | 269 | } |
266 | 270 | ||
267 | static int locomokbd_remove(struct locomo_dev *dev) | 271 | static int locomokbd_remove(struct locomo_dev *dev) |
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index cc6aaf9e85be..99836b3af47b 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c | |||
@@ -94,13 +94,13 @@ static int dc_kbd_connect(struct maple_device *dev) | |||
94 | struct input_dev *input_dev; | 94 | struct input_dev *input_dev; |
95 | unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); | 95 | unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); |
96 | int i; | 96 | int i; |
97 | int err; | ||
97 | 98 | ||
98 | dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); | 99 | dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); |
99 | input_dev = input_allocate_device(); | 100 | input_dev = input_allocate_device(); |
100 | if (!kbd || !input_dev) { | 101 | if (!kbd || !input_dev) { |
101 | kfree(kbd); | 102 | err = -ENOMEM; |
102 | input_free_device(input_dev); | 103 | goto fail; |
103 | return -ENOMEM; | ||
104 | } | 104 | } |
105 | 105 | ||
106 | kbd->dev = input_dev; | 106 | kbd->dev = input_dev; |
@@ -113,10 +113,16 @@ static int dc_kbd_connect(struct maple_device *dev) | |||
113 | set_bit(dc_kbd_keycode[i], input_dev->keybit); | 113 | set_bit(dc_kbd_keycode[i], input_dev->keybit); |
114 | clear_bit(0, input_dev->keybit); | 114 | clear_bit(0, input_dev->keybit); |
115 | 115 | ||
116 | input_register_device(kbd->dev); | 116 | err = input_register_device(kbd->dev); |
117 | if (err) | ||
118 | goto fail; | ||
117 | 119 | ||
118 | maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD); | 120 | maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD); |
119 | return 0; | 121 | return 0; |
122 | |||
123 | fail: input_free_device(input_dev); | ||
124 | kfree(kbd); | ||
125 | return err; | ||
120 | } | 126 | } |
121 | 127 | ||
122 | 128 | ||
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index 9282e4e082bd..aa29b50765c9 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c | |||
@@ -91,7 +91,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
91 | nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL); | 91 | nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL); |
92 | input_dev = input_allocate_device(); | 92 | input_dev = input_allocate_device(); |
93 | if (!nkbd || !input_dev) | 93 | if (!nkbd || !input_dev) |
94 | goto fail; | 94 | goto fail1; |
95 | 95 | ||
96 | nkbd->serio = serio; | 96 | nkbd->serio = serio; |
97 | nkbd->dev = input_dev; | 97 | nkbd->dev = input_dev; |
@@ -119,13 +119,17 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
119 | 119 | ||
120 | err = serio_open(serio, drv); | 120 | err = serio_open(serio, drv); |
121 | if (err) | 121 | if (err) |
122 | goto fail; | 122 | goto fail2; |
123 | |||
124 | err = input_register_device(nkbd->dev); | ||
125 | if (err) | ||
126 | goto fail3; | ||
123 | 127 | ||
124 | input_register_device(nkbd->dev); | ||
125 | return 0; | 128 | return 0; |
126 | 129 | ||
127 | fail: serio_set_drvdata(serio, NULL); | 130 | fail3: serio_close(serio); |
128 | input_free_device(input_dev); | 131 | fail2: serio_set_drvdata(serio, NULL); |
132 | fail1: input_free_device(input_dev); | ||
129 | kfree(nkbd); | 133 | kfree(nkbd); |
130 | return err; | 134 | return err; |
131 | } | 135 | } |
@@ -165,8 +169,7 @@ static struct serio_driver nkbd_drv = { | |||
165 | 169 | ||
166 | static int __init nkbd_init(void) | 170 | static int __init nkbd_init(void) |
167 | { | 171 | { |
168 | serio_register_driver(&nkbd_drv); | 172 | return serio_register_driver(&nkbd_drv); |
169 | return 0; | ||
170 | } | 173 | } |
171 | 174 | ||
172 | static void __exit nkbd_exit(void) | 175 | static void __exit nkbd_exit(void) |
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 28b2748e82d0..8a2166c77ff4 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -346,17 +346,12 @@ static int __init spitzkbd_probe(struct platform_device *dev) | |||
346 | { | 346 | { |
347 | struct spitzkbd *spitzkbd; | 347 | struct spitzkbd *spitzkbd; |
348 | struct input_dev *input_dev; | 348 | struct input_dev *input_dev; |
349 | int i; | 349 | int i, err = -ENOMEM; |
350 | 350 | ||
351 | spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL); | 351 | spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL); |
352 | if (!spitzkbd) | ||
353 | return -ENOMEM; | ||
354 | |||
355 | input_dev = input_allocate_device(); | 352 | input_dev = input_allocate_device(); |
356 | if (!input_dev) { | 353 | if (!spitzkbd || !input_dev) |
357 | kfree(spitzkbd); | 354 | goto fail; |
358 | return -ENOMEM; | ||
359 | } | ||
360 | 355 | ||
361 | platform_set_drvdata(dev, spitzkbd); | 356 | platform_set_drvdata(dev, spitzkbd); |
362 | strcpy(spitzkbd->phys, "spitzkbd/input0"); | 357 | strcpy(spitzkbd->phys, "spitzkbd/input0"); |
@@ -400,7 +395,9 @@ static int __init spitzkbd_probe(struct platform_device *dev) | |||
400 | set_bit(SW_TABLET_MODE, input_dev->swbit); | 395 | set_bit(SW_TABLET_MODE, input_dev->swbit); |
401 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); | 396 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); |
402 | 397 | ||
403 | input_register_device(input_dev); | 398 | err = input_register_device(input_dev); |
399 | if (err) | ||
400 | goto fail; | ||
404 | 401 | ||
405 | mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | 402 | mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); |
406 | 403 | ||
@@ -434,13 +431,15 @@ static int __init spitzkbd_probe(struct platform_device *dev) | |||
434 | request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, | 431 | request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, |
435 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 432 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
436 | "Spitzkbd SWB", spitzkbd); | 433 | "Spitzkbd SWB", spitzkbd); |
437 | request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, | 434 | request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, |
438 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 435 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
439 | "Spitzkbd HP", spitzkbd); | 436 | "Spitzkbd HP", spitzkbd); |
440 | 437 | ||
441 | printk(KERN_INFO "input: Spitz Keyboard Registered\n"); | ||
442 | |||
443 | return 0; | 438 | return 0; |
439 | |||
440 | fail: input_free_device(input_dev); | ||
441 | kfree(spitzkbd); | ||
442 | return err; | ||
444 | } | 443 | } |
445 | 444 | ||
446 | static int spitzkbd_remove(struct platform_device *dev) | 445 | static int spitzkbd_remove(struct platform_device *dev) |
@@ -474,6 +473,7 @@ static struct platform_driver spitzkbd_driver = { | |||
474 | .resume = spitzkbd_resume, | 473 | .resume = spitzkbd_resume, |
475 | .driver = { | 474 | .driver = { |
476 | .name = "spitz-keyboard", | 475 | .name = "spitz-keyboard", |
476 | .owner = THIS_MODULE, | ||
477 | }, | 477 | }, |
478 | }; | 478 | }; |
479 | 479 | ||
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index e60937d17b1c..f7b5c5b81451 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c | |||
@@ -173,8 +173,7 @@ static struct serio_driver skbd_drv = { | |||
173 | 173 | ||
174 | static int __init skbd_init(void) | 174 | static int __init skbd_init(void) |
175 | { | 175 | { |
176 | serio_register_driver(&skbd_drv); | 176 | return serio_register_driver(&skbd_drv); |
177 | return 0; | ||
178 | } | 177 | } |
179 | 178 | ||
180 | static void __exit skbd_exit(void) | 179 | static void __exit skbd_exit(void) |
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 6cd887c5eb0a..3826db9403e6 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -243,7 +243,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
243 | sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL); | 243 | sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL); |
244 | input_dev = input_allocate_device(); | 244 | input_dev = input_allocate_device(); |
245 | if (!sunkbd || !input_dev) | 245 | if (!sunkbd || !input_dev) |
246 | goto fail; | 246 | goto fail1; |
247 | 247 | ||
248 | sunkbd->serio = serio; | 248 | sunkbd->serio = serio; |
249 | sunkbd->dev = input_dev; | 249 | sunkbd->dev = input_dev; |
@@ -255,11 +255,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
255 | 255 | ||
256 | err = serio_open(serio, drv); | 256 | err = serio_open(serio, drv); |
257 | if (err) | 257 | if (err) |
258 | goto fail; | 258 | goto fail2; |
259 | 259 | ||
260 | if (sunkbd_initialize(sunkbd) < 0) { | 260 | if (sunkbd_initialize(sunkbd) < 0) { |
261 | serio_close(serio); | 261 | err = -ENODEV; |
262 | goto fail; | 262 | goto fail3; |
263 | } | 263 | } |
264 | 264 | ||
265 | snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type); | 265 | snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type); |
@@ -287,11 +287,17 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
287 | clear_bit(0, input_dev->keybit); | 287 | clear_bit(0, input_dev->keybit); |
288 | 288 | ||
289 | sunkbd_enable(sunkbd, 1); | 289 | sunkbd_enable(sunkbd, 1); |
290 | input_register_device(sunkbd->dev); | 290 | |
291 | err = input_register_device(sunkbd->dev); | ||
292 | if (err) | ||
293 | goto fail4; | ||
294 | |||
291 | return 0; | 295 | return 0; |
292 | 296 | ||
293 | fail: serio_set_drvdata(serio, NULL); | 297 | fail4: sunkbd_enable(sunkbd, 0); |
294 | input_free_device(input_dev); | 298 | fail3: serio_close(serio); |
299 | fail2: serio_set_drvdata(serio, NULL); | ||
300 | fail1: input_free_device(input_dev); | ||
295 | kfree(sunkbd); | 301 | kfree(sunkbd); |
296 | return err; | 302 | return err; |
297 | } | 303 | } |
@@ -346,8 +352,7 @@ static struct serio_driver sunkbd_drv = { | |||
346 | 352 | ||
347 | static int __init sunkbd_init(void) | 353 | static int __init sunkbd_init(void) |
348 | { | 354 | { |
349 | serio_register_driver(&sunkbd_drv); | 355 | return serio_register_driver(&sunkbd_drv); |
350 | return 0; | ||
351 | } | 356 | } |
352 | 357 | ||
353 | static void __exit sunkbd_exit(void) | 358 | static void __exit sunkbd_exit(void) |
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 8c11dc935454..a82093432138 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c | |||
@@ -95,7 +95,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
95 | xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL); | 95 | xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL); |
96 | input_dev = input_allocate_device(); | 96 | input_dev = input_allocate_device(); |
97 | if (!xtkbd || !input_dev) | 97 | if (!xtkbd || !input_dev) |
98 | goto fail; | 98 | goto fail1; |
99 | 99 | ||
100 | xtkbd->serio = serio; | 100 | xtkbd->serio = serio; |
101 | xtkbd->dev = input_dev; | 101 | xtkbd->dev = input_dev; |
@@ -124,13 +124,17 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
124 | 124 | ||
125 | err = serio_open(serio, drv); | 125 | err = serio_open(serio, drv); |
126 | if (err) | 126 | if (err) |
127 | goto fail; | 127 | goto fail2; |
128 | |||
129 | err = input_register_device(xtkbd->dev); | ||
130 | if (err) | ||
131 | goto fail3; | ||
128 | 132 | ||
129 | input_register_device(xtkbd->dev); | ||
130 | return 0; | 133 | return 0; |
131 | 134 | ||
132 | fail: serio_set_drvdata(serio, NULL); | 135 | fail3: serio_close(serio); |
133 | input_free_device(input_dev); | 136 | fail2: serio_set_drvdata(serio, NULL); |
137 | fail1: input_free_device(input_dev); | ||
134 | kfree(xtkbd); | 138 | kfree(xtkbd); |
135 | return err; | 139 | return err; |
136 | } | 140 | } |
@@ -170,8 +174,7 @@ static struct serio_driver xtkbd_drv = { | |||
170 | 174 | ||
171 | static int __init xtkbd_init(void) | 175 | static int __init xtkbd_init(void) |
172 | { | 176 | { |
173 | serio_register_driver(&xtkbd_drv); | 177 | return serio_register_driver(&xtkbd_drv); |
174 | return 0; | ||
175 | } | 178 | } |
176 | 179 | ||
177 | static void __exit xtkbd_exit(void) | 180 | static void __exit xtkbd_exit(void) |
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index 599a7b2dc519..239a0e16d91a 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c | |||
@@ -95,10 +95,13 @@ static void amimouse_close(struct input_dev *dev) | |||
95 | 95 | ||
96 | static int __init amimouse_init(void) | 96 | static int __init amimouse_init(void) |
97 | { | 97 | { |
98 | int err; | ||
99 | |||
98 | if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) | 100 | if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) |
99 | return -ENODEV; | 101 | return -ENODEV; |
100 | 102 | ||
101 | if (!(amimouse_dev = input_allocate_device())) | 103 | amimouse_dev = input_allocate_device(); |
104 | if (!amimouse_dev) | ||
102 | return -ENOMEM; | 105 | return -ENOMEM; |
103 | 106 | ||
104 | amimouse_dev->name = "Amiga mouse"; | 107 | amimouse_dev->name = "Amiga mouse"; |
@@ -114,7 +117,11 @@ static int __init amimouse_init(void) | |||
114 | amimouse_dev->open = amimouse_open; | 117 | amimouse_dev->open = amimouse_open; |
115 | amimouse_dev->close = amimouse_close; | 118 | amimouse_dev->close = amimouse_close; |
116 | 119 | ||
117 | input_register_device(amimouse_dev); | 120 | err = input_register_device(amimouse_dev); |
121 | if (err) { | ||
122 | input_free_device(amimouse_dev); | ||
123 | return err; | ||
124 | } | ||
118 | 125 | ||
119 | return 0; | 126 | return 0; |
120 | } | 127 | } |
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index 4f2b503c1ac7..bfb174fe3230 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c | |||
@@ -417,8 +417,7 @@ static struct serio_driver hil_ptr_serio_driver = { | |||
417 | 417 | ||
418 | static int __init hil_ptr_init(void) | 418 | static int __init hil_ptr_init(void) |
419 | { | 419 | { |
420 | serio_register_driver(&hil_ptr_serio_driver); | 420 | return serio_register_driver(&hil_ptr_serio_driver); |
421 | return 0; | ||
422 | } | 421 | } |
423 | 422 | ||
424 | static void __exit hil_ptr_exit(void) | 423 | static void __exit hil_ptr_exit(void) |
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index e1252fa9a107..13dd96785e39 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c | |||
@@ -135,6 +135,7 @@ static void inport_close(struct input_dev *dev) | |||
135 | static int __init inport_init(void) | 135 | static int __init inport_init(void) |
136 | { | 136 | { |
137 | unsigned char a, b, c; | 137 | unsigned char a, b, c; |
138 | int err; | ||
138 | 139 | ||
139 | if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) { | 140 | if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) { |
140 | printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE); | 141 | printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE); |
@@ -145,15 +146,16 @@ static int __init inport_init(void) | |||
145 | b = inb(INPORT_SIGNATURE_PORT); | 146 | b = inb(INPORT_SIGNATURE_PORT); |
146 | c = inb(INPORT_SIGNATURE_PORT); | 147 | c = inb(INPORT_SIGNATURE_PORT); |
147 | if (a == b || a != c) { | 148 | if (a == b || a != c) { |
148 | release_region(INPORT_BASE, INPORT_EXTENT); | ||
149 | printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE); | 149 | printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE); |
150 | return -ENODEV; | 150 | err = -ENODEV; |
151 | goto err_release_region; | ||
151 | } | 152 | } |
152 | 153 | ||
153 | if (!(inport_dev = input_allocate_device())) { | 154 | inport_dev = input_allocate_device(); |
155 | if (!inport_dev) { | ||
154 | printk(KERN_ERR "inport.c: Not enough memory for input device\n"); | 156 | printk(KERN_ERR "inport.c: Not enough memory for input device\n"); |
155 | release_region(INPORT_BASE, INPORT_EXTENT); | 157 | err = -ENOMEM; |
156 | return -ENOMEM; | 158 | goto err_release_region; |
157 | } | 159 | } |
158 | 160 | ||
159 | inport_dev->name = INPORT_NAME; | 161 | inport_dev->name = INPORT_NAME; |
@@ -174,9 +176,18 @@ static int __init inport_init(void) | |||
174 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | 176 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); |
175 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); | 177 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); |
176 | 178 | ||
177 | input_register_device(inport_dev); | 179 | err = input_register_device(inport_dev); |
180 | if (err) | ||
181 | goto err_free_dev; | ||
178 | 182 | ||
179 | return 0; | 183 | return 0; |
184 | |||
185 | err_free_dev: | ||
186 | input_free_device(inport_dev); | ||
187 | err_release_region: | ||
188 | release_region(INPORT_BASE, INPORT_EXTENT); | ||
189 | |||
190 | return err; | ||
180 | } | 191 | } |
181 | 192 | ||
182 | static void __exit inport_exit(void) | 193 | static void __exit inport_exit(void) |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index c57e8853b949..29542f0631cb 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -21,47 +21,51 @@ | |||
21 | #include "lifebook.h" | 21 | #include "lifebook.h" |
22 | 22 | ||
23 | static struct dmi_system_id lifebook_dmi_table[] = { | 23 | static struct dmi_system_id lifebook_dmi_table[] = { |
24 | { | 24 | { |
25 | .ident = "LifeBook B", | 25 | .ident = "FLORA-ie 55mi", |
26 | .matches = { | 26 | .matches = { |
27 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), | 27 | DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"), |
28 | }, | 28 | }, |
29 | }, | 29 | }, |
30 | { | 30 | { |
31 | .ident = "Lifebook B", | 31 | .ident = "LifeBook B", |
32 | .matches = { | 32 | .matches = { |
33 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), | 33 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), |
34 | }, | 34 | }, |
35 | }, | 35 | }, |
36 | { | 36 | { |
37 | .ident = "Lifebook B213x/B2150", | 37 | .ident = "Lifebook B", |
38 | .matches = { | 38 | .matches = { |
39 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), | 39 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), |
40 | }, | 40 | }, |
41 | }, | 41 | }, |
42 | { | 42 | { |
43 | .ident = "Zephyr", | 43 | .ident = "Lifebook B213x/B2150", |
44 | .matches = { | 44 | .matches = { |
45 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), | 45 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), |
46 | }, | 46 | }, |
47 | }, | 47 | }, |
48 | { | 48 | { |
49 | .ident = "CF-18", | 49 | .ident = "Zephyr", |
50 | .matches = { | 50 | .matches = { |
51 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), | 51 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), |
52 | }, | 52 | }, |
53 | }, | 53 | }, |
54 | { | 54 | { |
55 | .ident = "Lifebook B142", | 55 | .ident = "CF-18", |
56 | .matches = { | 56 | .matches = { |
57 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), | 57 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), |
58 | }, | 58 | }, |
59 | 59 | }, | |
60 | }, | 60 | { |
61 | { } | 61 | .ident = "Lifebook B142", |
62 | .matches = { | ||
63 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), | ||
64 | }, | ||
65 | }, | ||
66 | { } | ||
62 | }; | 67 | }; |
63 | 68 | ||
64 | |||
65 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | 69 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
66 | { | 70 | { |
67 | unsigned char *packet = psmouse->packet; | 71 | unsigned char *packet = psmouse->packet; |
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index 8e9c2f3d69a8..db205995bffd 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c | |||
@@ -124,6 +124,8 @@ static void logibm_close(struct input_dev *dev) | |||
124 | 124 | ||
125 | static int __init logibm_init(void) | 125 | static int __init logibm_init(void) |
126 | { | 126 | { |
127 | int err; | ||
128 | |||
127 | if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) { | 129 | if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) { |
128 | printk(KERN_ERR "logibm.c: Can't allocate ports at %#x\n", LOGIBM_BASE); | 130 | printk(KERN_ERR "logibm.c: Can't allocate ports at %#x\n", LOGIBM_BASE); |
129 | return -EBUSY; | 131 | return -EBUSY; |
@@ -134,18 +136,19 @@ static int __init logibm_init(void) | |||
134 | udelay(100); | 136 | udelay(100); |
135 | 137 | ||
136 | if (inb(LOGIBM_SIGNATURE_PORT) != LOGIBM_SIGNATURE_BYTE) { | 138 | if (inb(LOGIBM_SIGNATURE_PORT) != LOGIBM_SIGNATURE_BYTE) { |
137 | release_region(LOGIBM_BASE, LOGIBM_EXTENT); | ||
138 | printk(KERN_ERR "logibm.c: Didn't find Logitech busmouse at %#x\n", LOGIBM_BASE); | 139 | printk(KERN_ERR "logibm.c: Didn't find Logitech busmouse at %#x\n", LOGIBM_BASE); |
139 | return -ENODEV; | 140 | err = -ENODEV; |
141 | goto err_release_region; | ||
140 | } | 142 | } |
141 | 143 | ||
142 | outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT); | 144 | outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT); |
143 | outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); | 145 | outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); |
144 | 146 | ||
145 | if (!(logibm_dev = input_allocate_device())) { | 147 | logibm_dev = input_allocate_device(); |
148 | if (!logibm_dev) { | ||
146 | printk(KERN_ERR "logibm.c: Not enough memory for input device\n"); | 149 | printk(KERN_ERR "logibm.c: Not enough memory for input device\n"); |
147 | release_region(LOGIBM_BASE, LOGIBM_EXTENT); | 150 | err = -ENOMEM; |
148 | return -ENOMEM; | 151 | goto err_release_region; |
149 | } | 152 | } |
150 | 153 | ||
151 | logibm_dev->name = "Logitech bus mouse"; | 154 | logibm_dev->name = "Logitech bus mouse"; |
@@ -162,9 +165,18 @@ static int __init logibm_init(void) | |||
162 | logibm_dev->open = logibm_open; | 165 | logibm_dev->open = logibm_open; |
163 | logibm_dev->close = logibm_close; | 166 | logibm_dev->close = logibm_close; |
164 | 167 | ||
165 | input_register_device(logibm_dev); | 168 | err = input_register_device(logibm_dev); |
169 | if (err) | ||
170 | goto err_free_dev; | ||
166 | 171 | ||
167 | return 0; | 172 | return 0; |
173 | |||
174 | err_free_dev: | ||
175 | input_free_device(logibm_dev); | ||
176 | err_release_region: | ||
177 | release_region(LOGIBM_BASE, LOGIBM_EXTENT); | ||
178 | |||
179 | return err; | ||
168 | } | 180 | } |
169 | 181 | ||
170 | static void __exit logibm_exit(void) | 182 | static void __exit logibm_exit(void) |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 8a4f862709e7..d3ddea26b8ca 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -328,6 +328,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
328 | unsigned char model, buttons; | 328 | unsigned char model, buttons; |
329 | const struct ps2pp_info *model_info; | 329 | const struct ps2pp_info *model_info; |
330 | int use_ps2pp = 0; | 330 | int use_ps2pp = 0; |
331 | int error; | ||
331 | 332 | ||
332 | param[0] = 0; | 333 | param[0] = 0; |
333 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | 334 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); |
@@ -393,8 +394,14 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
393 | psmouse->set_resolution = ps2pp_set_resolution; | 394 | psmouse->set_resolution = ps2pp_set_resolution; |
394 | psmouse->disconnect = ps2pp_disconnect; | 395 | psmouse->disconnect = ps2pp_disconnect; |
395 | 396 | ||
396 | device_create_file(&psmouse->ps2dev.serio->dev, | 397 | error = device_create_file(&psmouse->ps2dev.serio->dev, |
397 | &psmouse_attr_smartscroll.dattr); | 398 | &psmouse_attr_smartscroll.dattr); |
399 | if (error) { | ||
400 | printk(KERN_ERR | ||
401 | "logips2pp.c: failed to create smartscroll " | ||
402 | "sysfs attribute, error: %d\n", error); | ||
403 | return -1; | ||
404 | } | ||
398 | } | 405 | } |
399 | } | 406 | } |
400 | 407 | ||
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index 8c075aa7223b..f155c1fea04e 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
@@ -108,6 +108,7 @@ static int pc110pad_open(struct input_dev *dev) | |||
108 | static int __init pc110pad_init(void) | 108 | static int __init pc110pad_init(void) |
109 | { | 109 | { |
110 | struct pci_dev *dev; | 110 | struct pci_dev *dev; |
111 | int err; | ||
111 | 112 | ||
112 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); | 113 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); |
113 | if (dev) { | 114 | if (dev) { |
@@ -124,16 +125,16 @@ static int __init pc110pad_init(void) | |||
124 | outb(PC110PAD_OFF, pc110pad_io + 2); | 125 | outb(PC110PAD_OFF, pc110pad_io + 2); |
125 | 126 | ||
126 | if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) { | 127 | if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) { |
127 | release_region(pc110pad_io, 4); | ||
128 | printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq); | 128 | printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq); |
129 | return -EBUSY; | 129 | err = -EBUSY; |
130 | goto err_release_region; | ||
130 | } | 131 | } |
131 | 132 | ||
132 | if (!(pc110pad_dev = input_allocate_device())) { | 133 | pc110pad_dev = input_allocate_device(); |
133 | free_irq(pc110pad_irq, NULL); | 134 | if (!pc110pad_dev) { |
134 | release_region(pc110pad_io, 4); | ||
135 | printk(KERN_ERR "pc110pad: Not enough memory.\n"); | 135 | printk(KERN_ERR "pc110pad: Not enough memory.\n"); |
136 | return -ENOMEM; | 136 | err = -ENOMEM; |
137 | goto err_free_irq; | ||
137 | } | 138 | } |
138 | 139 | ||
139 | pc110pad_dev->name = "IBM PC110 TouchPad"; | 140 | pc110pad_dev->name = "IBM PC110 TouchPad"; |
@@ -153,9 +154,20 @@ static int __init pc110pad_init(void) | |||
153 | pc110pad_dev->open = pc110pad_open; | 154 | pc110pad_dev->open = pc110pad_open; |
154 | pc110pad_dev->close = pc110pad_close; | 155 | pc110pad_dev->close = pc110pad_close; |
155 | 156 | ||
156 | input_register_device(pc110pad_dev); | 157 | err = input_register_device(pc110pad_dev); |
158 | if (err) | ||
159 | goto err_free_dev; | ||
157 | 160 | ||
158 | return 0; | 161 | return 0; |
162 | |||
163 | err_free_dev: | ||
164 | input_free_device(pc110pad_dev); | ||
165 | err_free_irq: | ||
166 | free_irq(pc110pad_irq, NULL); | ||
167 | err_release_region: | ||
168 | release_region(pc110pad_io, 4); | ||
169 | |||
170 | return err; | ||
159 | } | 171 | } |
160 | 172 | ||
161 | static void __exit pc110pad_exit(void) | 173 | static void __exit pc110pad_exit(void) |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 52bb2226ce2f..a0e4a033e2db 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -1103,7 +1103,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
1103 | { | 1103 | { |
1104 | struct psmouse *psmouse, *parent = NULL; | 1104 | struct psmouse *psmouse, *parent = NULL; |
1105 | struct input_dev *input_dev; | 1105 | struct input_dev *input_dev; |
1106 | int retval = -ENOMEM; | 1106 | int retval = 0, error = -ENOMEM; |
1107 | 1107 | ||
1108 | mutex_lock(&psmouse_mutex); | 1108 | mutex_lock(&psmouse_mutex); |
1109 | 1109 | ||
@@ -1119,7 +1119,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
1119 | psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); | 1119 | psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); |
1120 | input_dev = input_allocate_device(); | 1120 | input_dev = input_allocate_device(); |
1121 | if (!psmouse || !input_dev) | 1121 | if (!psmouse || !input_dev) |
1122 | goto out; | 1122 | goto err_free; |
1123 | 1123 | ||
1124 | ps2_init(&psmouse->ps2dev, serio); | 1124 | ps2_init(&psmouse->ps2dev, serio); |
1125 | INIT_WORK(&psmouse->resync_work, psmouse_resync); | 1125 | INIT_WORK(&psmouse->resync_work, psmouse_resync); |
@@ -1130,14 +1130,13 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
1130 | 1130 | ||
1131 | serio_set_drvdata(serio, psmouse); | 1131 | serio_set_drvdata(serio, psmouse); |
1132 | 1132 | ||
1133 | retval = serio_open(serio, drv); | 1133 | error = serio_open(serio, drv); |
1134 | if (retval) | 1134 | if (error) |
1135 | goto out; | 1135 | goto err_clear_drvdata; |
1136 | 1136 | ||
1137 | if (psmouse_probe(psmouse) < 0) { | 1137 | if (psmouse_probe(psmouse) < 0) { |
1138 | serio_close(serio); | 1138 | error = -ENODEV; |
1139 | retval = -ENODEV; | 1139 | goto err_close_serio; |
1140 | goto out; | ||
1141 | } | 1140 | } |
1142 | 1141 | ||
1143 | psmouse->rate = psmouse_rate; | 1142 | psmouse->rate = psmouse_rate; |
@@ -1151,30 +1150,44 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
1151 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1150 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
1152 | psmouse_initialize(psmouse); | 1151 | psmouse_initialize(psmouse); |
1153 | 1152 | ||
1154 | input_register_device(psmouse->dev); | 1153 | error = input_register_device(psmouse->dev); |
1154 | if (error) | ||
1155 | goto err_protocol_disconnect; | ||
1155 | 1156 | ||
1156 | if (parent && parent->pt_activate) | 1157 | if (parent && parent->pt_activate) |
1157 | parent->pt_activate(parent); | 1158 | parent->pt_activate(parent); |
1158 | 1159 | ||
1159 | sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); | 1160 | error = sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); |
1161 | if (error) | ||
1162 | goto err_pt_deactivate; | ||
1160 | 1163 | ||
1161 | psmouse_activate(psmouse); | 1164 | psmouse_activate(psmouse); |
1162 | 1165 | ||
1163 | retval = 0; | 1166 | out: |
1164 | |||
1165 | out: | ||
1166 | if (retval) { | ||
1167 | serio_set_drvdata(serio, NULL); | ||
1168 | input_free_device(input_dev); | ||
1169 | kfree(psmouse); | ||
1170 | } | ||
1171 | |||
1172 | /* If this is a pass-through port the parent needs to be re-activated */ | 1167 | /* If this is a pass-through port the parent needs to be re-activated */ |
1173 | if (parent) | 1168 | if (parent) |
1174 | psmouse_activate(parent); | 1169 | psmouse_activate(parent); |
1175 | 1170 | ||
1176 | mutex_unlock(&psmouse_mutex); | 1171 | mutex_unlock(&psmouse_mutex); |
1177 | return retval; | 1172 | return retval; |
1173 | |||
1174 | err_pt_deactivate: | ||
1175 | if (parent && parent->pt_deactivate) | ||
1176 | parent->pt_deactivate(parent); | ||
1177 | err_protocol_disconnect: | ||
1178 | if (psmouse->disconnect) | ||
1179 | psmouse->disconnect(psmouse); | ||
1180 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
1181 | err_close_serio: | ||
1182 | serio_close(serio); | ||
1183 | err_clear_drvdata: | ||
1184 | serio_set_drvdata(serio, NULL); | ||
1185 | err_free: | ||
1186 | input_free_device(input_dev); | ||
1187 | kfree(psmouse); | ||
1188 | |||
1189 | retval = error; | ||
1190 | goto out; | ||
1178 | } | 1191 | } |
1179 | 1192 | ||
1180 | 1193 | ||
@@ -1337,14 +1350,14 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1337 | 1350 | ||
1338 | static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf) | 1351 | static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf) |
1339 | { | 1352 | { |
1340 | unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset); | 1353 | unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); |
1341 | 1354 | ||
1342 | return sprintf(buf, "%lu\n", *field); | 1355 | return sprintf(buf, "%u\n", *field); |
1343 | } | 1356 | } |
1344 | 1357 | ||
1345 | static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count) | 1358 | static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count) |
1346 | { | 1359 | { |
1347 | unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset); | 1360 | unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); |
1348 | unsigned long value; | 1361 | unsigned long value; |
1349 | char *rest; | 1362 | char *rest; |
1350 | 1363 | ||
@@ -1352,6 +1365,9 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const | |||
1352 | if (*rest) | 1365 | if (*rest) |
1353 | return -EINVAL; | 1366 | return -EINVAL; |
1354 | 1367 | ||
1368 | if ((unsigned int)value != value) | ||
1369 | return -EINVAL; | ||
1370 | |||
1355 | *field = value; | 1371 | *field = value; |
1356 | 1372 | ||
1357 | return count; | 1373 | return count; |
@@ -1366,17 +1382,20 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1366 | { | 1382 | { |
1367 | struct serio *serio = psmouse->ps2dev.serio; | 1383 | struct serio *serio = psmouse->ps2dev.serio; |
1368 | struct psmouse *parent = NULL; | 1384 | struct psmouse *parent = NULL; |
1369 | struct input_dev *new_dev; | 1385 | struct input_dev *old_dev, *new_dev; |
1370 | const struct psmouse_protocol *proto; | 1386 | const struct psmouse_protocol *proto, *old_proto; |
1387 | int error; | ||
1371 | int retry = 0; | 1388 | int retry = 0; |
1372 | 1389 | ||
1373 | if (!(proto = psmouse_protocol_by_name(buf, count))) | 1390 | proto = psmouse_protocol_by_name(buf, count); |
1391 | if (!proto) | ||
1374 | return -EINVAL; | 1392 | return -EINVAL; |
1375 | 1393 | ||
1376 | if (psmouse->type == proto->type) | 1394 | if (psmouse->type == proto->type) |
1377 | return count; | 1395 | return count; |
1378 | 1396 | ||
1379 | if (!(new_dev = input_allocate_device())) | 1397 | new_dev = input_allocate_device(); |
1398 | if (!new_dev) | ||
1380 | return -ENOMEM; | 1399 | return -ENOMEM; |
1381 | 1400 | ||
1382 | while (serio->child) { | 1401 | while (serio->child) { |
@@ -1409,11 +1428,13 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1409 | parent->pt_deactivate(parent); | 1428 | parent->pt_deactivate(parent); |
1410 | } | 1429 | } |
1411 | 1430 | ||
1431 | old_dev = psmouse->dev; | ||
1432 | old_proto = psmouse_protocol_by_type(psmouse->type); | ||
1433 | |||
1412 | if (psmouse->disconnect) | 1434 | if (psmouse->disconnect) |
1413 | psmouse->disconnect(psmouse); | 1435 | psmouse->disconnect(psmouse); |
1414 | 1436 | ||
1415 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 1437 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
1416 | input_unregister_device(psmouse->dev); | ||
1417 | 1438 | ||
1418 | psmouse->dev = new_dev; | 1439 | psmouse->dev = new_dev; |
1419 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 1440 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
@@ -1427,7 +1448,23 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1427 | psmouse_initialize(psmouse); | 1448 | psmouse_initialize(psmouse); |
1428 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1449 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
1429 | 1450 | ||
1430 | input_register_device(psmouse->dev); | 1451 | error = input_register_device(psmouse->dev); |
1452 | if (error) { | ||
1453 | if (psmouse->disconnect) | ||
1454 | psmouse->disconnect(psmouse); | ||
1455 | |||
1456 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
1457 | input_free_device(new_dev); | ||
1458 | psmouse->dev = old_dev; | ||
1459 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | ||
1460 | psmouse_switch_protocol(psmouse, old_proto); | ||
1461 | psmouse_initialize(psmouse); | ||
1462 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
1463 | |||
1464 | return error; | ||
1465 | } | ||
1466 | |||
1467 | input_unregister_device(old_dev); | ||
1431 | 1468 | ||
1432 | if (parent && parent->pt_activate) | 1469 | if (parent && parent->pt_activate) |
1433 | parent->pt_activate(parent); | 1470 | parent->pt_activate(parent); |
@@ -1488,15 +1525,19 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) | |||
1488 | 1525 | ||
1489 | static int __init psmouse_init(void) | 1526 | static int __init psmouse_init(void) |
1490 | { | 1527 | { |
1528 | int err; | ||
1529 | |||
1491 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1530 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1492 | if (!kpsmoused_wq) { | 1531 | if (!kpsmoused_wq) { |
1493 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); | 1532 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); |
1494 | return -ENOMEM; | 1533 | return -ENOMEM; |
1495 | } | 1534 | } |
1496 | 1535 | ||
1497 | serio_register_driver(&psmouse_drv); | 1536 | err = serio_register_driver(&psmouse_drv); |
1537 | if (err) | ||
1538 | destroy_workqueue(kpsmoused_wq); | ||
1498 | 1539 | ||
1499 | return 0; | 1540 | return err; |
1500 | } | 1541 | } |
1501 | 1542 | ||
1502 | static void __exit psmouse_exit(void) | 1543 | static void __exit psmouse_exit(void) |
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index ea0468569610..fbdcfd8eb4e9 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c | |||
@@ -66,7 +66,10 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) | |||
66 | 66 | ||
67 | static int __init rpcmouse_init(void) | 67 | static int __init rpcmouse_init(void) |
68 | { | 68 | { |
69 | if (!(rpcmouse_dev = input_allocate_device())) | 69 | int err; |
70 | |||
71 | rpcmouse_dev = input_allocate_device(); | ||
72 | if (!rpcmouse_dev) | ||
70 | return -ENOMEM; | 73 | return -ENOMEM; |
71 | 74 | ||
72 | rpcmouse_dev->name = "Acorn RiscPC Mouse"; | 75 | rpcmouse_dev->name = "Acorn RiscPC Mouse"; |
@@ -85,13 +88,22 @@ static int __init rpcmouse_init(void) | |||
85 | 88 | ||
86 | if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, IRQF_SHARED, "rpcmouse", rpcmouse_dev)) { | 89 | if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, IRQF_SHARED, "rpcmouse", rpcmouse_dev)) { |
87 | printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n"); | 90 | printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n"); |
88 | input_free_device(rpcmouse_dev); | 91 | err = -EBUSY; |
89 | return -EBUSY; | 92 | goto err_free_dev; |
90 | } | 93 | } |
91 | 94 | ||
92 | input_register_device(rpcmouse_dev); | 95 | err = input_register_device(rpcmouse_dev); |
96 | if (err) | ||
97 | goto err_free_irq; | ||
93 | 98 | ||
94 | return 0; | 99 | return 0; |
100 | |||
101 | err_free_irq: | ||
102 | free_irq(IRQ_VSYNCPULSE, rpcmouse_dev); | ||
103 | err_free_dev: | ||
104 | input_free_device(rpcmouse_dev); | ||
105 | |||
106 | return err; | ||
95 | } | 107 | } |
96 | 108 | ||
97 | static void __exit rpcmouse_exit(void) | 109 | static void __exit rpcmouse_exit(void) |
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 2a272c5daf08..a85d74710b44 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -246,7 +246,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) | |||
246 | sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL); | 246 | sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL); |
247 | input_dev = input_allocate_device(); | 247 | input_dev = input_allocate_device(); |
248 | if (!sermouse || !input_dev) | 248 | if (!sermouse || !input_dev) |
249 | goto fail; | 249 | goto fail1; |
250 | 250 | ||
251 | sermouse->dev = input_dev; | 251 | sermouse->dev = input_dev; |
252 | snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys); | 252 | snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys); |
@@ -275,14 +275,17 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) | |||
275 | 275 | ||
276 | err = serio_open(serio, drv); | 276 | err = serio_open(serio, drv); |
277 | if (err) | 277 | if (err) |
278 | goto fail; | 278 | goto fail2; |
279 | 279 | ||
280 | input_register_device(sermouse->dev); | 280 | err = input_register_device(sermouse->dev); |
281 | if (err) | ||
282 | goto fail3; | ||
281 | 283 | ||
282 | return 0; | 284 | return 0; |
283 | 285 | ||
284 | fail: serio_set_drvdata(serio, NULL); | 286 | fail3: serio_close(serio); |
285 | input_free_device(input_dev); | 287 | fail2: serio_set_drvdata(serio, NULL); |
288 | fail1: input_free_device(input_dev); | ||
286 | kfree(sermouse); | 289 | kfree(sermouse); |
287 | return err; | 290 | return err; |
288 | } | 291 | } |
@@ -348,8 +351,7 @@ static struct serio_driver sermouse_drv = { | |||
348 | 351 | ||
349 | static int __init sermouse_init(void) | 352 | static int __init sermouse_init(void) |
350 | { | 353 | { |
351 | serio_register_driver(&sermouse_drv); | 354 | return serio_register_driver(&sermouse_drv); |
352 | return 0; | ||
353 | } | 355 | } |
354 | 356 | ||
355 | static void __exit sermouse_exit(void) | 357 | static void __exit sermouse_exit(void) |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index ae5871a0e060..9ab5b5ea809d 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -293,6 +293,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) | |||
293 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 293 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
294 | unsigned char firmware_id; | 294 | unsigned char firmware_id; |
295 | unsigned char button_info; | 295 | unsigned char button_info; |
296 | int error; | ||
296 | 297 | ||
297 | if (trackpoint_start_protocol(psmouse, &firmware_id)) | 298 | if (trackpoint_start_protocol(psmouse, &firmware_id)) |
298 | return -1; | 299 | return -1; |
@@ -305,7 +306,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) | |||
305 | button_info = 0; | 306 | button_info = 0; |
306 | } | 307 | } |
307 | 308 | ||
308 | psmouse->private = priv = kcalloc(1, sizeof(struct trackpoint_data), GFP_KERNEL); | 309 | psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); |
309 | if (!priv) | 310 | if (!priv) |
310 | return -1; | 311 | return -1; |
311 | 312 | ||
@@ -318,7 +319,14 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) | |||
318 | trackpoint_defaults(priv); | 319 | trackpoint_defaults(priv); |
319 | trackpoint_sync(psmouse); | 320 | trackpoint_sync(psmouse); |
320 | 321 | ||
321 | sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); | 322 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); |
323 | if (error) { | ||
324 | printk(KERN_ERR | ||
325 | "trackpoint.c: failed to create sysfs attributes, error: %d\n", | ||
326 | error); | ||
327 | kfree(priv); | ||
328 | return -1; | ||
329 | } | ||
322 | 330 | ||
323 | printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", | 331 | printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", |
324 | firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); | 332 | firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index ffdb50eee93d..c3d64fcc858d 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -497,7 +497,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
497 | mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); | 497 | mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); |
498 | input_dev = input_allocate_device (); | 498 | input_dev = input_allocate_device (); |
499 | if (!mouse || !input_dev) | 499 | if (!mouse || !input_dev) |
500 | goto fail; | 500 | goto fail1; |
501 | 501 | ||
502 | mouse->dev = input_dev; | 502 | mouse->dev = input_dev; |
503 | mouse->serio = serio; | 503 | mouse->serio = serio; |
@@ -527,7 +527,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
527 | 527 | ||
528 | err = serio_open (serio, drv); | 528 | err = serio_open (serio, drv); |
529 | if (err) | 529 | if (err) |
530 | goto fail; | 530 | goto fail2; |
531 | 531 | ||
532 | /* | 532 | /* |
533 | * Request selftest. Standard packet format and differential | 533 | * Request selftest. Standard packet format and differential |
@@ -535,12 +535,15 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
535 | */ | 535 | */ |
536 | serio->write (serio, 'T'); /* Test */ | 536 | serio->write (serio, 'T'); /* Test */ |
537 | 537 | ||
538 | input_register_device (input_dev); | 538 | err = input_register_device (input_dev); |
539 | if (err) | ||
540 | goto fail3; | ||
539 | 541 | ||
540 | return 0; | 542 | return 0; |
541 | 543 | ||
542 | fail: serio_set_drvdata (serio, NULL); | 544 | fail3: serio_close (serio); |
543 | input_free_device (input_dev); | 545 | fail2: serio_set_drvdata (serio, NULL); |
546 | fail1: input_free_device (input_dev); | ||
544 | kfree (mouse); | 547 | kfree (mouse); |
545 | return err; | 548 | return err; |
546 | } | 549 | } |
@@ -571,8 +574,7 @@ static struct serio_driver vsxxxaa_drv = { | |||
571 | static int __init | 574 | static int __init |
572 | vsxxxaa_init (void) | 575 | vsxxxaa_init (void) |
573 | { | 576 | { |
574 | serio_register_driver(&vsxxxaa_drv); | 577 | return serio_register_driver(&vsxxxaa_drv); |
575 | return 0; | ||
576 | } | 578 | } |
577 | 579 | ||
578 | static void __exit | 580 | static void __exit |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a22a74a2a3dc..664bcc8116fc 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -196,12 +196,12 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int | |||
196 | switch (code) { | 196 | switch (code) { |
197 | case BTN_TOUCH: | 197 | case BTN_TOUCH: |
198 | case BTN_0: | 198 | case BTN_0: |
199 | case BTN_FORWARD: | ||
200 | case BTN_LEFT: index = 0; break; | 199 | case BTN_LEFT: index = 0; break; |
201 | case BTN_STYLUS: | 200 | case BTN_STYLUS: |
202 | case BTN_1: | 201 | case BTN_1: |
203 | case BTN_RIGHT: index = 1; break; | 202 | case BTN_RIGHT: index = 1; break; |
204 | case BTN_2: | 203 | case BTN_2: |
204 | case BTN_FORWARD: | ||
205 | case BTN_STYLUS2: | 205 | case BTN_STYLUS2: |
206 | case BTN_MIDDLE: index = 2; break; | 206 | case BTN_MIDDLE: index = 2; break; |
207 | case BTN_3: | 207 | case BTN_3: |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 7e3141f37e32..debe9445488c 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -255,25 +255,10 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) | |||
255 | static int i8042_aux_write(struct serio *serio, unsigned char c) | 255 | static int i8042_aux_write(struct serio *serio, unsigned char c) |
256 | { | 256 | { |
257 | struct i8042_port *port = serio->port_data; | 257 | struct i8042_port *port = serio->port_data; |
258 | int retval; | ||
259 | |||
260 | /* | ||
261 | * Send the byte out. | ||
262 | */ | ||
263 | |||
264 | if (port->mux == -1) | ||
265 | retval = i8042_command(&c, I8042_CMD_AUX_SEND); | ||
266 | else | ||
267 | retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux); | ||
268 | |||
269 | /* | ||
270 | * Make sure the interrupt happens and the character is received even | ||
271 | * in the case the IRQ isn't wired, so that we can receive further | ||
272 | * characters later. | ||
273 | */ | ||
274 | 258 | ||
275 | i8042_interrupt(0, NULL); | 259 | return i8042_command(&c, port->mux == -1 ? |
276 | return retval; | 260 | I8042_CMD_AUX_SEND : |
261 | I8042_CMD_MUX_SEND + port->mux); | ||
277 | } | 262 | } |
278 | 263 | ||
279 | /* | 264 | /* |
@@ -337,23 +322,27 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
337 | dfl = 0; | 322 | dfl = 0; |
338 | if (str & I8042_STR_MUXERR) { | 323 | if (str & I8042_STR_MUXERR) { |
339 | dbg("MUX error, status is %02x, data is %02x", str, data); | 324 | dbg("MUX error, status is %02x, data is %02x", str, data); |
340 | switch (data) { | ||
341 | default: | ||
342 | /* | 325 | /* |
343 | * When MUXERR condition is signalled the data register can only contain | 326 | * When MUXERR condition is signalled the data register can only contain |
344 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately | 327 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately |
345 | * it is not always the case. Some KBC just get confused which port the | 328 | * it is not always the case. Some KBCs also report 0xfc when there is |
346 | * data came from and signal error leaving the data intact. They _do not_ | 329 | * nothing connected to the port while others sometimes get confused which |
347 | * revert to legacy mode (actually I've never seen KBC reverting to legacy | 330 | * port the data came from and signal error leaving the data intact. They |
348 | * mode yet, when we see one we'll add proper handling). | 331 | * _do not_ revert to legacy mode (actually I've never seen KBC reverting |
349 | * Anyway, we will assume that the data came from the same serio last byte | 332 | * to legacy mode yet, when we see one we'll add proper handling). |
333 | * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the | ||
334 | * rest assume that the data came from the same serio last byte | ||
350 | * was transmitted (if transmission happened not too long ago). | 335 | * was transmitted (if transmission happened not too long ago). |
351 | */ | 336 | */ |
337 | |||
338 | switch (data) { | ||
339 | default: | ||
352 | if (time_before(jiffies, last_transmit + HZ/10)) { | 340 | if (time_before(jiffies, last_transmit + HZ/10)) { |
353 | str = last_str; | 341 | str = last_str; |
354 | break; | 342 | break; |
355 | } | 343 | } |
356 | /* fall through - report timeout */ | 344 | /* fall through - report timeout */ |
345 | case 0xfc: | ||
357 | case 0xfd: | 346 | case 0xfd: |
358 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; | 347 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; |
359 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; | 348 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 5f1d4032fd57..f0ce822c1028 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -45,8 +45,7 @@ EXPORT_SYMBOL(serio_interrupt); | |||
45 | EXPORT_SYMBOL(__serio_register_port); | 45 | EXPORT_SYMBOL(__serio_register_port); |
46 | EXPORT_SYMBOL(serio_unregister_port); | 46 | EXPORT_SYMBOL(serio_unregister_port); |
47 | EXPORT_SYMBOL(serio_unregister_child_port); | 47 | EXPORT_SYMBOL(serio_unregister_child_port); |
48 | EXPORT_SYMBOL(__serio_unregister_port_delayed); | 48 | EXPORT_SYMBOL(serio_register_driver); |
49 | EXPORT_SYMBOL(__serio_register_driver); | ||
50 | EXPORT_SYMBOL(serio_unregister_driver); | 49 | EXPORT_SYMBOL(serio_unregister_driver); |
51 | EXPORT_SYMBOL(serio_open); | 50 | EXPORT_SYMBOL(serio_open); |
52 | EXPORT_SYMBOL(serio_close); | 51 | EXPORT_SYMBOL(serio_close); |
@@ -63,11 +62,10 @@ static LIST_HEAD(serio_list); | |||
63 | 62 | ||
64 | static struct bus_type serio_bus; | 63 | static struct bus_type serio_bus; |
65 | 64 | ||
66 | static void serio_add_driver(struct serio_driver *drv); | ||
67 | static void serio_add_port(struct serio *serio); | 65 | static void serio_add_port(struct serio *serio); |
68 | static void serio_destroy_port(struct serio *serio); | ||
69 | static void serio_reconnect_port(struct serio *serio); | 66 | static void serio_reconnect_port(struct serio *serio); |
70 | static void serio_disconnect_port(struct serio *serio); | 67 | static void serio_disconnect_port(struct serio *serio); |
68 | static void serio_attach_driver(struct serio_driver *drv); | ||
71 | 69 | ||
72 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | 70 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) |
73 | { | 71 | { |
@@ -171,11 +169,10 @@ static void serio_find_driver(struct serio *serio) | |||
171 | */ | 169 | */ |
172 | 170 | ||
173 | enum serio_event_type { | 171 | enum serio_event_type { |
174 | SERIO_RESCAN, | 172 | SERIO_RESCAN_PORT, |
175 | SERIO_RECONNECT, | 173 | SERIO_RECONNECT_PORT, |
176 | SERIO_REGISTER_PORT, | 174 | SERIO_REGISTER_PORT, |
177 | SERIO_UNREGISTER_PORT, | 175 | SERIO_ATTACH_DRIVER, |
178 | SERIO_REGISTER_DRIVER, | ||
179 | }; | 176 | }; |
180 | 177 | ||
181 | struct serio_event { | 178 | struct serio_event { |
@@ -190,11 +187,12 @@ static LIST_HEAD(serio_event_list); | |||
190 | static DECLARE_WAIT_QUEUE_HEAD(serio_wait); | 187 | static DECLARE_WAIT_QUEUE_HEAD(serio_wait); |
191 | static struct task_struct *serio_task; | 188 | static struct task_struct *serio_task; |
192 | 189 | ||
193 | static void serio_queue_event(void *object, struct module *owner, | 190 | static int serio_queue_event(void *object, struct module *owner, |
194 | enum serio_event_type event_type) | 191 | enum serio_event_type event_type) |
195 | { | 192 | { |
196 | unsigned long flags; | 193 | unsigned long flags; |
197 | struct serio_event *event; | 194 | struct serio_event *event; |
195 | int retval = 0; | ||
198 | 196 | ||
199 | spin_lock_irqsave(&serio_event_lock, flags); | 197 | spin_lock_irqsave(&serio_event_lock, flags); |
200 | 198 | ||
@@ -213,24 +211,34 @@ static void serio_queue_event(void *object, struct module *owner, | |||
213 | } | 211 | } |
214 | } | 212 | } |
215 | 213 | ||
216 | if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { | 214 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); |
217 | if (!try_module_get(owner)) { | 215 | if (!event) { |
218 | printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); | 216 | printk(KERN_ERR |
219 | kfree(event); | 217 | "serio: Not enough memory to queue event %d\n", |
220 | goto out; | 218 | event_type); |
221 | } | 219 | retval = -ENOMEM; |
222 | 220 | goto out; | |
223 | event->type = event_type; | 221 | } |
224 | event->object = object; | ||
225 | event->owner = owner; | ||
226 | 222 | ||
227 | list_add_tail(&event->node, &serio_event_list); | 223 | if (!try_module_get(owner)) { |
228 | wake_up(&serio_wait); | 224 | printk(KERN_WARNING |
229 | } else { | 225 | "serio: Can't get module reference, dropping event %d\n", |
230 | printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type); | 226 | event_type); |
227 | kfree(event); | ||
228 | retval = -EINVAL; | ||
229 | goto out; | ||
231 | } | 230 | } |
231 | |||
232 | event->type = event_type; | ||
233 | event->object = object; | ||
234 | event->owner = owner; | ||
235 | |||
236 | list_add_tail(&event->node, &serio_event_list); | ||
237 | wake_up(&serio_wait); | ||
238 | |||
232 | out: | 239 | out: |
233 | spin_unlock_irqrestore(&serio_event_lock, flags); | 240 | spin_unlock_irqrestore(&serio_event_lock, flags); |
241 | return retval; | ||
234 | } | 242 | } |
235 | 243 | ||
236 | static void serio_free_event(struct serio_event *event) | 244 | static void serio_free_event(struct serio_event *event) |
@@ -308,22 +316,17 @@ static void serio_handle_event(void) | |||
308 | serio_add_port(event->object); | 316 | serio_add_port(event->object); |
309 | break; | 317 | break; |
310 | 318 | ||
311 | case SERIO_UNREGISTER_PORT: | 319 | case SERIO_RECONNECT_PORT: |
312 | serio_disconnect_port(event->object); | ||
313 | serio_destroy_port(event->object); | ||
314 | break; | ||
315 | |||
316 | case SERIO_RECONNECT: | ||
317 | serio_reconnect_port(event->object); | 320 | serio_reconnect_port(event->object); |
318 | break; | 321 | break; |
319 | 322 | ||
320 | case SERIO_RESCAN: | 323 | case SERIO_RESCAN_PORT: |
321 | serio_disconnect_port(event->object); | 324 | serio_disconnect_port(event->object); |
322 | serio_find_driver(event->object); | 325 | serio_find_driver(event->object); |
323 | break; | 326 | break; |
324 | 327 | ||
325 | case SERIO_REGISTER_DRIVER: | 328 | case SERIO_ATTACH_DRIVER: |
326 | serio_add_driver(event->object); | 329 | serio_attach_driver(event->object); |
327 | break; | 330 | break; |
328 | 331 | ||
329 | default: | 332 | default: |
@@ -675,12 +678,12 @@ static void serio_disconnect_port(struct serio *serio) | |||
675 | 678 | ||
676 | void serio_rescan(struct serio *serio) | 679 | void serio_rescan(struct serio *serio) |
677 | { | 680 | { |
678 | serio_queue_event(serio, NULL, SERIO_RESCAN); | 681 | serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); |
679 | } | 682 | } |
680 | 683 | ||
681 | void serio_reconnect(struct serio *serio) | 684 | void serio_reconnect(struct serio *serio) |
682 | { | 685 | { |
683 | serio_queue_event(serio, NULL, SERIO_RECONNECT); | 686 | serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); |
684 | } | 687 | } |
685 | 688 | ||
686 | /* | 689 | /* |
@@ -717,16 +720,6 @@ void serio_unregister_child_port(struct serio *serio) | |||
717 | mutex_unlock(&serio_mutex); | 720 | mutex_unlock(&serio_mutex); |
718 | } | 721 | } |
719 | 722 | ||
720 | /* | ||
721 | * Submits register request to kseriod for subsequent execution. | ||
722 | * Can be used when it is not obvious whether the serio_mutex is | ||
723 | * taken or not and when delayed execution is feasible. | ||
724 | */ | ||
725 | void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) | ||
726 | { | ||
727 | serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT); | ||
728 | } | ||
729 | |||
730 | 723 | ||
731 | /* | 724 | /* |
732 | * Serio driver operations | 725 | * Serio driver operations |
@@ -785,28 +778,52 @@ static int serio_driver_remove(struct device *dev) | |||
785 | return 0; | 778 | return 0; |
786 | } | 779 | } |
787 | 780 | ||
788 | static struct bus_type serio_bus = { | 781 | static void serio_attach_driver(struct serio_driver *drv) |
789 | .name = "serio", | ||
790 | .probe = serio_driver_probe, | ||
791 | .remove = serio_driver_remove, | ||
792 | }; | ||
793 | |||
794 | static void serio_add_driver(struct serio_driver *drv) | ||
795 | { | 782 | { |
796 | int error; | 783 | int error; |
797 | 784 | ||
798 | error = driver_register(&drv->driver); | 785 | error = driver_attach(&drv->driver); |
799 | if (error) | 786 | if (error) |
800 | printk(KERN_ERR | 787 | printk(KERN_WARNING |
801 | "serio: driver_register() failed for %s, error: %d\n", | 788 | "serio: driver_attach() failed for %s with error %d\n", |
802 | drv->driver.name, error); | 789 | drv->driver.name, error); |
803 | } | 790 | } |
804 | 791 | ||
805 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) | 792 | int serio_register_driver(struct serio_driver *drv) |
806 | { | 793 | { |
794 | int manual_bind = drv->manual_bind; | ||
795 | int error; | ||
796 | |||
807 | drv->driver.bus = &serio_bus; | 797 | drv->driver.bus = &serio_bus; |
808 | 798 | ||
809 | serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER); | 799 | /* |
800 | * Temporarily disable automatic binding because probing | ||
801 | * takes long time and we are better off doing it in kseriod | ||
802 | */ | ||
803 | drv->manual_bind = 1; | ||
804 | |||
805 | error = driver_register(&drv->driver); | ||
806 | if (error) { | ||
807 | printk(KERN_ERR | ||
808 | "serio: driver_register() failed for %s, error: %d\n", | ||
809 | drv->driver.name, error); | ||
810 | return error; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Restore original bind mode and let kseriod bind the | ||
815 | * driver to free ports | ||
816 | */ | ||
817 | if (!manual_bind) { | ||
818 | drv->manual_bind = 0; | ||
819 | error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER); | ||
820 | if (error) { | ||
821 | driver_unregister(&drv->driver); | ||
822 | return error; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | return 0; | ||
810 | } | 827 | } |
811 | 828 | ||
812 | void serio_unregister_driver(struct serio_driver *drv) | 829 | void serio_unregister_driver(struct serio_driver *drv) |
@@ -947,15 +964,21 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
947 | return ret; | 964 | return ret; |
948 | } | 965 | } |
949 | 966 | ||
967 | static struct bus_type serio_bus = { | ||
968 | .name = "serio", | ||
969 | .dev_attrs = serio_device_attrs, | ||
970 | .drv_attrs = serio_driver_attrs, | ||
971 | .match = serio_bus_match, | ||
972 | .uevent = serio_uevent, | ||
973 | .probe = serio_driver_probe, | ||
974 | .remove = serio_driver_remove, | ||
975 | .resume = serio_resume, | ||
976 | }; | ||
977 | |||
950 | static int __init serio_init(void) | 978 | static int __init serio_init(void) |
951 | { | 979 | { |
952 | int error; | 980 | int error; |
953 | 981 | ||
954 | serio_bus.dev_attrs = serio_device_attrs; | ||
955 | serio_bus.drv_attrs = serio_driver_attrs; | ||
956 | serio_bus.match = serio_bus_match; | ||
957 | serio_bus.uevent = serio_uevent; | ||
958 | serio_bus.resume = serio_resume; | ||
959 | error = bus_register(&serio_bus); | 982 | error = bus_register(&serio_bus); |
960 | if (error) { | 983 | if (error) { |
961 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | 984 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 7c8d0399ae82..088ebc348ba3 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -389,8 +389,7 @@ static struct serio_driver serio_raw_drv = { | |||
389 | 389 | ||
390 | static int __init serio_raw_init(void) | 390 | static int __init serio_raw_init(void) |
391 | { | 391 | { |
392 | serio_register_driver(&serio_raw_drv); | 392 | return serio_register_driver(&serio_raw_drv); |
393 | return 0; | ||
394 | } | 393 | } |
395 | 394 | ||
396 | static void __exit serio_raw_exit(void) | 395 | static void __exit serio_raw_exit(void) |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 9418bbe47072..29ca0ab0acb8 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -144,4 +144,19 @@ config TOUCHSCREEN_TOUCHWIN | |||
144 | To compile this driver as a module, choose M here: the | 144 | To compile this driver as a module, choose M here: the |
145 | module will be called touchwin. | 145 | module will be called touchwin. |
146 | 146 | ||
147 | config TOUCHSCREEN_UCB1400 | ||
148 | tristate "Philips UCB1400 touchscreen" | ||
149 | select SND_AC97_BUS | ||
150 | help | ||
151 | This enables support for the Philips UCB1400 touchscreen interface. | ||
152 | The UCB1400 is an AC97 audio codec. The touchscreen interface | ||
153 | will be initialized only after the ALSA subsystem has been | ||
154 | brought up and the UCB1400 detected. You therefore have to | ||
155 | configure ALSA support as well (either built-in or modular, | ||
156 | independently of whether this driver is itself built-in or | ||
157 | modular) for this driver to work. | ||
158 | |||
159 | To compile this driver as a module, choose M here: the | ||
160 | module will be called ucb1400_ts. | ||
161 | |||
147 | endif | 162 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 1abb8f10d608..30e6e2217a15 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -15,3 +15,4 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o | |||
15 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 15 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
16 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 16 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
17 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 17 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
18 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 0517c7387d67..c6164b6f476a 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -76,6 +76,7 @@ struct ads7846 { | |||
76 | char phys[32]; | 76 | char phys[32]; |
77 | 77 | ||
78 | struct spi_device *spi; | 78 | struct spi_device *spi; |
79 | struct attribute_group *attr_group; | ||
79 | u16 model; | 80 | u16 model; |
80 | u16 vref_delay_usecs; | 81 | u16 vref_delay_usecs; |
81 | u16 x_plate_ohms; | 82 | u16 x_plate_ohms; |
@@ -317,6 +318,48 @@ static ssize_t ads7846_disable_store(struct device *dev, | |||
317 | 318 | ||
318 | static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); | 319 | static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); |
319 | 320 | ||
321 | static struct attribute *ads7846_attributes[] = { | ||
322 | &dev_attr_temp0.attr, | ||
323 | &dev_attr_temp1.attr, | ||
324 | &dev_attr_vbatt.attr, | ||
325 | &dev_attr_vaux.attr, | ||
326 | &dev_attr_pen_down.attr, | ||
327 | &dev_attr_disable.attr, | ||
328 | NULL, | ||
329 | }; | ||
330 | |||
331 | static struct attribute_group ads7846_attr_group = { | ||
332 | .attrs = ads7846_attributes, | ||
333 | }; | ||
334 | |||
335 | /* | ||
336 | * ads7843/7845 don't have temperature sensors, and | ||
337 | * use the other sensors a bit differently too | ||
338 | */ | ||
339 | |||
340 | static struct attribute *ads7843_attributes[] = { | ||
341 | &dev_attr_vbatt.attr, | ||
342 | &dev_attr_vaux.attr, | ||
343 | &dev_attr_pen_down.attr, | ||
344 | &dev_attr_disable.attr, | ||
345 | NULL, | ||
346 | }; | ||
347 | |||
348 | static struct attribute_group ads7843_attr_group = { | ||
349 | .attrs = ads7843_attributes, | ||
350 | }; | ||
351 | |||
352 | static struct attribute *ads7845_attributes[] = { | ||
353 | &dev_attr_vaux.attr, | ||
354 | &dev_attr_pen_down.attr, | ||
355 | &dev_attr_disable.attr, | ||
356 | NULL, | ||
357 | }; | ||
358 | |||
359 | static struct attribute_group ads7845_attr_group = { | ||
360 | .attrs = ads7845_attributes, | ||
361 | }; | ||
362 | |||
320 | /*--------------------------------------------------------------------------*/ | 363 | /*--------------------------------------------------------------------------*/ |
321 | 364 | ||
322 | /* | 365 | /* |
@@ -788,38 +831,30 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
788 | (void) ads7846_read12_ser(&spi->dev, | 831 | (void) ads7846_read12_ser(&spi->dev, |
789 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | 832 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); |
790 | 833 | ||
791 | /* ads7843/7845 don't have temperature sensors, and | 834 | switch (ts->model) { |
792 | * use the other sensors a bit differently too | 835 | case 7846: |
793 | */ | 836 | ts->attr_group = &ads7846_attr_group; |
794 | if (ts->model == 7846) { | 837 | break; |
795 | device_create_file(&spi->dev, &dev_attr_temp0); | 838 | case 7845: |
796 | device_create_file(&spi->dev, &dev_attr_temp1); | 839 | ts->attr_group = &ads7845_attr_group; |
840 | break; | ||
841 | default: | ||
842 | ts->attr_group = &ads7843_attr_group; | ||
843 | break; | ||
797 | } | 844 | } |
798 | if (ts->model != 7845) | 845 | err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); |
799 | device_create_file(&spi->dev, &dev_attr_vbatt); | 846 | if (err) |
800 | device_create_file(&spi->dev, &dev_attr_vaux); | 847 | goto err_free_irq; |
801 | |||
802 | device_create_file(&spi->dev, &dev_attr_pen_down); | ||
803 | |||
804 | device_create_file(&spi->dev, &dev_attr_disable); | ||
805 | 848 | ||
806 | err = input_register_device(input_dev); | 849 | err = input_register_device(input_dev); |
807 | if (err) | 850 | if (err) |
808 | goto err_remove_attr; | 851 | goto err_remove_attr_group; |
809 | 852 | ||
810 | return 0; | 853 | return 0; |
811 | 854 | ||
812 | err_remove_attr: | 855 | err_remove_attr_group: |
813 | device_remove_file(&spi->dev, &dev_attr_disable); | 856 | sysfs_remove_group(&spi->dev.kobj, ts->attr_group); |
814 | device_remove_file(&spi->dev, &dev_attr_pen_down); | 857 | err_free_irq: |
815 | if (ts->model == 7846) { | ||
816 | device_remove_file(&spi->dev, &dev_attr_temp1); | ||
817 | device_remove_file(&spi->dev, &dev_attr_temp0); | ||
818 | } | ||
819 | if (ts->model != 7845) | ||
820 | device_remove_file(&spi->dev, &dev_attr_vbatt); | ||
821 | device_remove_file(&spi->dev, &dev_attr_vaux); | ||
822 | |||
823 | free_irq(spi->irq, ts); | 858 | free_irq(spi->irq, ts); |
824 | err_free_mem: | 859 | err_free_mem: |
825 | input_free_device(input_dev); | 860 | input_free_device(input_dev); |
@@ -835,15 +870,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
835 | 870 | ||
836 | ads7846_suspend(spi, PMSG_SUSPEND); | 871 | ads7846_suspend(spi, PMSG_SUSPEND); |
837 | 872 | ||
838 | device_remove_file(&spi->dev, &dev_attr_disable); | 873 | sysfs_remove_group(&spi->dev.kobj, ts->attr_group); |
839 | device_remove_file(&spi->dev, &dev_attr_pen_down); | ||
840 | if (ts->model == 7846) { | ||
841 | device_remove_file(&spi->dev, &dev_attr_temp1); | ||
842 | device_remove_file(&spi->dev, &dev_attr_temp0); | ||
843 | } | ||
844 | if (ts->model != 7845) | ||
845 | device_remove_file(&spi->dev, &dev_attr_vbatt); | ||
846 | device_remove_file(&spi->dev, &dev_attr_vaux); | ||
847 | 874 | ||
848 | free_irq(ts->spi->irq, ts); | 875 | free_irq(ts->spi->irq, ts); |
849 | /* suspend left the IRQ disabled */ | 876 | /* suspend left the IRQ disabled */ |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 66121f6a89ad..e2945582828e 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -175,17 +175,19 @@ static int read_xydata(struct corgi_ts *corgi_ts) | |||
175 | 175 | ||
176 | static void new_data(struct corgi_ts *corgi_ts) | 176 | static void new_data(struct corgi_ts *corgi_ts) |
177 | { | 177 | { |
178 | struct input_dev *dev = corgi_ts->input; | ||
179 | |||
178 | if (corgi_ts->power_mode != PWR_MODE_ACTIVE) | 180 | if (corgi_ts->power_mode != PWR_MODE_ACTIVE) |
179 | return; | 181 | return; |
180 | 182 | ||
181 | if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) | 183 | if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) |
182 | return; | 184 | return; |
183 | 185 | ||
184 | input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x); | 186 | input_report_abs(dev, ABS_X, corgi_ts->tc.x); |
185 | input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y); | 187 | input_report_abs(dev, ABS_Y, corgi_ts->tc.y); |
186 | input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); | 188 | input_report_abs(dev, ABS_PRESSURE, corgi_ts->tc.pressure); |
187 | input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); | 189 | input_report_key(dev, BTN_TOUCH, corgi_ts->pendown); |
188 | input_sync(corgi_ts->input); | 190 | input_sync(dev); |
189 | } | 191 | } |
190 | 192 | ||
191 | static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) | 193 | static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) |
@@ -219,12 +221,14 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) | |||
219 | static void corgi_ts_timer(unsigned long data) | 221 | static void corgi_ts_timer(unsigned long data) |
220 | { | 222 | { |
221 | struct corgi_ts *corgits_data = (struct corgi_ts *) data; | 223 | struct corgi_ts *corgits_data = (struct corgi_ts *) data; |
224 | |||
222 | ts_interrupt_main(corgits_data, 1); | 225 | ts_interrupt_main(corgits_data, 1); |
223 | } | 226 | } |
224 | 227 | ||
225 | static irqreturn_t ts_interrupt(int irq, void *dev_id) | 228 | static irqreturn_t ts_interrupt(int irq, void *dev_id) |
226 | { | 229 | { |
227 | struct corgi_ts *corgits_data = dev_id; | 230 | struct corgi_ts *corgits_data = dev_id; |
231 | |||
228 | ts_interrupt_main(corgits_data, 0); | 232 | ts_interrupt_main(corgits_data, 0); |
229 | return IRQ_HANDLED; | 233 | return IRQ_HANDLED; |
230 | } | 234 | } |
@@ -272,7 +276,7 @@ static int __init corgits_probe(struct platform_device *pdev) | |||
272 | corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); | 276 | corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); |
273 | input_dev = input_allocate_device(); | 277 | input_dev = input_allocate_device(); |
274 | if (!corgi_ts || !input_dev) | 278 | if (!corgi_ts || !input_dev) |
275 | goto fail; | 279 | goto fail1; |
276 | 280 | ||
277 | platform_set_drvdata(pdev, corgi_ts); | 281 | platform_set_drvdata(pdev, corgi_ts); |
278 | 282 | ||
@@ -281,7 +285,7 @@ static int __init corgits_probe(struct platform_device *pdev) | |||
281 | 285 | ||
282 | if (corgi_ts->irq_gpio < 0) { | 286 | if (corgi_ts->irq_gpio < 0) { |
283 | err = -ENODEV; | 287 | err = -ENODEV; |
284 | goto fail; | 288 | goto fail1; |
285 | } | 289 | } |
286 | 290 | ||
287 | corgi_ts->input = input_dev; | 291 | corgi_ts->input = input_dev; |
@@ -319,10 +323,12 @@ static int __init corgits_probe(struct platform_device *pdev) | |||
319 | 323 | ||
320 | if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) { | 324 | if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) { |
321 | err = -EBUSY; | 325 | err = -EBUSY; |
322 | goto fail; | 326 | goto fail1; |
323 | } | 327 | } |
324 | 328 | ||
325 | input_register_device(corgi_ts->input); | 329 | err = input_register_device(corgi_ts->input); |
330 | if (err) | ||
331 | goto fail2; | ||
326 | 332 | ||
327 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | 333 | corgi_ts->power_mode = PWR_MODE_ACTIVE; |
328 | 334 | ||
@@ -331,17 +337,17 @@ static int __init corgits_probe(struct platform_device *pdev) | |||
331 | 337 | ||
332 | return 0; | 338 | return 0; |
333 | 339 | ||
334 | fail: input_free_device(input_dev); | 340 | fail2: free_irq(corgi_ts->irq_gpio, corgi_ts); |
341 | fail1: input_free_device(input_dev); | ||
335 | kfree(corgi_ts); | 342 | kfree(corgi_ts); |
336 | return err; | 343 | return err; |
337 | |||
338 | } | 344 | } |
339 | 345 | ||
340 | static int corgits_remove(struct platform_device *pdev) | 346 | static int corgits_remove(struct platform_device *pdev) |
341 | { | 347 | { |
342 | struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); | 348 | struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); |
343 | 349 | ||
344 | free_irq(corgi_ts->irq_gpio, NULL); | 350 | free_irq(corgi_ts->irq_gpio, corgi_ts); |
345 | del_timer_sync(&corgi_ts->timer); | 351 | del_timer_sync(&corgi_ts->timer); |
346 | corgi_ts->machinfo->put_hsync(); | 352 | corgi_ts->machinfo->put_hsync(); |
347 | input_unregister_device(corgi_ts->input); | 353 | input_unregister_device(corgi_ts->input); |
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 913e1b73bb0e..9d61cd133d01 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
@@ -397,8 +397,7 @@ static struct serio_driver elo_drv = { | |||
397 | 397 | ||
398 | static int __init elo_init(void) | 398 | static int __init elo_init(void) |
399 | { | 399 | { |
400 | serio_register_driver(&elo_drv); | 400 | return serio_register_driver(&elo_drv); |
401 | return 0; | ||
402 | } | 401 | } |
403 | 402 | ||
404 | static void __exit elo_exit(void) | 403 | static void __exit elo_exit(void) |
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 817c2198933d..9157eb148e84 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
@@ -123,7 +123,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) | |||
123 | input_dev = input_allocate_device(); | 123 | input_dev = input_allocate_device(); |
124 | if (!gunze || !input_dev) { | 124 | if (!gunze || !input_dev) { |
125 | err = -ENOMEM; | 125 | err = -ENOMEM; |
126 | goto fail; | 126 | goto fail1; |
127 | } | 127 | } |
128 | 128 | ||
129 | gunze->serio = serio; | 129 | gunze->serio = serio; |
@@ -146,13 +146,17 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) | |||
146 | 146 | ||
147 | err = serio_open(serio, drv); | 147 | err = serio_open(serio, drv); |
148 | if (err) | 148 | if (err) |
149 | goto fail; | 149 | goto fail2; |
150 | |||
151 | err = input_register_device(gunze->dev); | ||
152 | if (err) | ||
153 | goto fail3; | ||
150 | 154 | ||
151 | input_register_device(gunze->dev); | ||
152 | return 0; | 155 | return 0; |
153 | 156 | ||
154 | fail: serio_set_drvdata(serio, NULL); | 157 | fail3: serio_close(serio); |
155 | input_free_device(input_dev); | 158 | fail2: serio_set_drvdata(serio, NULL); |
159 | fail1: input_free_device(input_dev); | ||
156 | kfree(gunze); | 160 | kfree(gunze); |
157 | return err; | 161 | return err; |
158 | } | 162 | } |
@@ -190,8 +194,7 @@ static struct serio_driver gunze_drv = { | |||
190 | 194 | ||
191 | static int __init gunze_init(void) | 195 | static int __init gunze_init(void) |
192 | { | 196 | { |
193 | serio_register_driver(&gunze_drv); | 197 | return serio_register_driver(&gunze_drv); |
194 | return 0; | ||
195 | } | 198 | } |
196 | 199 | ||
197 | static void __exit gunze_exit(void) | 200 | static void __exit gunze_exit(void) |
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index d9e61ee05ea9..c4116d4f64e7 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -478,8 +478,7 @@ static struct serio_driver h3600ts_drv = { | |||
478 | 478 | ||
479 | static int __init h3600ts_init(void) | 479 | static int __init h3600ts_init(void) |
480 | { | 480 | { |
481 | serio_register_driver(&h3600ts_drv); | 481 | return serio_register_driver(&h3600ts_drv); |
482 | return 0; | ||
483 | } | 482 | } |
484 | 483 | ||
485 | static void __exit h3600ts_exit(void) | 484 | static void __exit h3600ts_exit(void) |
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 58fca316786c..249087472740 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -76,38 +76,47 @@ static irqreturn_t hp680_ts_interrupt(int irq, void *dev) | |||
76 | 76 | ||
77 | static int __init hp680_ts_init(void) | 77 | static int __init hp680_ts_init(void) |
78 | { | 78 | { |
79 | int err; | ||
80 | |||
79 | hp680_ts_dev = input_allocate_device(); | 81 | hp680_ts_dev = input_allocate_device(); |
80 | if (!hp680_ts_dev) | 82 | if (!hp680_ts_dev) |
81 | return -ENOMEM; | 83 | return -ENOMEM; |
82 | 84 | ||
83 | hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); | 85 | hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); |
84 | hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); | ||
85 | hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 86 | hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
86 | 87 | ||
87 | hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN; | 88 | input_set_abs_params(hp680_ts_dev, ABS_X, |
88 | hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; | 89 | HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0); |
89 | hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX; | 90 | input_set_abs_params(hp680_ts_dev, ABS_Y, |
90 | hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; | 91 | HP680_TS_ABS_Y_MIN, HP680_TS_ABS_Y_MAX, 0, 0); |
91 | 92 | ||
92 | hp680_ts_dev->name = "HP Jornada touchscreen"; | 93 | hp680_ts_dev->name = "HP Jornada touchscreen"; |
93 | hp680_ts_dev->phys = "hp680_ts/input0"; | 94 | hp680_ts_dev->phys = "hp680_ts/input0"; |
94 | 95 | ||
95 | input_register_device(hp680_ts_dev); | ||
96 | |||
97 | if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, | 96 | if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, |
98 | IRQF_DISABLED, MODNAME, 0) < 0) { | 97 | IRQF_DISABLED, MODNAME, 0) < 0) { |
99 | printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", | 98 | printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", |
100 | HP680_TS_IRQ); | 99 | HP680_TS_IRQ); |
101 | input_unregister_device(hp680_ts_dev); | 100 | err = -EBUSY; |
102 | return -EBUSY; | 101 | goto fail1; |
103 | } | 102 | } |
104 | 103 | ||
104 | err = input_register_device(hp680_ts_dev); | ||
105 | if (err) | ||
106 | goto fail2; | ||
107 | |||
105 | return 0; | 108 | return 0; |
109 | |||
110 | fail2: free_irq(HP680_TS_IRQ, NULL); | ||
111 | cancel_delayed_work(&work); | ||
112 | flush_scheduled_work(); | ||
113 | fail1: input_free_device(hp680_ts_dev); | ||
114 | return err; | ||
106 | } | 115 | } |
107 | 116 | ||
108 | static void __exit hp680_ts_exit(void) | 117 | static void __exit hp680_ts_exit(void) |
109 | { | 118 | { |
110 | free_irq(HP680_TS_IRQ, 0); | 119 | free_irq(HP680_TS_IRQ, NULL); |
111 | cancel_delayed_work(&work); | 120 | cancel_delayed_work(&work); |
112 | flush_scheduled_work(); | 121 | flush_scheduled_work(); |
113 | input_unregister_device(hp680_ts_dev); | 122 | input_unregister_device(hp680_ts_dev); |
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index 4cbcaa6a71e5..44140feeffc5 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c | |||
@@ -96,15 +96,13 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) | |||
96 | goto end; | 96 | goto end; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (~status & MK712_STATUS_TOUCH) | 99 | if (~status & MK712_STATUS_TOUCH) { |
100 | { | ||
101 | debounce = 1; | 100 | debounce = 1; |
102 | input_report_key(mk712_dev, BTN_TOUCH, 0); | 101 | input_report_key(mk712_dev, BTN_TOUCH, 0); |
103 | goto end; | 102 | goto end; |
104 | } | 103 | } |
105 | 104 | ||
106 | if (debounce) | 105 | if (debounce) { |
107 | { | ||
108 | debounce = 0; | 106 | debounce = 0; |
109 | goto end; | 107 | goto end; |
110 | } | 108 | } |
@@ -113,8 +111,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) | |||
113 | input_report_abs(mk712_dev, ABS_X, last_x); | 111 | input_report_abs(mk712_dev, ABS_X, last_x); |
114 | input_report_abs(mk712_dev, ABS_Y, last_y); | 112 | input_report_abs(mk712_dev, ABS_Y, last_y); |
115 | 113 | ||
116 | end: | 114 | end: |
117 | |||
118 | last_x = inw(mk712_io + MK712_X) & 0x0fff; | 115 | last_x = inw(mk712_io + MK712_X) & 0x0fff; |
119 | last_y = inw(mk712_io + MK712_Y) & 0x0fff; | 116 | last_y = inw(mk712_io + MK712_Y) & 0x0fff; |
120 | input_sync(mk712_dev); | 117 | input_sync(mk712_dev); |
@@ -169,13 +166,14 @@ static int __init mk712_init(void) | |||
169 | (inw(mk712_io + MK712_STATUS) & 0xf333)) { | 166 | (inw(mk712_io + MK712_STATUS) & 0xf333)) { |
170 | printk(KERN_WARNING "mk712: device not present\n"); | 167 | printk(KERN_WARNING "mk712: device not present\n"); |
171 | err = -ENODEV; | 168 | err = -ENODEV; |
172 | goto fail; | 169 | goto fail1; |
173 | } | 170 | } |
174 | 171 | ||
175 | if (!(mk712_dev = input_allocate_device())) { | 172 | mk712_dev = input_allocate_device(); |
173 | if (!mk712_dev) { | ||
176 | printk(KERN_ERR "mk712: not enough memory\n"); | 174 | printk(KERN_ERR "mk712: not enough memory\n"); |
177 | err = -ENOMEM; | 175 | err = -ENOMEM; |
178 | goto fail; | 176 | goto fail1; |
179 | } | 177 | } |
180 | 178 | ||
181 | mk712_dev->name = "ICS MicroClock MK712 TouchScreen"; | 179 | mk712_dev->name = "ICS MicroClock MK712 TouchScreen"; |
@@ -196,13 +194,17 @@ static int __init mk712_init(void) | |||
196 | if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) { | 194 | if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) { |
197 | printk(KERN_WARNING "mk712: unable to get IRQ\n"); | 195 | printk(KERN_WARNING "mk712: unable to get IRQ\n"); |
198 | err = -EBUSY; | 196 | err = -EBUSY; |
199 | goto fail; | 197 | goto fail1; |
200 | } | 198 | } |
201 | 199 | ||
202 | input_register_device(mk712_dev); | 200 | err = input_register_device(mk712_dev); |
201 | if (err) | ||
202 | goto fail2; | ||
203 | |||
203 | return 0; | 204 | return 0; |
204 | 205 | ||
205 | fail: input_free_device(mk712_dev); | 206 | fail2: free_irq(mk712_irq, mk712_dev); |
207 | fail1: input_free_device(mk712_dev); | ||
206 | release_region(mk712_io, 8); | 208 | release_region(mk712_io, 8); |
207 | return err; | 209 | return err; |
208 | } | 210 | } |
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 3b4c61664b63..c3c2d735d0ec 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c | |||
@@ -137,7 +137,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) | |||
137 | input_dev = input_allocate_device(); | 137 | input_dev = input_allocate_device(); |
138 | if (!mtouch || !input_dev) { | 138 | if (!mtouch || !input_dev) { |
139 | err = -ENOMEM; | 139 | err = -ENOMEM; |
140 | goto fail; | 140 | goto fail1; |
141 | } | 141 | } |
142 | 142 | ||
143 | mtouch->serio = serio; | 143 | mtouch->serio = serio; |
@@ -160,14 +160,17 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) | |||
160 | 160 | ||
161 | err = serio_open(serio, drv); | 161 | err = serio_open(serio, drv); |
162 | if (err) | 162 | if (err) |
163 | goto fail; | 163 | goto fail2; |
164 | 164 | ||
165 | input_register_device(mtouch->dev); | 165 | err = input_register_device(mtouch->dev); |
166 | if (err) | ||
167 | goto fail3; | ||
166 | 168 | ||
167 | return 0; | 169 | return 0; |
168 | 170 | ||
169 | fail: serio_set_drvdata(serio, NULL); | 171 | fail3: serio_close(serio); |
170 | input_free_device(input_dev); | 172 | fail2: serio_set_drvdata(serio, NULL); |
173 | fail1: input_free_device(input_dev); | ||
171 | kfree(mtouch); | 174 | kfree(mtouch); |
172 | return err; | 175 | return err; |
173 | } | 176 | } |
@@ -205,8 +208,7 @@ static struct serio_driver mtouch_drv = { | |||
205 | 208 | ||
206 | static int __init mtouch_init(void) | 209 | static int __init mtouch_init(void) |
207 | { | 210 | { |
208 | serio_register_driver(&mtouch_drv); | 211 | return serio_register_driver(&mtouch_drv); |
209 | return 0; | ||
210 | } | 212 | } |
211 | 213 | ||
212 | static void __exit mtouch_exit(void) | 214 | static void __exit mtouch_exit(void) |
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 6c7d0c2c76cc..bd2767991ae9 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c | |||
@@ -171,8 +171,7 @@ static struct serio_driver pm_drv = { | |||
171 | 171 | ||
172 | static int __init pm_init(void) | 172 | static int __init pm_init(void) |
173 | { | 173 | { |
174 | serio_register_driver(&pm_drv); | 174 | return serio_register_driver(&pm_drv); |
175 | return 0; | ||
176 | } | 175 | } |
177 | 176 | ||
178 | static void __exit pm_exit(void) | 177 | static void __exit pm_exit(void) |
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index c74f74e57af0..35ba46c6ad2d 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c | |||
@@ -182,8 +182,7 @@ static struct serio_driver tr_drv = { | |||
182 | 182 | ||
183 | static int __init tr_init(void) | 183 | static int __init tr_init(void) |
184 | { | 184 | { |
185 | serio_register_driver(&tr_drv); | 185 | return serio_register_driver(&tr_drv); |
186 | return 0; | ||
187 | } | 186 | } |
188 | 187 | ||
189 | static void __exit tr_exit(void) | 188 | static void __exit tr_exit(void) |
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 9911820fa2fe..4dc073dacabb 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c | |||
@@ -189,8 +189,7 @@ static struct serio_driver tw_drv = { | |||
189 | 189 | ||
190 | static int __init tw_init(void) | 190 | static int __init tw_init(void) |
191 | { | 191 | { |
192 | serio_register_driver(&tw_drv); | 192 | return serio_register_driver(&tw_drv); |
193 | return 0; | ||
194 | } | 193 | } |
195 | 194 | ||
196 | static void __exit tw_exit(void) | 195 | static void __exit tw_exit(void) |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c new file mode 100644 index 000000000000..6ef08369f65b --- /dev/null +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -0,0 +1,579 @@ | |||
1 | /* | ||
2 | * Philips UCB1400 touchscreen driver | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: September 25, 2006 | ||
6 | * Copyright: MontaVista Software, Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This code is heavily based on ucb1x00-*.c copyrighted by Russell King | ||
13 | * covering the UCB1100, UCB1200 and UCB1300.. Support for the UCB1400 has | ||
14 | * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/moduleparam.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/completion.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/suspend.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/kthread.h> | ||
29 | |||
30 | #include <sound/driver.h> | ||
31 | #include <sound/core.h> | ||
32 | #include <sound/ac97_codec.h> | ||
33 | |||
34 | |||
35 | /* | ||
36 | * Interesting UCB1400 AC-link registers | ||
37 | */ | ||
38 | |||
39 | #define UCB_IE_RIS 0x5e | ||
40 | #define UCB_IE_FAL 0x60 | ||
41 | #define UCB_IE_STATUS 0x62 | ||
42 | #define UCB_IE_CLEAR 0x62 | ||
43 | #define UCB_IE_ADC (1 << 11) | ||
44 | #define UCB_IE_TSPX (1 << 12) | ||
45 | |||
46 | #define UCB_TS_CR 0x64 | ||
47 | #define UCB_TS_CR_TSMX_POW (1 << 0) | ||
48 | #define UCB_TS_CR_TSPX_POW (1 << 1) | ||
49 | #define UCB_TS_CR_TSMY_POW (1 << 2) | ||
50 | #define UCB_TS_CR_TSPY_POW (1 << 3) | ||
51 | #define UCB_TS_CR_TSMX_GND (1 << 4) | ||
52 | #define UCB_TS_CR_TSPX_GND (1 << 5) | ||
53 | #define UCB_TS_CR_TSMY_GND (1 << 6) | ||
54 | #define UCB_TS_CR_TSPY_GND (1 << 7) | ||
55 | #define UCB_TS_CR_MODE_INT (0 << 8) | ||
56 | #define UCB_TS_CR_MODE_PRES (1 << 8) | ||
57 | #define UCB_TS_CR_MODE_POS (2 << 8) | ||
58 | #define UCB_TS_CR_BIAS_ENA (1 << 11) | ||
59 | #define UCB_TS_CR_TSPX_LOW (1 << 12) | ||
60 | #define UCB_TS_CR_TSMX_LOW (1 << 13) | ||
61 | |||
62 | #define UCB_ADC_CR 0x66 | ||
63 | #define UCB_ADC_SYNC_ENA (1 << 0) | ||
64 | #define UCB_ADC_VREFBYP_CON (1 << 1) | ||
65 | #define UCB_ADC_INP_TSPX (0 << 2) | ||
66 | #define UCB_ADC_INP_TSMX (1 << 2) | ||
67 | #define UCB_ADC_INP_TSPY (2 << 2) | ||
68 | #define UCB_ADC_INP_TSMY (3 << 2) | ||
69 | #define UCB_ADC_INP_AD0 (4 << 2) | ||
70 | #define UCB_ADC_INP_AD1 (5 << 2) | ||
71 | #define UCB_ADC_INP_AD2 (6 << 2) | ||
72 | #define UCB_ADC_INP_AD3 (7 << 2) | ||
73 | #define UCB_ADC_EXT_REF (1 << 5) | ||
74 | #define UCB_ADC_START (1 << 7) | ||
75 | #define UCB_ADC_ENA (1 << 15) | ||
76 | |||
77 | #define UCB_ADC_DATA 0x68 | ||
78 | #define UCB_ADC_DAT_VALID (1 << 15) | ||
79 | #define UCB_ADC_DAT_VALUE(x) ((x) & 0x3ff) | ||
80 | |||
81 | #define UCB_ID 0x7e | ||
82 | #define UCB_ID_1400 0x4304 | ||
83 | |||
84 | |||
85 | struct ucb1400 { | ||
86 | ac97_t *ac97; | ||
87 | struct input_dev *ts_idev; | ||
88 | |||
89 | int irq; | ||
90 | |||
91 | wait_queue_head_t ts_wait; | ||
92 | struct task_struct *ts_task; | ||
93 | |||
94 | unsigned int irq_pending; /* not bit field shared */ | ||
95 | unsigned int ts_restart:1; | ||
96 | unsigned int adcsync:1; | ||
97 | }; | ||
98 | |||
99 | static int adcsync; | ||
100 | |||
101 | static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg) | ||
102 | { | ||
103 | return ucb->ac97->bus->ops->read(ucb->ac97, reg); | ||
104 | } | ||
105 | |||
106 | static inline void ucb1400_reg_write(struct ucb1400 *ucb, u16 reg, u16 val) | ||
107 | { | ||
108 | ucb->ac97->bus->ops->write(ucb->ac97, reg, val); | ||
109 | } | ||
110 | |||
111 | static inline void ucb1400_adc_enable(struct ucb1400 *ucb) | ||
112 | { | ||
113 | ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); | ||
114 | } | ||
115 | |||
116 | static unsigned int ucb1400_adc_read(struct ucb1400 *ucb, u16 adc_channel) | ||
117 | { | ||
118 | unsigned int val; | ||
119 | |||
120 | if (ucb->adcsync) | ||
121 | adc_channel |= UCB_ADC_SYNC_ENA; | ||
122 | |||
123 | ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel); | ||
124 | ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | UCB_ADC_START); | ||
125 | |||
126 | for (;;) { | ||
127 | val = ucb1400_reg_read(ucb, UCB_ADC_DATA); | ||
128 | if (val & UCB_ADC_DAT_VALID) | ||
129 | break; | ||
130 | /* yield to other processes */ | ||
131 | set_current_state(TASK_INTERRUPTIBLE); | ||
132 | schedule_timeout(1); | ||
133 | } | ||
134 | |||
135 | return UCB_ADC_DAT_VALUE(val); | ||
136 | } | ||
137 | |||
138 | static inline void ucb1400_adc_disable(struct ucb1400 *ucb) | ||
139 | { | ||
140 | ucb1400_reg_write(ucb, UCB_ADC_CR, 0); | ||
141 | } | ||
142 | |||
143 | /* Switch to interrupt mode. */ | ||
144 | static inline void ucb1400_ts_mode_int(struct ucb1400 *ucb) | ||
145 | { | ||
146 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
147 | UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | | ||
148 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | | ||
149 | UCB_TS_CR_MODE_INT); | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * Switch to pressure mode, and read pressure. We don't need to wait | ||
154 | * here, since both plates are being driven. | ||
155 | */ | ||
156 | static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb) | ||
157 | { | ||
158 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
159 | UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | | ||
160 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | | ||
161 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
162 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Switch to X position mode and measure Y plate. We switch the plate | ||
167 | * configuration in pressure mode, then switch to position mode. This | ||
168 | * gives a faster response time. Even so, we need to wait about 55us | ||
169 | * for things to stabilise. | ||
170 | */ | ||
171 | static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb) | ||
172 | { | ||
173 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
174 | UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | | ||
175 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
176 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
177 | UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | | ||
178 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
179 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
180 | UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | | ||
181 | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); | ||
182 | |||
183 | udelay(55); | ||
184 | |||
185 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Switch to Y position mode and measure X plate. We switch the plate | ||
190 | * configuration in pressure mode, then switch to position mode. This | ||
191 | * gives a faster response time. Even so, we need to wait about 55us | ||
192 | * for things to stabilise. | ||
193 | */ | ||
194 | static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb) | ||
195 | { | ||
196 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
197 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | | ||
198 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
199 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
200 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | | ||
201 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
202 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
203 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | | ||
204 | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); | ||
205 | |||
206 | udelay(55); | ||
207 | |||
208 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX); | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Switch to X plate resistance mode. Set MX to ground, PX to | ||
213 | * supply. Measure current. | ||
214 | */ | ||
215 | static inline unsigned int ucb1400_ts_read_xres(struct ucb1400 *ucb) | ||
216 | { | ||
217 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
218 | UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | | ||
219 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
220 | return ucb1400_adc_read(ucb, 0); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Switch to Y plate resistance mode. Set MY to ground, PY to | ||
225 | * supply. Measure current. | ||
226 | */ | ||
227 | static inline unsigned int ucb1400_ts_read_yres(struct ucb1400 *ucb) | ||
228 | { | ||
229 | ucb1400_reg_write(ucb, UCB_TS_CR, | ||
230 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | | ||
231 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | ||
232 | return ucb1400_adc_read(ucb, 0); | ||
233 | } | ||
234 | |||
235 | static inline int ucb1400_ts_pen_down(struct ucb1400 *ucb) | ||
236 | { | ||
237 | unsigned short val = ucb1400_reg_read(ucb, UCB_TS_CR); | ||
238 | return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)); | ||
239 | } | ||
240 | |||
241 | static inline void ucb1400_ts_irq_enable(struct ucb1400 *ucb) | ||
242 | { | ||
243 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, UCB_IE_TSPX); | ||
244 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); | ||
245 | ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_TSPX); | ||
246 | } | ||
247 | |||
248 | static inline void ucb1400_ts_irq_disable(struct ucb1400 *ucb) | ||
249 | { | ||
250 | ucb1400_reg_write(ucb, UCB_IE_FAL, 0); | ||
251 | } | ||
252 | |||
253 | static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16 y) | ||
254 | { | ||
255 | input_report_abs(idev, ABS_X, x); | ||
256 | input_report_abs(idev, ABS_Y, y); | ||
257 | input_report_abs(idev, ABS_PRESSURE, pressure); | ||
258 | input_sync(idev); | ||
259 | } | ||
260 | |||
261 | static void ucb1400_ts_event_release(struct input_dev *idev) | ||
262 | { | ||
263 | input_report_abs(idev, ABS_PRESSURE, 0); | ||
264 | input_sync(idev); | ||
265 | } | ||
266 | |||
267 | static void ucb1400_handle_pending_irq(struct ucb1400 *ucb) | ||
268 | { | ||
269 | unsigned int isr; | ||
270 | |||
271 | isr = ucb1400_reg_read(ucb, UCB_IE_STATUS); | ||
272 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, isr); | ||
273 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); | ||
274 | |||
275 | if (isr & UCB_IE_TSPX) | ||
276 | ucb1400_ts_irq_disable(ucb); | ||
277 | else | ||
278 | printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr); | ||
279 | |||
280 | enable_irq(ucb->irq); | ||
281 | } | ||
282 | |||
283 | static int ucb1400_ts_thread(void *_ucb) | ||
284 | { | ||
285 | struct ucb1400 *ucb = _ucb; | ||
286 | struct task_struct *tsk = current; | ||
287 | int valid = 0; | ||
288 | |||
289 | tsk->policy = SCHED_FIFO; | ||
290 | tsk->rt_priority = 1; | ||
291 | |||
292 | while (!kthread_should_stop()) { | ||
293 | unsigned int x, y, p; | ||
294 | long timeout; | ||
295 | |||
296 | ucb->ts_restart = 0; | ||
297 | |||
298 | if (ucb->irq_pending) { | ||
299 | ucb->irq_pending = 0; | ||
300 | ucb1400_handle_pending_irq(ucb); | ||
301 | } | ||
302 | |||
303 | ucb1400_adc_enable(ucb); | ||
304 | x = ucb1400_ts_read_xpos(ucb); | ||
305 | y = ucb1400_ts_read_ypos(ucb); | ||
306 | p = ucb1400_ts_read_pressure(ucb); | ||
307 | ucb1400_adc_disable(ucb); | ||
308 | |||
309 | /* Switch back to interrupt mode. */ | ||
310 | ucb1400_ts_mode_int(ucb); | ||
311 | |||
312 | msleep(10); | ||
313 | |||
314 | if (ucb1400_ts_pen_down(ucb)) { | ||
315 | ucb1400_ts_irq_enable(ucb); | ||
316 | |||
317 | /* | ||
318 | * If we spat out a valid sample set last time, | ||
319 | * spit out a "pen off" sample here. | ||
320 | */ | ||
321 | if (valid) { | ||
322 | ucb1400_ts_event_release(ucb->ts_idev); | ||
323 | valid = 0; | ||
324 | } | ||
325 | |||
326 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
327 | } else { | ||
328 | valid = 1; | ||
329 | ucb1400_ts_evt_add(ucb->ts_idev, p, x, y); | ||
330 | timeout = msecs_to_jiffies(10); | ||
331 | } | ||
332 | |||
333 | wait_event_interruptible_timeout(ucb->ts_wait, | ||
334 | ucb->irq_pending || ucb->ts_restart || kthread_should_stop(), | ||
335 | timeout); | ||
336 | try_to_freeze(); | ||
337 | } | ||
338 | |||
339 | /* Send the "pen off" if we are stopping with the pen still active */ | ||
340 | if (valid) | ||
341 | ucb1400_ts_event_release(ucb->ts_idev); | ||
342 | |||
343 | ucb->ts_task = NULL; | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | /* | ||
348 | * A restriction with interrupts exists when using the ucb1400, as | ||
349 | * the codec read/write routines may sleep while waiting for codec | ||
350 | * access completion and uses semaphores for access control to the | ||
351 | * AC97 bus. A complete codec read cycle could take anywhere from | ||
352 | * 60 to 100uSec so we *definitely* don't want to spin inside the | ||
353 | * interrupt handler waiting for codec access. So, we handle the | ||
354 | * interrupt by scheduling a RT kernel thread to run in process | ||
355 | * context instead of interrupt context. | ||
356 | */ | ||
357 | static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid) | ||
358 | { | ||
359 | struct ucb1400 *ucb = devid; | ||
360 | |||
361 | if (irqnr == ucb->irq) { | ||
362 | disable_irq(ucb->irq); | ||
363 | ucb->irq_pending = 1; | ||
364 | wake_up(&ucb->ts_wait); | ||
365 | return IRQ_HANDLED; | ||
366 | } | ||
367 | return IRQ_NONE; | ||
368 | } | ||
369 | |||
370 | static int ucb1400_ts_open(struct input_dev *idev) | ||
371 | { | ||
372 | struct ucb1400 *ucb = idev->private; | ||
373 | int ret = 0; | ||
374 | |||
375 | BUG_ON(ucb->ts_task); | ||
376 | |||
377 | ucb->ts_task = kthread_run(ucb1400_ts_thread, ucb, "UCB1400_ts"); | ||
378 | if (IS_ERR(ucb->ts_task)) { | ||
379 | ret = PTR_ERR(ucb->ts_task); | ||
380 | ucb->ts_task = NULL; | ||
381 | } | ||
382 | |||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | static void ucb1400_ts_close(struct input_dev *idev) | ||
387 | { | ||
388 | struct ucb1400 *ucb = idev->private; | ||
389 | |||
390 | if (ucb->ts_task) | ||
391 | kthread_stop(ucb->ts_task); | ||
392 | |||
393 | ucb1400_ts_irq_disable(ucb); | ||
394 | ucb1400_reg_write(ucb, UCB_TS_CR, 0); | ||
395 | } | ||
396 | |||
397 | #ifdef CONFIG_PM | ||
398 | static int ucb1400_ts_resume(struct device *dev) | ||
399 | { | ||
400 | struct ucb1400 *ucb = dev_get_drvdata(dev); | ||
401 | |||
402 | if (ucb->ts_task) { | ||
403 | /* | ||
404 | * Restart the TS thread to ensure the | ||
405 | * TS interrupt mode is set up again | ||
406 | * after sleep. | ||
407 | */ | ||
408 | ucb->ts_restart = 1; | ||
409 | wake_up(&ucb->ts_wait); | ||
410 | } | ||
411 | return 0; | ||
412 | } | ||
413 | #else | ||
414 | #define ucb1400_ts_resume NULL | ||
415 | #endif | ||
416 | |||
417 | #ifndef NO_IRQ | ||
418 | #define NO_IRQ 0 | ||
419 | #endif | ||
420 | |||
421 | /* | ||
422 | * Try to probe our interrupt, rather than relying on lots of | ||
423 | * hard-coded machine dependencies. | ||
424 | */ | ||
425 | static int ucb1400_detect_irq(struct ucb1400 *ucb) | ||
426 | { | ||
427 | unsigned long mask, timeout; | ||
428 | |||
429 | mask = probe_irq_on(); | ||
430 | if (!mask) { | ||
431 | probe_irq_off(mask); | ||
432 | return -EBUSY; | ||
433 | } | ||
434 | |||
435 | /* Enable the ADC interrupt. */ | ||
436 | ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); | ||
437 | ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC); | ||
438 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff); | ||
439 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); | ||
440 | |||
441 | /* Cause an ADC interrupt. */ | ||
442 | ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); | ||
443 | ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START); | ||
444 | |||
445 | /* Wait for the conversion to complete. */ | ||
446 | timeout = jiffies + HZ/2; | ||
447 | while (!(ucb1400_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VALID)) { | ||
448 | cpu_relax(); | ||
449 | if (time_after(jiffies, timeout)) { | ||
450 | printk(KERN_ERR "ucb1400: timed out in IRQ probe\n"); | ||
451 | probe_irq_off(mask); | ||
452 | return -ENODEV; | ||
453 | } | ||
454 | } | ||
455 | ucb1400_reg_write(ucb, UCB_ADC_CR, 0); | ||
456 | |||
457 | /* Disable and clear interrupt. */ | ||
458 | ucb1400_reg_write(ucb, UCB_IE_RIS, 0); | ||
459 | ucb1400_reg_write(ucb, UCB_IE_FAL, 0); | ||
460 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff); | ||
461 | ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); | ||
462 | |||
463 | /* Read triggered interrupt. */ | ||
464 | ucb->irq = probe_irq_off(mask); | ||
465 | if (ucb->irq < 0 || ucb->irq == NO_IRQ) | ||
466 | return -ENODEV; | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int ucb1400_ts_probe(struct device *dev) | ||
472 | { | ||
473 | struct ucb1400 *ucb; | ||
474 | struct input_dev *idev; | ||
475 | int error, id, x_res, y_res; | ||
476 | |||
477 | ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL); | ||
478 | idev = input_allocate_device(); | ||
479 | if (!ucb || !idev) { | ||
480 | error = -ENOMEM; | ||
481 | goto err_free_devs; | ||
482 | } | ||
483 | |||
484 | ucb->ts_idev = idev; | ||
485 | ucb->adcsync = adcsync; | ||
486 | ucb->ac97 = to_ac97_t(dev); | ||
487 | init_waitqueue_head(&ucb->ts_wait); | ||
488 | |||
489 | id = ucb1400_reg_read(ucb, UCB_ID); | ||
490 | if (id != UCB_ID_1400) { | ||
491 | error = -ENODEV; | ||
492 | goto err_free_devs; | ||
493 | } | ||
494 | |||
495 | error = ucb1400_detect_irq(ucb); | ||
496 | if (error) { | ||
497 | printk(KERN_ERR "UCB1400: IRQ probe failed\n"); | ||
498 | goto err_free_devs; | ||
499 | } | ||
500 | |||
501 | error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING, | ||
502 | "UCB1400", ucb); | ||
503 | if (error) { | ||
504 | printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n", | ||
505 | ucb->irq, error); | ||
506 | goto err_free_devs; | ||
507 | } | ||
508 | printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq); | ||
509 | |||
510 | idev->private = ucb; | ||
511 | idev->cdev.dev = dev; | ||
512 | idev->name = "UCB1400 touchscreen interface"; | ||
513 | idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); | ||
514 | idev->id.product = id; | ||
515 | idev->open = ucb1400_ts_open; | ||
516 | idev->close = ucb1400_ts_close; | ||
517 | idev->evbit[0] = BIT(EV_ABS); | ||
518 | |||
519 | ucb1400_adc_enable(ucb); | ||
520 | x_res = ucb1400_ts_read_xres(ucb); | ||
521 | y_res = ucb1400_ts_read_yres(ucb); | ||
522 | ucb1400_adc_disable(ucb); | ||
523 | printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res); | ||
524 | |||
525 | input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0); | ||
526 | input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0); | ||
527 | input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); | ||
528 | |||
529 | error = input_register_device(idev); | ||
530 | if (error) | ||
531 | goto err_free_irq; | ||
532 | |||
533 | dev_set_drvdata(dev, ucb); | ||
534 | return 0; | ||
535 | |||
536 | err_free_irq: | ||
537 | free_irq(ucb->irq, ucb); | ||
538 | err_free_devs: | ||
539 | input_free_device(idev); | ||
540 | kfree(ucb); | ||
541 | return error; | ||
542 | } | ||
543 | |||
544 | static int ucb1400_ts_remove(struct device *dev) | ||
545 | { | ||
546 | struct ucb1400 *ucb = dev_get_drvdata(dev); | ||
547 | |||
548 | free_irq(ucb->irq, ucb); | ||
549 | input_unregister_device(ucb->ts_idev); | ||
550 | dev_set_drvdata(dev, NULL); | ||
551 | kfree(ucb); | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static struct device_driver ucb1400_ts_driver = { | ||
556 | .owner = THIS_MODULE, | ||
557 | .bus = &ac97_bus_type, | ||
558 | .probe = ucb1400_ts_probe, | ||
559 | .remove = ucb1400_ts_remove, | ||
560 | .resume = ucb1400_ts_resume, | ||
561 | }; | ||
562 | |||
563 | static int __init ucb1400_ts_init(void) | ||
564 | { | ||
565 | return driver_register(&ucb1400_ts_driver); | ||
566 | } | ||
567 | |||
568 | static void __exit ucb1400_ts_exit(void) | ||
569 | { | ||
570 | driver_unregister(&ucb1400_ts_driver); | ||
571 | } | ||
572 | |||
573 | module_param(adcsync, int, 0444); | ||
574 | |||
575 | module_init(ucb1400_ts_init); | ||
576 | module_exit(ucb1400_ts_exit); | ||
577 | |||
578 | MODULE_DESCRIPTION("Philips UCB1400 touchscreen driver"); | ||
579 | MODULE_LICENSE("GPL"); | ||