summaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 21:07:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 21:07:18 -0500
commit9f7a9b1191b0252184b1971c7248c304d4e38e5e (patch)
treed946c6bddc459a76b79b6effc01160c4536fa460 /drivers/input/misc
parent4e4510fec4af08ead21f6934c1410af1f19a8cad (diff)
parentc25141062a82ae8bddced1b3ce2b57a1c0efabe0 (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.c2
-rw-r--r--drivers/input/misc/uinput.c305
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
49enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED };
50
51struct 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
67struct 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
45static int uinput_dev_event(struct input_dev *dev, 83static 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
405static 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
417static int uinput_dev_setup(struct uinput_device *udev, 451static 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);