diff options
| -rw-r--r-- | drivers/input/mousedev.c | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 4c842c320c2e..b604564dec5c 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -67,7 +67,6 @@ struct mousedev { | |||
| 67 | struct device dev; | 67 | struct device dev; |
| 68 | struct cdev cdev; | 68 | struct cdev cdev; |
| 69 | bool exist; | 69 | bool exist; |
| 70 | bool is_mixdev; | ||
| 71 | 70 | ||
| 72 | struct list_head mixdev_node; | 71 | struct list_head mixdev_node; |
| 73 | bool opened_by_mixdev; | 72 | bool opened_by_mixdev; |
| @@ -77,6 +76,9 @@ struct mousedev { | |||
| 77 | int old_x[4], old_y[4]; | 76 | int old_x[4], old_y[4]; |
| 78 | int frac_dx, frac_dy; | 77 | int frac_dx, frac_dy; |
| 79 | unsigned long touch; | 78 | unsigned long touch; |
| 79 | |||
| 80 | int (*open_device)(struct mousedev *mousedev); | ||
| 81 | void (*close_device)(struct mousedev *mousedev); | ||
| 80 | }; | 82 | }; |
| 81 | 83 | ||
| 82 | enum mousedev_emul { | 84 | enum mousedev_emul { |
| @@ -116,9 +118,6 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; | |||
| 116 | static struct mousedev *mousedev_mix; | 118 | static struct mousedev *mousedev_mix; |
| 117 | static LIST_HEAD(mousedev_mix_list); | 119 | static LIST_HEAD(mousedev_mix_list); |
| 118 | 120 | ||
| 119 | static void mixdev_open_devices(void); | ||
| 120 | static void mixdev_close_devices(void); | ||
| 121 | |||
| 122 | #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) | 121 | #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) |
| 123 | #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) | 122 | #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) |
| 124 | 123 | ||
| @@ -428,9 +427,7 @@ static int mousedev_open_device(struct mousedev *mousedev) | |||
| 428 | if (retval) | 427 | if (retval) |
| 429 | return retval; | 428 | return retval; |
| 430 | 429 | ||
| 431 | if (mousedev->is_mixdev) | 430 | if (!mousedev->exist) |
| 432 | mixdev_open_devices(); | ||
| 433 | else if (!mousedev->exist) | ||
| 434 | retval = -ENODEV; | 431 | retval = -ENODEV; |
| 435 | else if (!mousedev->open++) { | 432 | else if (!mousedev->open++) { |
| 436 | retval = input_open_device(&mousedev->handle); | 433 | retval = input_open_device(&mousedev->handle); |
| @@ -446,9 +443,7 @@ static void mousedev_close_device(struct mousedev *mousedev) | |||
| 446 | { | 443 | { |
| 447 | mutex_lock(&mousedev->mutex); | 444 | mutex_lock(&mousedev->mutex); |
| 448 | 445 | ||
| 449 | if (mousedev->is_mixdev) | 446 | if (mousedev->exist && !--mousedev->open) |
| 450 | mixdev_close_devices(); | ||
| 451 | else if (mousedev->exist && !--mousedev->open) | ||
| 452 | input_close_device(&mousedev->handle); | 447 | input_close_device(&mousedev->handle); |
| 453 | 448 | ||
| 454 | mutex_unlock(&mousedev->mutex); | 449 | mutex_unlock(&mousedev->mutex); |
| @@ -459,21 +454,29 @@ static void mousedev_close_device(struct mousedev *mousedev) | |||
| 459 | * stream. Note that this function is called with mousedev_mix->mutex | 454 | * stream. Note that this function is called with mousedev_mix->mutex |
| 460 | * held. | 455 | * held. |
| 461 | */ | 456 | */ |
| 462 | static void mixdev_open_devices(void) | 457 | static int mixdev_open_devices(struct mousedev *mixdev) |
| 463 | { | 458 | { |
| 464 | struct mousedev *mousedev; | 459 | int error; |
| 460 | |||
| 461 | error = mutex_lock_interruptible(&mixdev->mutex); | ||
| 462 | if (error) | ||
| 463 | return error; | ||
| 465 | 464 | ||
| 466 | if (mousedev_mix->open++) | 465 | if (!mixdev->open++) { |
| 467 | return; | 466 | struct mousedev *mousedev; |
| 468 | 467 | ||
| 469 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { | 468 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { |
| 470 | if (!mousedev->opened_by_mixdev) { | 469 | if (!mousedev->opened_by_mixdev) { |
| 471 | if (mousedev_open_device(mousedev)) | 470 | if (mousedev_open_device(mousedev)) |
| 472 | continue; | 471 | continue; |
| 473 | 472 | ||
| 474 | mousedev->opened_by_mixdev = true; | 473 | mousedev->opened_by_mixdev = true; |
| 474 | } | ||
| 475 | } | 475 | } |
| 476 | } | 476 | } |
| 477 | |||
| 478 | mutex_unlock(&mixdev->mutex); | ||
| 479 | return 0; | ||
| 477 | } | 480 | } |
| 478 | 481 | ||
| 479 | /* | 482 | /* |
| @@ -481,19 +484,22 @@ static void mixdev_open_devices(void) | |||
| 481 | * device. Note that this function is called with mousedev_mix->mutex | 484 | * device. Note that this function is called with mousedev_mix->mutex |
| 482 | * held. | 485 | * held. |
| 483 | */ | 486 | */ |
| 484 | static void mixdev_close_devices(void) | 487 | static void mixdev_close_devices(struct mousedev *mixdev) |
| 485 | { | 488 | { |
| 486 | struct mousedev *mousedev; | 489 | mutex_lock(&mixdev->mutex); |
| 487 | 490 | ||
| 488 | if (--mousedev_mix->open) | 491 | if (!--mixdev->open) { |
| 489 | return; | 492 | struct mousedev *mousedev; |
| 490 | 493 | ||
| 491 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { | 494 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { |
| 492 | if (mousedev->opened_by_mixdev) { | 495 | if (mousedev->opened_by_mixdev) { |
| 493 | mousedev->opened_by_mixdev = false; | 496 | mousedev->opened_by_mixdev = false; |
| 494 | mousedev_close_device(mousedev); | 497 | mousedev_close_device(mousedev); |
| 498 | } | ||
| 495 | } | 499 | } |
| 496 | } | 500 | } |
| 501 | |||
| 502 | mutex_unlock(&mixdev->mutex); | ||
| 497 | } | 503 | } |
| 498 | 504 | ||
| 499 | 505 | ||
| @@ -522,7 +528,7 @@ static int mousedev_release(struct inode *inode, struct file *file) | |||
| 522 | mousedev_detach_client(mousedev, client); | 528 | mousedev_detach_client(mousedev, client); |
| 523 | kfree(client); | 529 | kfree(client); |
| 524 | 530 | ||
| 525 | mousedev_close_device(mousedev); | 531 | mousedev->close_device(mousedev); |
| 526 | 532 | ||
| 527 | return 0; | 533 | return 0; |
| 528 | } | 534 | } |
| @@ -550,7 +556,7 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
| 550 | client->mousedev = mousedev; | 556 | client->mousedev = mousedev; |
| 551 | mousedev_attach_client(mousedev, client); | 557 | mousedev_attach_client(mousedev, client); |
| 552 | 558 | ||
| 553 | error = mousedev_open_device(mousedev); | 559 | error = mousedev->open_device(mousedev); |
| 554 | if (error) | 560 | if (error) |
| 555 | goto err_free_client; | 561 | goto err_free_client; |
| 556 | 562 | ||
| @@ -861,16 +867,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
| 861 | 867 | ||
| 862 | if (mixdev) { | 868 | if (mixdev) { |
| 863 | dev_set_name(&mousedev->dev, "mice"); | 869 | dev_set_name(&mousedev->dev, "mice"); |
| 870 | |||
| 871 | mousedev->open_device = mixdev_open_devices; | ||
| 872 | mousedev->close_device = mixdev_close_devices; | ||
| 864 | } else { | 873 | } else { |
| 865 | int dev_no = minor; | 874 | int dev_no = minor; |
| 866 | /* Normalize device number if it falls into legacy range */ | 875 | /* Normalize device number if it falls into legacy range */ |
| 867 | if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS) | 876 | if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS) |
| 868 | dev_no -= MOUSEDEV_MINOR_BASE; | 877 | dev_no -= MOUSEDEV_MINOR_BASE; |
| 869 | dev_set_name(&mousedev->dev, "mouse%d", dev_no); | 878 | dev_set_name(&mousedev->dev, "mouse%d", dev_no); |
| 879 | |||
| 880 | mousedev->open_device = mousedev_open_device; | ||
| 881 | mousedev->close_device = mousedev_close_device; | ||
| 870 | } | 882 | } |
| 871 | 883 | ||
| 872 | mousedev->exist = true; | 884 | mousedev->exist = true; |
| 873 | mousedev->is_mixdev = mixdev; | ||
| 874 | mousedev->handle.dev = input_get_device(dev); | 885 | mousedev->handle.dev = input_get_device(dev); |
| 875 | mousedev->handle.name = dev_name(&mousedev->dev); | 886 | mousedev->handle.name = dev_name(&mousedev->dev); |
| 876 | mousedev->handle.handler = handler; | 887 | mousedev->handle.handler = handler; |
| @@ -919,7 +930,7 @@ static void mousedev_destroy(struct mousedev *mousedev) | |||
| 919 | device_del(&mousedev->dev); | 930 | device_del(&mousedev->dev); |
| 920 | mousedev_cleanup(mousedev); | 931 | mousedev_cleanup(mousedev); |
| 921 | input_free_minor(MINOR(mousedev->dev.devt)); | 932 | input_free_minor(MINOR(mousedev->dev.devt)); |
| 922 | if (!mousedev->is_mixdev) | 933 | if (mousedev != mousedev_mix) |
| 923 | input_unregister_handle(&mousedev->handle); | 934 | input_unregister_handle(&mousedev->handle); |
| 924 | put_device(&mousedev->dev); | 935 | put_device(&mousedev->dev); |
| 925 | } | 936 | } |
