diff options
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index ab060710688f..86cb2d2196ff 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/rcupdate.h> | 25 | #include <linux/rcupdate.h> |
26 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
27 | #include "input-compat.h" | ||
27 | 28 | ||
28 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | 29 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
29 | MODULE_DESCRIPTION("Input core"); | 30 | MODULE_DESCRIPTION("Input core"); |
@@ -45,6 +46,7 @@ static unsigned int input_abs_bypass_init_data[] __initdata = { | |||
45 | ABS_MT_TOOL_TYPE, | 46 | ABS_MT_TOOL_TYPE, |
46 | ABS_MT_BLOB_ID, | 47 | ABS_MT_BLOB_ID, |
47 | ABS_MT_TRACKING_ID, | 48 | ABS_MT_TRACKING_ID, |
49 | ABS_MT_PRESSURE, | ||
48 | 0 | 50 | 0 |
49 | }; | 51 | }; |
50 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; | 52 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; |
@@ -764,6 +766,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
764 | return error; | 766 | return error; |
765 | } | 767 | } |
766 | 768 | ||
769 | #ifdef CONFIG_COMPAT | ||
770 | |||
771 | static int input_bits_to_string(char *buf, int buf_size, | ||
772 | unsigned long bits, bool skip_empty) | ||
773 | { | ||
774 | int len = 0; | ||
775 | |||
776 | if (INPUT_COMPAT_TEST) { | ||
777 | u32 dword = bits >> 32; | ||
778 | if (dword || !skip_empty) | ||
779 | len += snprintf(buf, buf_size, "%x ", dword); | ||
780 | |||
781 | dword = bits & 0xffffffffUL; | ||
782 | if (dword || !skip_empty || len) | ||
783 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
784 | "%x", dword); | ||
785 | } else { | ||
786 | if (bits || !skip_empty) | ||
787 | len += snprintf(buf, buf_size, "%lx", bits); | ||
788 | } | ||
789 | |||
790 | return len; | ||
791 | } | ||
792 | |||
793 | #else /* !CONFIG_COMPAT */ | ||
794 | |||
795 | static int input_bits_to_string(char *buf, int buf_size, | ||
796 | unsigned long bits, bool skip_empty) | ||
797 | { | ||
798 | return bits || !skip_empty ? | ||
799 | snprintf(buf, buf_size, "%lx", bits) : 0; | ||
800 | } | ||
801 | |||
802 | #endif | ||
767 | 803 | ||
768 | #ifdef CONFIG_PROC_FS | 804 | #ifdef CONFIG_PROC_FS |
769 | 805 | ||
@@ -832,14 +868,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, | |||
832 | unsigned long *bitmap, int max) | 868 | unsigned long *bitmap, int max) |
833 | { | 869 | { |
834 | int i; | 870 | int i; |
835 | 871 | bool skip_empty = true; | |
836 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 872 | char buf[18]; |
837 | if (bitmap[i]) | ||
838 | break; | ||
839 | 873 | ||
840 | seq_printf(seq, "B: %s=", name); | 874 | seq_printf(seq, "B: %s=", name); |
841 | for (; i >= 0; i--) | 875 | |
842 | seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); | 876 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { |
877 | if (input_bits_to_string(buf, sizeof(buf), | ||
878 | bitmap[i], skip_empty)) { | ||
879 | skip_empty = false; | ||
880 | seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | /* | ||
885 | * If no output was produced print a single 0. | ||
886 | */ | ||
887 | if (skip_empty) | ||
888 | seq_puts(seq, "0"); | ||
889 | |||
843 | seq_putc(seq, '\n'); | 890 | seq_putc(seq, '\n'); |
844 | } | 891 | } |
845 | 892 | ||
@@ -1128,14 +1175,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | |||
1128 | { | 1175 | { |
1129 | int i; | 1176 | int i; |
1130 | int len = 0; | 1177 | int len = 0; |
1178 | bool skip_empty = true; | ||
1179 | |||
1180 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { | ||
1181 | len += input_bits_to_string(buf + len, max(buf_size - len, 0), | ||
1182 | bitmap[i], skip_empty); | ||
1183 | if (len) { | ||
1184 | skip_empty = false; | ||
1185 | if (i > 0) | ||
1186 | len += snprintf(buf + len, max(buf_size - len, 0), " "); | ||
1187 | } | ||
1188 | } | ||
1131 | 1189 | ||
1132 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 1190 | /* |
1133 | if (bitmap[i]) | 1191 | * If no output was produced print a single 0. |
1134 | break; | 1192 | */ |
1135 | 1193 | if (len == 0) | |
1136 | for (; i >= 0; i--) | 1194 | len = snprintf(buf, buf_size, "%d", 0); |
1137 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
1138 | "%lx%s", bitmap[i], i > 0 ? " " : ""); | ||
1139 | 1195 | ||
1140 | if (add_cr) | 1196 | if (add_cr) |
1141 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); | 1197 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); |
@@ -1150,7 +1206,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ | |||
1150 | { \ | 1206 | { \ |
1151 | struct input_dev *input_dev = to_input_dev(dev); \ | 1207 | struct input_dev *input_dev = to_input_dev(dev); \ |
1152 | int len = input_print_bitmap(buf, PAGE_SIZE, \ | 1208 | int len = input_print_bitmap(buf, PAGE_SIZE, \ |
1153 | input_dev->bm##bit, ev##_MAX, 1); \ | 1209 | input_dev->bm##bit, ev##_MAX, \ |
1210 | true); \ | ||
1154 | return min_t(int, len, PAGE_SIZE); \ | 1211 | return min_t(int, len, PAGE_SIZE); \ |
1155 | } \ | 1212 | } \ |
1156 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) | 1213 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) |
@@ -1214,7 +1271,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
1214 | 1271 | ||
1215 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1272 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
1216 | sizeof(env->buf) - env->buflen, | 1273 | sizeof(env->buf) - env->buflen, |
1217 | bitmap, max, 0); | 1274 | bitmap, max, false); |
1218 | if (len >= (sizeof(env->buf) - env->buflen)) | 1275 | if (len >= (sizeof(env->buf) - env->buflen)) |
1219 | return -ENOMEM; | 1276 | return -ENOMEM; |
1220 | 1277 | ||