diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 21:07:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 21:07:18 -0500 |
commit | 9f7a9b1191b0252184b1971c7248c304d4e38e5e (patch) | |
tree | d946c6bddc459a76b79b6effc01160c4536fa460 /drivers/input/misc | |
parent | 4e4510fec4af08ead21f6934c1410af1f19a8cad (diff) | |
parent | c25141062a82ae8bddced1b3ce2b57a1c0efabe0 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
- three new touchscreen drivers: EETI EXC3000, HiDeep, and Samsung
S6SY761
- the timer API conversion (setup_timer() -> timer_setup())
- a few drivers swiytched to using managed API for creating custom
device attributes
- other assorted fixed and cleanups.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (50 commits)
Input: gamecon - mark expected switch fall-throughs
Input: sidewinder - mark expected switch fall-throughs
Input: spaceball - mark expected switch fall-throughs
Input: uinput - unlock on allocation failure in ioctl
Input: add support for the Samsung S6SY761 touchscreen
Input: add support for HiDeep touchscreen
Input: st1232 - remove obsolete platform device support
Input: convert autorepeat timer to use timer_setup()
media: ttpci: remove autorepeat handling and use timer_setup
Input: cyttsp4 - avoid overflows when calculating memory sizes
Input: mxs-lradc - remove redundant assignment to pointer input
Input: add I2C attached EETI EXC3000 multi touch driver
Input: goodix - support gt1151 touchpanel
Input: ps2-gpio - actually abort probe when connected to sleeping GPIOs
Input: hil_mlc - convert to using timer_setup()
Input: hp_sdc - convert to using timer_setup()
Input: touchsceen - convert timers to use timer_setup()
Input: keyboard - convert timers to use timer_setup()
Input: uinput - fold header into the driver proper
Input: uinput - remove uinput_allocate_device()
...
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/adxl34x.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/uinput.c | 305 |
2 files changed, 171 insertions, 136 deletions
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 2b2d02f408bb..a3e79bf5a04b 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c | |||
@@ -796,7 +796,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, | |||
796 | 796 | ||
797 | if (pdata->watermark) { | 797 | if (pdata->watermark) { |
798 | ac->int_mask |= WATERMARK; | 798 | ac->int_mask |= WATERMARK; |
799 | if (!FIFO_MODE(pdata->fifo_mode)) | 799 | if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) |
800 | ac->pdata.fifo_mode |= FIFO_STREAM; | 800 | ac->pdata.fifo_mode |= FIFO_STREAM; |
801 | } else { | 801 | } else { |
802 | ac->int_mask |= DATA_READY; | 802 | ac->int_mask |= DATA_READY; |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 443151de90c6..39ddd9a73feb 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -31,6 +31,7 @@ | |||
31 | * 0.1 20/06/2002 | 31 | * 0.1 20/06/2002 |
32 | * - first public version | 32 | * - first public version |
33 | */ | 33 | */ |
34 | #include <uapi/linux/uinput.h> | ||
34 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
35 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
@@ -38,10 +39,47 @@ | |||
38 | #include <linux/init.h> | 39 | #include <linux/init.h> |
39 | #include <linux/fs.h> | 40 | #include <linux/fs.h> |
40 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
41 | #include <linux/uinput.h> | ||
42 | #include <linux/input/mt.h> | 42 | #include <linux/input/mt.h> |
43 | #include "../input-compat.h" | 43 | #include "../input-compat.h" |
44 | 44 | ||
45 | #define UINPUT_NAME "uinput" | ||
46 | #define UINPUT_BUFFER_SIZE 16 | ||
47 | #define UINPUT_NUM_REQUESTS 16 | ||
48 | |||
49 | enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED }; | ||
50 | |||
51 | struct uinput_request { | ||
52 | unsigned int id; | ||
53 | unsigned int code; /* UI_FF_UPLOAD, UI_FF_ERASE */ | ||
54 | |||
55 | int retval; | ||
56 | struct completion done; | ||
57 | |||
58 | union { | ||
59 | unsigned int effect_id; | ||
60 | struct { | ||
61 | struct ff_effect *effect; | ||
62 | struct ff_effect *old; | ||
63 | } upload; | ||
64 | } u; | ||
65 | }; | ||
66 | |||
67 | struct uinput_device { | ||
68 | struct input_dev *dev; | ||
69 | struct mutex mutex; | ||
70 | enum uinput_state state; | ||
71 | wait_queue_head_t waitq; | ||
72 | unsigned char ready; | ||
73 | unsigned char head; | ||
74 | unsigned char tail; | ||
75 | struct input_event buff[UINPUT_BUFFER_SIZE]; | ||
76 | unsigned int ff_effects_max; | ||
77 | |||
78 | struct uinput_request *requests[UINPUT_NUM_REQUESTS]; | ||
79 | wait_queue_head_t requests_waitq; | ||
80 | spinlock_t requests_lock; | ||
81 | }; | ||
82 | |||
45 | static int uinput_dev_event(struct input_dev *dev, | 83 | static int uinput_dev_event(struct input_dev *dev, |
46 | unsigned int type, unsigned int code, int value) | 84 | unsigned int type, unsigned int code, int value) |
47 | { | 85 | { |
@@ -149,7 +187,11 @@ static int uinput_request_submit(struct uinput_device *udev, | |||
149 | if (retval) | 187 | if (retval) |
150 | goto out; | 188 | goto out; |
151 | 189 | ||
152 | wait_for_completion(&request->done); | 190 | if (!wait_for_completion_timeout(&request->done, 30 * HZ)) { |
191 | retval = -ETIMEDOUT; | ||
192 | goto out; | ||
193 | } | ||
194 | |||
153 | retval = request->retval; | 195 | retval = request->retval; |
154 | 196 | ||
155 | out: | 197 | out: |
@@ -320,6 +362,10 @@ static int uinput_create_device(struct uinput_device *udev) | |||
320 | dev->flush = uinput_dev_flush; | 362 | dev->flush = uinput_dev_flush; |
321 | } | 363 | } |
322 | 364 | ||
365 | dev->event = uinput_dev_event; | ||
366 | |||
367 | input_set_drvdata(udev->dev, udev); | ||
368 | |||
323 | error = input_register_device(udev->dev); | 369 | error = input_register_device(udev->dev); |
324 | if (error) | 370 | if (error) |
325 | goto fail2; | 371 | goto fail2; |
@@ -402,18 +448,6 @@ static int uinput_validate_absbits(struct input_dev *dev) | |||
402 | return 0; | 448 | return 0; |
403 | } | 449 | } |
404 | 450 | ||
405 | static int uinput_allocate_device(struct uinput_device *udev) | ||
406 | { | ||
407 | udev->dev = input_allocate_device(); | ||
408 | if (!udev->dev) | ||
409 | return -ENOMEM; | ||
410 | |||
411 | udev->dev->event = uinput_dev_event; | ||
412 | input_set_drvdata(udev->dev, udev); | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static int uinput_dev_setup(struct uinput_device *udev, | 451 | static int uinput_dev_setup(struct uinput_device *udev, |
418 | struct uinput_setup __user *arg) | 452 | struct uinput_setup __user *arg) |
419 | { | 453 | { |
@@ -489,9 +523,9 @@ static int uinput_setup_device_legacy(struct uinput_device *udev, | |||
489 | return -EINVAL; | 523 | return -EINVAL; |
490 | 524 | ||
491 | if (!udev->dev) { | 525 | if (!udev->dev) { |
492 | retval = uinput_allocate_device(udev); | 526 | udev->dev = input_allocate_device(); |
493 | if (retval) | 527 | if (!udev->dev) |
494 | return retval; | 528 | return -ENOMEM; |
495 | } | 529 | } |
496 | 530 | ||
497 | dev = udev->dev; | 531 | dev = udev->dev; |
@@ -822,162 +856,163 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
822 | return retval; | 856 | return retval; |
823 | 857 | ||
824 | if (!udev->dev) { | 858 | if (!udev->dev) { |
825 | retval = uinput_allocate_device(udev); | 859 | udev->dev = input_allocate_device(); |
826 | if (retval) | 860 | if (!udev->dev) { |
861 | retval = -ENOMEM; | ||
827 | goto out; | 862 | goto out; |
863 | } | ||
828 | } | 864 | } |
829 | 865 | ||
830 | switch (cmd) { | 866 | switch (cmd) { |
831 | case UI_GET_VERSION: | 867 | case UI_GET_VERSION: |
832 | if (put_user(UINPUT_VERSION, | 868 | if (put_user(UINPUT_VERSION, (unsigned int __user *)p)) |
833 | (unsigned int __user *)p)) | 869 | retval = -EFAULT; |
834 | retval = -EFAULT; | 870 | goto out; |
835 | goto out; | ||
836 | 871 | ||
837 | case UI_DEV_CREATE: | 872 | case UI_DEV_CREATE: |
838 | retval = uinput_create_device(udev); | 873 | retval = uinput_create_device(udev); |
839 | goto out; | 874 | goto out; |
840 | 875 | ||
841 | case UI_DEV_DESTROY: | 876 | case UI_DEV_DESTROY: |
842 | uinput_destroy_device(udev); | 877 | uinput_destroy_device(udev); |
843 | goto out; | 878 | goto out; |
844 | 879 | ||
845 | case UI_DEV_SETUP: | 880 | case UI_DEV_SETUP: |
846 | retval = uinput_dev_setup(udev, p); | 881 | retval = uinput_dev_setup(udev, p); |
847 | goto out; | 882 | goto out; |
848 | 883 | ||
849 | /* UI_ABS_SETUP is handled in the variable size ioctls */ | 884 | /* UI_ABS_SETUP is handled in the variable size ioctls */ |
850 | 885 | ||
851 | case UI_SET_EVBIT: | 886 | case UI_SET_EVBIT: |
852 | retval = uinput_set_bit(arg, evbit, EV_MAX); | 887 | retval = uinput_set_bit(arg, evbit, EV_MAX); |
853 | goto out; | 888 | goto out; |
854 | 889 | ||
855 | case UI_SET_KEYBIT: | 890 | case UI_SET_KEYBIT: |
856 | retval = uinput_set_bit(arg, keybit, KEY_MAX); | 891 | retval = uinput_set_bit(arg, keybit, KEY_MAX); |
857 | goto out; | 892 | goto out; |
858 | 893 | ||
859 | case UI_SET_RELBIT: | 894 | case UI_SET_RELBIT: |
860 | retval = uinput_set_bit(arg, relbit, REL_MAX); | 895 | retval = uinput_set_bit(arg, relbit, REL_MAX); |
861 | goto out; | 896 | goto out; |
862 | 897 | ||
863 | case UI_SET_ABSBIT: | 898 | case UI_SET_ABSBIT: |
864 | retval = uinput_set_bit(arg, absbit, ABS_MAX); | 899 | retval = uinput_set_bit(arg, absbit, ABS_MAX); |
865 | goto out; | 900 | goto out; |
866 | 901 | ||
867 | case UI_SET_MSCBIT: | 902 | case UI_SET_MSCBIT: |
868 | retval = uinput_set_bit(arg, mscbit, MSC_MAX); | 903 | retval = uinput_set_bit(arg, mscbit, MSC_MAX); |
869 | goto out; | 904 | goto out; |
870 | 905 | ||
871 | case UI_SET_LEDBIT: | 906 | case UI_SET_LEDBIT: |
872 | retval = uinput_set_bit(arg, ledbit, LED_MAX); | 907 | retval = uinput_set_bit(arg, ledbit, LED_MAX); |
873 | goto out; | 908 | goto out; |
909 | |||
910 | case UI_SET_SNDBIT: | ||
911 | retval = uinput_set_bit(arg, sndbit, SND_MAX); | ||
912 | goto out; | ||
874 | 913 | ||
875 | case UI_SET_SNDBIT: | 914 | case UI_SET_FFBIT: |
876 | retval = uinput_set_bit(arg, sndbit, SND_MAX); | 915 | retval = uinput_set_bit(arg, ffbit, FF_MAX); |
916 | goto out; | ||
917 | |||
918 | case UI_SET_SWBIT: | ||
919 | retval = uinput_set_bit(arg, swbit, SW_MAX); | ||
920 | goto out; | ||
921 | |||
922 | case UI_SET_PROPBIT: | ||
923 | retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); | ||
924 | goto out; | ||
925 | |||
926 | case UI_SET_PHYS: | ||
927 | if (udev->state == UIST_CREATED) { | ||
928 | retval = -EINVAL; | ||
877 | goto out; | 929 | goto out; |
930 | } | ||
878 | 931 | ||
879 | case UI_SET_FFBIT: | 932 | phys = strndup_user(p, 1024); |
880 | retval = uinput_set_bit(arg, ffbit, FF_MAX); | 933 | if (IS_ERR(phys)) { |
934 | retval = PTR_ERR(phys); | ||
881 | goto out; | 935 | goto out; |
936 | } | ||
937 | |||
938 | kfree(udev->dev->phys); | ||
939 | udev->dev->phys = phys; | ||
940 | goto out; | ||
882 | 941 | ||
883 | case UI_SET_SWBIT: | 942 | case UI_BEGIN_FF_UPLOAD: |
884 | retval = uinput_set_bit(arg, swbit, SW_MAX); | 943 | retval = uinput_ff_upload_from_user(p, &ff_up); |
944 | if (retval) | ||
885 | goto out; | 945 | goto out; |
886 | 946 | ||
887 | case UI_SET_PROPBIT: | 947 | req = uinput_request_find(udev, ff_up.request_id); |
888 | retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); | 948 | if (!req || req->code != UI_FF_UPLOAD || |
949 | !req->u.upload.effect) { | ||
950 | retval = -EINVAL; | ||
889 | goto out; | 951 | goto out; |
952 | } | ||
890 | 953 | ||
891 | case UI_SET_PHYS: | 954 | ff_up.retval = 0; |
892 | if (udev->state == UIST_CREATED) { | 955 | ff_up.effect = *req->u.upload.effect; |
893 | retval = -EINVAL; | 956 | if (req->u.upload.old) |
894 | goto out; | 957 | ff_up.old = *req->u.upload.old; |
895 | } | 958 | else |
959 | memset(&ff_up.old, 0, sizeof(struct ff_effect)); | ||
896 | 960 | ||
897 | phys = strndup_user(p, 1024); | 961 | retval = uinput_ff_upload_to_user(p, &ff_up); |
898 | if (IS_ERR(phys)) { | 962 | goto out; |
899 | retval = PTR_ERR(phys); | ||
900 | goto out; | ||
901 | } | ||
902 | 963 | ||
903 | kfree(udev->dev->phys); | 964 | case UI_BEGIN_FF_ERASE: |
904 | udev->dev->phys = phys; | 965 | if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) { |
966 | retval = -EFAULT; | ||
905 | goto out; | 967 | goto out; |
968 | } | ||
906 | 969 | ||
907 | case UI_BEGIN_FF_UPLOAD: | 970 | req = uinput_request_find(udev, ff_erase.request_id); |
908 | retval = uinput_ff_upload_from_user(p, &ff_up); | 971 | if (!req || req->code != UI_FF_ERASE) { |
909 | if (retval) | 972 | retval = -EINVAL; |
910 | goto out; | ||
911 | |||
912 | req = uinput_request_find(udev, ff_up.request_id); | ||
913 | if (!req || req->code != UI_FF_UPLOAD || | ||
914 | !req->u.upload.effect) { | ||
915 | retval = -EINVAL; | ||
916 | goto out; | ||
917 | } | ||
918 | |||
919 | ff_up.retval = 0; | ||
920 | ff_up.effect = *req->u.upload.effect; | ||
921 | if (req->u.upload.old) | ||
922 | ff_up.old = *req->u.upload.old; | ||
923 | else | ||
924 | memset(&ff_up.old, 0, sizeof(struct ff_effect)); | ||
925 | |||
926 | retval = uinput_ff_upload_to_user(p, &ff_up); | ||
927 | goto out; | 973 | goto out; |
974 | } | ||
928 | 975 | ||
929 | case UI_BEGIN_FF_ERASE: | 976 | ff_erase.retval = 0; |
930 | if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) { | 977 | ff_erase.effect_id = req->u.effect_id; |
931 | retval = -EFAULT; | 978 | if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) { |
932 | goto out; | 979 | retval = -EFAULT; |
933 | } | ||
934 | |||
935 | req = uinput_request_find(udev, ff_erase.request_id); | ||
936 | if (!req || req->code != UI_FF_ERASE) { | ||
937 | retval = -EINVAL; | ||
938 | goto out; | ||
939 | } | ||
940 | |||
941 | ff_erase.retval = 0; | ||
942 | ff_erase.effect_id = req->u.effect_id; | ||
943 | if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) { | ||
944 | retval = -EFAULT; | ||
945 | goto out; | ||
946 | } | ||
947 | |||
948 | goto out; | 980 | goto out; |
981 | } | ||
949 | 982 | ||
950 | case UI_END_FF_UPLOAD: | 983 | goto out; |
951 | retval = uinput_ff_upload_from_user(p, &ff_up); | ||
952 | if (retval) | ||
953 | goto out; | ||
954 | 984 | ||
955 | req = uinput_request_find(udev, ff_up.request_id); | 985 | case UI_END_FF_UPLOAD: |
956 | if (!req || req->code != UI_FF_UPLOAD || | 986 | retval = uinput_ff_upload_from_user(p, &ff_up); |
957 | !req->u.upload.effect) { | 987 | if (retval) |
958 | retval = -EINVAL; | 988 | goto out; |
959 | goto out; | ||
960 | } | ||
961 | 989 | ||
962 | req->retval = ff_up.retval; | 990 | req = uinput_request_find(udev, ff_up.request_id); |
963 | complete(&req->done); | 991 | if (!req || req->code != UI_FF_UPLOAD || |
992 | !req->u.upload.effect) { | ||
993 | retval = -EINVAL; | ||
964 | goto out; | 994 | goto out; |
995 | } | ||
965 | 996 | ||
966 | case UI_END_FF_ERASE: | 997 | req->retval = ff_up.retval; |
967 | if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) { | 998 | complete(&req->done); |
968 | retval = -EFAULT; | 999 | goto out; |
969 | goto out; | ||
970 | } | ||
971 | 1000 | ||
972 | req = uinput_request_find(udev, ff_erase.request_id); | 1001 | case UI_END_FF_ERASE: |
973 | if (!req || req->code != UI_FF_ERASE) { | 1002 | if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) { |
974 | retval = -EINVAL; | 1003 | retval = -EFAULT; |
975 | goto out; | 1004 | goto out; |
976 | } | 1005 | } |
977 | 1006 | ||
978 | req->retval = ff_erase.retval; | 1007 | req = uinput_request_find(udev, ff_erase.request_id); |
979 | complete(&req->done); | 1008 | if (!req || req->code != UI_FF_ERASE) { |
1009 | retval = -EINVAL; | ||
980 | goto out; | 1010 | goto out; |
1011 | } | ||
1012 | |||
1013 | req->retval = ff_erase.retval; | ||
1014 | complete(&req->done); | ||
1015 | goto out; | ||
981 | } | 1016 | } |
982 | 1017 | ||
983 | size = _IOC_SIZE(cmd); | 1018 | size = _IOC_SIZE(cmd); |