diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-01-15 17:51:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-01-15 17:51:57 -0500 |
commit | 3b3ef30833cc85982b0b7e950998d86f5e2d28cf (patch) | |
tree | 0abbb1ec81a14f0f718abc01ac908bbe783f7bf9 /drivers | |
parent | 9fc819172aa565c7be51f758b7e85301c9df7c70 (diff) | |
parent | c332e9fcc5289698350d39d4d22c3ed5257d7a80 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: sentelic - fix left/right horizontal scroll mapping
Input: pmouse - move Sentelic probe down the list
Input: add compat support for sysfs and /proc capabilities output
Input: i8042 - add Dritek quirk for Acer Aspire 5610.
Input: xbox - do not use GFP_KERNEL under spinlock
Input: psmouse - fix Synaptics detection when protocol is disabled
Input: bcm5974 - report ABS_MT events
Input: davinci_keyscan - add device_enable method to platform data
Input: evdev - be less aggressive about sending SIGIO notifies
Input: atkbd - fix canceling event_work in disconnect
Input: serio - fix potential deadlock when unbinding drivers
Input: gf2k - fix &&/|| confusion in gf2k_connect()
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/evdev.c | 3 | ||||
-rw-r--r-- | drivers/input/input.c | 86 | ||||
-rw-r--r-- | drivers/input/joystick/gf2k.c | 2 | ||||
-rw-r--r-- | drivers/input/joystick/xpad.c | 4 | ||||
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 69 | ||||
-rw-r--r-- | drivers/input/keyboard/davinci_keyscan.c | 8 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 44 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 69 | ||||
-rw-r--r-- | drivers/input/mouse/sentelic.c | 6 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 10 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 1 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 7 |
12 files changed, 207 insertions, 102 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index dee6706038aa..258c639571b5 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -59,7 +59,8 @@ static void evdev_pass_event(struct evdev_client *client, | |||
59 | client->head &= EVDEV_BUFFER_SIZE - 1; | 59 | client->head &= EVDEV_BUFFER_SIZE - 1; |
60 | spin_unlock(&client->buffer_lock); | 60 | spin_unlock(&client->buffer_lock); |
61 | 61 | ||
62 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 62 | if (event->type == EV_SYN) |
63 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | ||
63 | } | 64 | } |
64 | 65 | ||
65 | /* | 66 | /* |
diff --git a/drivers/input/input.c b/drivers/input/input.c index ab060710688f..30b503b8d67b 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"); |
@@ -764,6 +765,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
764 | return error; | 765 | return error; |
765 | } | 766 | } |
766 | 767 | ||
768 | #ifdef CONFIG_COMPAT | ||
769 | |||
770 | static int input_bits_to_string(char *buf, int buf_size, | ||
771 | unsigned long bits, bool skip_empty) | ||
772 | { | ||
773 | int len = 0; | ||
774 | |||
775 | if (INPUT_COMPAT_TEST) { | ||
776 | u32 dword = bits >> 32; | ||
777 | if (dword || !skip_empty) | ||
778 | len += snprintf(buf, buf_size, "%x ", dword); | ||
779 | |||
780 | dword = bits & 0xffffffffUL; | ||
781 | if (dword || !skip_empty || len) | ||
782 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
783 | "%x", dword); | ||
784 | } else { | ||
785 | if (bits || !skip_empty) | ||
786 | len += snprintf(buf, buf_size, "%lx", bits); | ||
787 | } | ||
788 | |||
789 | return len; | ||
790 | } | ||
791 | |||
792 | #else /* !CONFIG_COMPAT */ | ||
793 | |||
794 | static int input_bits_to_string(char *buf, int buf_size, | ||
795 | unsigned long bits, bool skip_empty) | ||
796 | { | ||
797 | return bits || !skip_empty ? | ||
798 | snprintf(buf, buf_size, "%lx", bits) : 0; | ||
799 | } | ||
800 | |||
801 | #endif | ||
767 | 802 | ||
768 | #ifdef CONFIG_PROC_FS | 803 | #ifdef CONFIG_PROC_FS |
769 | 804 | ||
@@ -832,14 +867,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, | |||
832 | unsigned long *bitmap, int max) | 867 | unsigned long *bitmap, int max) |
833 | { | 868 | { |
834 | int i; | 869 | int i; |
835 | 870 | bool skip_empty = true; | |
836 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 871 | char buf[18]; |
837 | if (bitmap[i]) | ||
838 | break; | ||
839 | 872 | ||
840 | seq_printf(seq, "B: %s=", name); | 873 | seq_printf(seq, "B: %s=", name); |
841 | for (; i >= 0; i--) | 874 | |
842 | seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); | 875 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { |
876 | if (input_bits_to_string(buf, sizeof(buf), | ||
877 | bitmap[i], skip_empty)) { | ||
878 | skip_empty = false; | ||
879 | seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); | ||
880 | } | ||
881 | } | ||
882 | |||
883 | /* | ||
884 | * If no output was produced print a single 0. | ||
885 | */ | ||
886 | if (skip_empty) | ||
887 | seq_puts(seq, "0"); | ||
888 | |||
843 | seq_putc(seq, '\n'); | 889 | seq_putc(seq, '\n'); |
844 | } | 890 | } |
845 | 891 | ||
@@ -1128,14 +1174,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | |||
1128 | { | 1174 | { |
1129 | int i; | 1175 | int i; |
1130 | int len = 0; | 1176 | int len = 0; |
1177 | bool skip_empty = true; | ||
1178 | |||
1179 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { | ||
1180 | len += input_bits_to_string(buf + len, max(buf_size - len, 0), | ||
1181 | bitmap[i], skip_empty); | ||
1182 | if (len) { | ||
1183 | skip_empty = false; | ||
1184 | if (i > 0) | ||
1185 | len += snprintf(buf + len, max(buf_size - len, 0), " "); | ||
1186 | } | ||
1187 | } | ||
1131 | 1188 | ||
1132 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 1189 | /* |
1133 | if (bitmap[i]) | 1190 | * If no output was produced print a single 0. |
1134 | break; | 1191 | */ |
1135 | 1192 | if (len == 0) | |
1136 | for (; i >= 0; i--) | 1193 | 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 | 1194 | ||
1140 | if (add_cr) | 1195 | if (add_cr) |
1141 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); | 1196 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); |
@@ -1150,7 +1205,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ | |||
1150 | { \ | 1205 | { \ |
1151 | struct input_dev *input_dev = to_input_dev(dev); \ | 1206 | struct input_dev *input_dev = to_input_dev(dev); \ |
1152 | int len = input_print_bitmap(buf, PAGE_SIZE, \ | 1207 | int len = input_print_bitmap(buf, PAGE_SIZE, \ |
1153 | input_dev->bm##bit, ev##_MAX, 1); \ | 1208 | input_dev->bm##bit, ev##_MAX, \ |
1209 | true); \ | ||
1154 | return min_t(int, len, PAGE_SIZE); \ | 1210 | return min_t(int, len, PAGE_SIZE); \ |
1155 | } \ | 1211 | } \ |
1156 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) | 1212 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) |
@@ -1214,7 +1270,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
1214 | 1270 | ||
1215 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1271 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
1216 | sizeof(env->buf) - env->buflen, | 1272 | sizeof(env->buf) - env->buflen, |
1217 | bitmap, max, 0); | 1273 | bitmap, max, false); |
1218 | if (len >= (sizeof(env->buf) - env->buflen)) | 1274 | if (len >= (sizeof(env->buf) - env->buflen)) |
1219 | return -ENOMEM; | 1275 | return -ENOMEM; |
1220 | 1276 | ||
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 67c207f5b1a1..45ac70eae0aa 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -277,7 +277,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | #ifdef RESET_WORKS | 279 | #ifdef RESET_WORKS |
280 | if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) || | 280 | if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) && |
281 | (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { | 281 | (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { |
282 | err = -ENODEV; | 282 | err = -ENODEV; |
283 | goto fail2; | 283 | goto fail2; |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 482cb1204e43..8a28fb7846dc 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -446,7 +446,7 @@ static void xpad_irq_in(struct urb *urb) | |||
446 | } | 446 | } |
447 | 447 | ||
448 | exit: | 448 | exit: |
449 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 449 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
450 | if (retval) | 450 | if (retval) |
451 | err ("%s - usb_submit_urb failed with result %d", | 451 | err ("%s - usb_submit_urb failed with result %d", |
452 | __func__, retval); | 452 | __func__, retval); |
@@ -571,7 +571,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
571 | xpad->odata[6] = 0x00; | 571 | xpad->odata[6] = 0x00; |
572 | xpad->odata[7] = 0x00; | 572 | xpad->odata[7] = 0x00; |
573 | xpad->irq_out->transfer_buffer_length = 8; | 573 | xpad->irq_out->transfer_buffer_length = 8; |
574 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | 574 | usb_submit_urb(xpad->irq_out, GFP_ATOMIC); |
575 | } | 575 | } |
576 | 576 | ||
577 | return 0; | 577 | return 0; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 1f5e2ce327d6..7b4056292eaf 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -225,8 +225,10 @@ struct atkbd { | |||
225 | 225 | ||
226 | struct delayed_work event_work; | 226 | struct delayed_work event_work; |
227 | unsigned long event_jiffies; | 227 | unsigned long event_jiffies; |
228 | struct mutex event_mutex; | ||
229 | unsigned long event_mask; | 228 | unsigned long event_mask; |
229 | |||
230 | /* Serializes reconnect(), attr->set() and event work */ | ||
231 | struct mutex mutex; | ||
230 | }; | 232 | }; |
231 | 233 | ||
232 | /* | 234 | /* |
@@ -577,7 +579,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
577 | { | 579 | { |
578 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); | 580 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); |
579 | 581 | ||
580 | mutex_lock(&atkbd->event_mutex); | 582 | mutex_lock(&atkbd->mutex); |
581 | 583 | ||
582 | if (!atkbd->enabled) { | 584 | if (!atkbd->enabled) { |
583 | /* | 585 | /* |
@@ -596,7 +598,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
596 | atkbd_set_repeat_rate(atkbd); | 598 | atkbd_set_repeat_rate(atkbd); |
597 | } | 599 | } |
598 | 600 | ||
599 | mutex_unlock(&atkbd->event_mutex); | 601 | mutex_unlock(&atkbd->mutex); |
600 | } | 602 | } |
601 | 603 | ||
602 | /* | 604 | /* |
@@ -612,7 +614,7 @@ static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) | |||
612 | 614 | ||
613 | atkbd->event_jiffies = jiffies; | 615 | atkbd->event_jiffies = jiffies; |
614 | set_bit(event_bit, &atkbd->event_mask); | 616 | set_bit(event_bit, &atkbd->event_mask); |
615 | wmb(); | 617 | mb(); |
616 | schedule_delayed_work(&atkbd->event_work, delay); | 618 | schedule_delayed_work(&atkbd->event_work, delay); |
617 | } | 619 | } |
618 | 620 | ||
@@ -849,13 +851,20 @@ static void atkbd_disconnect(struct serio *serio) | |||
849 | { | 851 | { |
850 | struct atkbd *atkbd = serio_get_drvdata(serio); | 852 | struct atkbd *atkbd = serio_get_drvdata(serio); |
851 | 853 | ||
854 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
855 | |||
852 | atkbd_disable(atkbd); | 856 | atkbd_disable(atkbd); |
853 | 857 | ||
854 | /* make sure we don't have a command in flight */ | 858 | input_unregister_device(atkbd->dev); |
859 | |||
860 | /* | ||
861 | * Make sure we don't have a command in flight. | ||
862 | * Note that since atkbd->enabled is false event work will keep | ||
863 | * rescheduling itself until it gets canceled and will not try | ||
864 | * accessing freed input device or serio port. | ||
865 | */ | ||
855 | cancel_delayed_work_sync(&atkbd->event_work); | 866 | cancel_delayed_work_sync(&atkbd->event_work); |
856 | 867 | ||
857 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
858 | input_unregister_device(atkbd->dev); | ||
859 | serio_close(serio); | 868 | serio_close(serio); |
860 | serio_set_drvdata(serio, NULL); | 869 | serio_set_drvdata(serio, NULL); |
861 | kfree(atkbd); | 870 | kfree(atkbd); |
@@ -1087,7 +1096,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1087 | atkbd->dev = dev; | 1096 | atkbd->dev = dev; |
1088 | ps2_init(&atkbd->ps2dev, serio); | 1097 | ps2_init(&atkbd->ps2dev, serio); |
1089 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); | 1098 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); |
1090 | mutex_init(&atkbd->event_mutex); | 1099 | mutex_init(&atkbd->mutex); |
1091 | 1100 | ||
1092 | switch (serio->id.type) { | 1101 | switch (serio->id.type) { |
1093 | 1102 | ||
@@ -1160,19 +1169,23 @@ static int atkbd_reconnect(struct serio *serio) | |||
1160 | { | 1169 | { |
1161 | struct atkbd *atkbd = serio_get_drvdata(serio); | 1170 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1162 | struct serio_driver *drv = serio->drv; | 1171 | struct serio_driver *drv = serio->drv; |
1172 | int retval = -1; | ||
1163 | 1173 | ||
1164 | if (!atkbd || !drv) { | 1174 | if (!atkbd || !drv) { |
1165 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 1175 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); |
1166 | return -1; | 1176 | return -1; |
1167 | } | 1177 | } |
1168 | 1178 | ||
1179 | mutex_lock(&atkbd->mutex); | ||
1180 | |||
1169 | atkbd_disable(atkbd); | 1181 | atkbd_disable(atkbd); |
1170 | 1182 | ||
1171 | if (atkbd->write) { | 1183 | if (atkbd->write) { |
1172 | if (atkbd_probe(atkbd)) | 1184 | if (atkbd_probe(atkbd)) |
1173 | return -1; | 1185 | goto out; |
1186 | |||
1174 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1187 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) |
1175 | return -1; | 1188 | goto out; |
1176 | 1189 | ||
1177 | atkbd_activate(atkbd); | 1190 | atkbd_activate(atkbd); |
1178 | 1191 | ||
@@ -1190,8 +1203,11 @@ static int atkbd_reconnect(struct serio *serio) | |||
1190 | } | 1203 | } |
1191 | 1204 | ||
1192 | atkbd_enable(atkbd); | 1205 | atkbd_enable(atkbd); |
1206 | retval = 0; | ||
1193 | 1207 | ||
1194 | return 0; | 1208 | out: |
1209 | mutex_unlock(&atkbd->mutex); | ||
1210 | return retval; | ||
1195 | } | 1211 | } |
1196 | 1212 | ||
1197 | static struct serio_device_id atkbd_serio_ids[] = { | 1213 | static struct serio_device_id atkbd_serio_ids[] = { |
@@ -1235,47 +1251,28 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | |||
1235 | ssize_t (*handler)(struct atkbd *, char *)) | 1251 | ssize_t (*handler)(struct atkbd *, char *)) |
1236 | { | 1252 | { |
1237 | struct serio *serio = to_serio_port(dev); | 1253 | struct serio *serio = to_serio_port(dev); |
1238 | int retval; | 1254 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1239 | |||
1240 | retval = serio_pin_driver(serio); | ||
1241 | if (retval) | ||
1242 | return retval; | ||
1243 | |||
1244 | if (serio->drv != &atkbd_drv) { | ||
1245 | retval = -ENODEV; | ||
1246 | goto out; | ||
1247 | } | ||
1248 | |||
1249 | retval = handler((struct atkbd *)serio_get_drvdata(serio), buf); | ||
1250 | 1255 | ||
1251 | out: | 1256 | return handler(atkbd, buf); |
1252 | serio_unpin_driver(serio); | ||
1253 | return retval; | ||
1254 | } | 1257 | } |
1255 | 1258 | ||
1256 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 1259 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, |
1257 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) | 1260 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) |
1258 | { | 1261 | { |
1259 | struct serio *serio = to_serio_port(dev); | 1262 | struct serio *serio = to_serio_port(dev); |
1260 | struct atkbd *atkbd; | 1263 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1261 | int retval; | 1264 | int retval; |
1262 | 1265 | ||
1263 | retval = serio_pin_driver(serio); | 1266 | retval = mutex_lock_interruptible(&atkbd->mutex); |
1264 | if (retval) | 1267 | if (retval) |
1265 | return retval; | 1268 | return retval; |
1266 | 1269 | ||
1267 | if (serio->drv != &atkbd_drv) { | ||
1268 | retval = -ENODEV; | ||
1269 | goto out; | ||
1270 | } | ||
1271 | |||
1272 | atkbd = serio_get_drvdata(serio); | ||
1273 | atkbd_disable(atkbd); | 1270 | atkbd_disable(atkbd); |
1274 | retval = handler(atkbd, buf, count); | 1271 | retval = handler(atkbd, buf, count); |
1275 | atkbd_enable(atkbd); | 1272 | atkbd_enable(atkbd); |
1276 | 1273 | ||
1277 | out: | 1274 | mutex_unlock(&atkbd->mutex); |
1278 | serio_unpin_driver(serio); | 1275 | |
1279 | return retval; | 1276 | return retval; |
1280 | } | 1277 | } |
1281 | 1278 | ||
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 6e52d855f637..d410d7a52f1d 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -174,6 +174,14 @@ static int __init davinci_ks_probe(struct platform_device *pdev) | |||
174 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; | 174 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; |
175 | int error, i; | 175 | int error, i; |
176 | 176 | ||
177 | if (pdata->device_enable) { | ||
178 | error = pdata->device_enable(dev); | ||
179 | if (error < 0) { | ||
180 | dev_dbg(dev, "device enable function failed\n"); | ||
181 | return error; | ||
182 | } | ||
183 | } | ||
184 | |||
177 | if (!pdata->keymap) { | 185 | if (!pdata->keymap) { |
178 | dev_dbg(dev, "no keymap from pdata\n"); | 186 | dev_dbg(dev, "no keymap from pdata\n"); |
179 | return -EINVAL; | 187 | return -EINVAL; |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 0d1d33468b43..4f8fe0886b2a 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -139,6 +139,7 @@ struct tp_finger { | |||
139 | /* trackpad finger data size, empirically at least ten fingers */ | 139 | /* trackpad finger data size, empirically at least ten fingers */ |
140 | #define SIZEOF_FINGER sizeof(struct tp_finger) | 140 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) | 141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) |
142 | #define MAX_FINGER_ORIENTATION 16384 | ||
142 | 143 | ||
143 | /* device-specific parameters */ | 144 | /* device-specific parameters */ |
144 | struct bcm5974_param { | 145 | struct bcm5974_param { |
@@ -284,6 +285,26 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
284 | input_set_abs_params(input_dev, ABS_Y, | 285 | input_set_abs_params(input_dev, ABS_Y, |
285 | 0, cfg->y.dim, cfg->y.fuzz, 0); | 286 | 0, cfg->y.dim, cfg->y.fuzz, 0); |
286 | 287 | ||
288 | /* finger touch area */ | ||
289 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
290 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
291 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
292 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
293 | /* finger approach area */ | ||
294 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, | ||
295 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
296 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, | ||
297 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
298 | /* finger orientation */ | ||
299 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | ||
300 | -MAX_FINGER_ORIENTATION, | ||
301 | MAX_FINGER_ORIENTATION, 0, 0); | ||
302 | /* finger position */ | ||
303 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
304 | cfg->x.devmin, cfg->x.devmax, 0, 0); | ||
305 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
306 | cfg->y.devmin, cfg->y.devmax, 0, 0); | ||
307 | |||
287 | __set_bit(EV_KEY, input_dev->evbit); | 308 | __set_bit(EV_KEY, input_dev->evbit); |
288 | __set_bit(BTN_TOUCH, input_dev->keybit); | 309 | __set_bit(BTN_TOUCH, input_dev->keybit); |
289 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 310 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
@@ -310,13 +331,29 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
310 | return 0; | 331 | return 0; |
311 | } | 332 | } |
312 | 333 | ||
334 | static void report_finger_data(struct input_dev *input, | ||
335 | const struct bcm5974_config *cfg, | ||
336 | const struct tp_finger *f) | ||
337 | { | ||
338 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major)); | ||
339 | input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor)); | ||
340 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major)); | ||
341 | input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor)); | ||
342 | input_report_abs(input, ABS_MT_ORIENTATION, | ||
343 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | ||
344 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | ||
345 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
346 | cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); | ||
347 | input_mt_sync(input); | ||
348 | } | ||
349 | |||
313 | /* report trackpad data as logical trackpad state */ | 350 | /* report trackpad data as logical trackpad state */ |
314 | static int report_tp_state(struct bcm5974 *dev, int size) | 351 | static int report_tp_state(struct bcm5974 *dev, int size) |
315 | { | 352 | { |
316 | const struct bcm5974_config *c = &dev->cfg; | 353 | const struct bcm5974_config *c = &dev->cfg; |
317 | const struct tp_finger *f; | 354 | const struct tp_finger *f; |
318 | struct input_dev *input = dev->input; | 355 | struct input_dev *input = dev->input; |
319 | int raw_p, raw_w, raw_x, raw_y, raw_n; | 356 | int raw_p, raw_w, raw_x, raw_y, raw_n, i; |
320 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; | 357 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; |
321 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 358 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
322 | 359 | ||
@@ -329,6 +366,11 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
329 | 366 | ||
330 | /* always track the first finger; when detached, start over */ | 367 | /* always track the first finger; when detached, start over */ |
331 | if (raw_n) { | 368 | if (raw_n) { |
369 | |||
370 | /* report raw trackpad data */ | ||
371 | for (i = 0; i < raw_n; i++) | ||
372 | report_finger_data(input, c, &f[i]); | ||
373 | |||
332 | raw_p = raw2int(f->force_major); | 374 | raw_p = raw2int(f->force_major); |
333 | raw_w = raw2int(f->size_major); | 375 | raw_w = raw2int(f->size_major); |
334 | raw_x = raw2int(f->abs_x); | 376 | raw_x = raw2int(f->abs_x); |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 401ac6b6edd4..9774bdfaa482 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -627,8 +627,15 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
627 | synaptics_hardware = true; | 627 | synaptics_hardware = true; |
628 | 628 | ||
629 | if (max_proto > PSMOUSE_IMEX) { | 629 | if (max_proto > PSMOUSE_IMEX) { |
630 | if (!set_properties || synaptics_init(psmouse) == 0) | 630 | /* |
631 | * Try activating protocol, but check if support is enabled first, since | ||
632 | * we try detecting Synaptics even when protocol is disabled. | ||
633 | */ | ||
634 | if (synaptics_supported() && | ||
635 | (!set_properties || synaptics_init(psmouse) == 0)) { | ||
631 | return PSMOUSE_SYNAPTICS; | 636 | return PSMOUSE_SYNAPTICS; |
637 | } | ||
638 | |||
632 | /* | 639 | /* |
633 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). | 640 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). |
634 | * Unfortunately Logitech/Genius probes confuse some firmware versions so | 641 | * Unfortunately Logitech/Genius probes confuse some firmware versions so |
@@ -683,19 +690,6 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
683 | max_proto = PSMOUSE_IMEX; | 690 | max_proto = PSMOUSE_IMEX; |
684 | } | 691 | } |
685 | 692 | ||
686 | /* | ||
687 | * Try Finger Sensing Pad | ||
688 | */ | ||
689 | if (max_proto > PSMOUSE_IMEX) { | ||
690 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
691 | if (!set_properties || fsp_init(psmouse) == 0) | ||
692 | return PSMOUSE_FSP; | ||
693 | /* | ||
694 | * Init failed, try basic relative protocols | ||
695 | */ | ||
696 | max_proto = PSMOUSE_IMEX; | ||
697 | } | ||
698 | } | ||
699 | 693 | ||
700 | if (max_proto > PSMOUSE_IMEX) { | 694 | if (max_proto > PSMOUSE_IMEX) { |
701 | if (genius_detect(psmouse, set_properties) == 0) | 695 | if (genius_detect(psmouse, set_properties) == 0) |
@@ -712,6 +706,21 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
712 | } | 706 | } |
713 | 707 | ||
714 | /* | 708 | /* |
709 | * Try Finger Sensing Pad. We do it here because its probe upsets | ||
710 | * Trackpoint devices (causing TP_READ_ID command to time out). | ||
711 | */ | ||
712 | if (max_proto > PSMOUSE_IMEX) { | ||
713 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
714 | if (!set_properties || fsp_init(psmouse) == 0) | ||
715 | return PSMOUSE_FSP; | ||
716 | /* | ||
717 | * Init failed, try basic relative protocols | ||
718 | */ | ||
719 | max_proto = PSMOUSE_IMEX; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | /* | ||
715 | * Reset to defaults in case the device got confused by extended | 724 | * Reset to defaults in case the device got confused by extended |
716 | * protocol probes. Note that we follow up with full reset because | 725 | * protocol probes. Note that we follow up with full reset because |
717 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. | 726 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. |
@@ -1450,24 +1459,10 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *de | |||
1450 | struct serio *serio = to_serio_port(dev); | 1459 | struct serio *serio = to_serio_port(dev); |
1451 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); | 1460 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); |
1452 | struct psmouse *psmouse; | 1461 | struct psmouse *psmouse; |
1453 | int retval; | ||
1454 | |||
1455 | retval = serio_pin_driver(serio); | ||
1456 | if (retval) | ||
1457 | return retval; | ||
1458 | |||
1459 | if (serio->drv != &psmouse_drv) { | ||
1460 | retval = -ENODEV; | ||
1461 | goto out; | ||
1462 | } | ||
1463 | 1462 | ||
1464 | psmouse = serio_get_drvdata(serio); | 1463 | psmouse = serio_get_drvdata(serio); |
1465 | 1464 | ||
1466 | retval = attr->show(psmouse, attr->data, buf); | 1465 | return attr->show(psmouse, attr->data, buf); |
1467 | |||
1468 | out: | ||
1469 | serio_unpin_driver(serio); | ||
1470 | return retval; | ||
1471 | } | 1466 | } |
1472 | 1467 | ||
1473 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, | 1468 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, |
@@ -1478,18 +1473,9 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1478 | struct psmouse *psmouse, *parent = NULL; | 1473 | struct psmouse *psmouse, *parent = NULL; |
1479 | int retval; | 1474 | int retval; |
1480 | 1475 | ||
1481 | retval = serio_pin_driver(serio); | ||
1482 | if (retval) | ||
1483 | return retval; | ||
1484 | |||
1485 | if (serio->drv != &psmouse_drv) { | ||
1486 | retval = -ENODEV; | ||
1487 | goto out_unpin; | ||
1488 | } | ||
1489 | |||
1490 | retval = mutex_lock_interruptible(&psmouse_mutex); | 1476 | retval = mutex_lock_interruptible(&psmouse_mutex); |
1491 | if (retval) | 1477 | if (retval) |
1492 | goto out_unpin; | 1478 | goto out; |
1493 | 1479 | ||
1494 | psmouse = serio_get_drvdata(serio); | 1480 | psmouse = serio_get_drvdata(serio); |
1495 | 1481 | ||
@@ -1519,8 +1505,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1519 | 1505 | ||
1520 | out_unlock: | 1506 | out_unlock: |
1521 | mutex_unlock(&psmouse_mutex); | 1507 | mutex_unlock(&psmouse_mutex); |
1522 | out_unpin: | 1508 | out: |
1523 | serio_unpin_driver(serio); | ||
1524 | return retval; | 1509 | return retval; |
1525 | } | 1510 | } |
1526 | 1511 | ||
@@ -1582,9 +1567,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1582 | } | 1567 | } |
1583 | 1568 | ||
1584 | mutex_unlock(&psmouse_mutex); | 1569 | mutex_unlock(&psmouse_mutex); |
1585 | serio_unpin_driver(serio); | ||
1586 | serio_unregister_child_port(serio); | 1570 | serio_unregister_child_port(serio); |
1587 | serio_pin_driver_uninterruptible(serio); | ||
1588 | mutex_lock(&psmouse_mutex); | 1571 | mutex_lock(&psmouse_mutex); |
1589 | 1572 | ||
1590 | if (serio->drv != &psmouse_drv) { | 1573 | if (serio->drv != &psmouse_drv) { |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 77b9fd0b3fbf..81a6b81cb2fe 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Finger Sensing Pad PS/2 mouse driver. | 2 | * Finger Sensing Pad PS/2 mouse driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. |
5 | * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation. | 5 | * Copyright (C) 2005-2010 Tai-hwa Liang, Sentelic Corporation. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -658,9 +658,9 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
658 | if (packet[3] & BIT(1)) | 658 | if (packet[3] & BIT(1)) |
659 | button_status |= 0x0f; /* wheel up */ | 659 | button_status |= 0x0f; /* wheel up */ |
660 | if (packet[3] & BIT(2)) | 660 | if (packet[3] & BIT(2)) |
661 | button_status |= BIT(5);/* horizontal left */ | 661 | button_status |= BIT(4);/* horizontal left */ |
662 | if (packet[3] & BIT(3)) | 662 | if (packet[3] & BIT(3)) |
663 | button_status |= BIT(4);/* horizontal right */ | 663 | button_status |= BIT(5);/* horizontal right */ |
664 | /* push back to packet queue */ | 664 | /* push back to packet queue */ |
665 | if (button_status != 0) | 665 | if (button_status != 0) |
666 | packet[3] = button_status; | 666 | packet[3] = button_status; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 05689e732191..d3f5243fa093 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -743,6 +743,11 @@ int synaptics_init(struct psmouse *psmouse) | |||
743 | return -1; | 743 | return -1; |
744 | } | 744 | } |
745 | 745 | ||
746 | bool synaptics_supported(void) | ||
747 | { | ||
748 | return true; | ||
749 | } | ||
750 | |||
746 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 751 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
747 | 752 | ||
748 | void __init synaptics_module_init(void) | 753 | void __init synaptics_module_init(void) |
@@ -754,5 +759,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
754 | return -ENOSYS; | 759 | return -ENOSYS; |
755 | } | 760 | } |
756 | 761 | ||
762 | bool synaptics_supported(void) | ||
763 | { | ||
764 | return false; | ||
765 | } | ||
766 | |||
757 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 767 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
758 | 768 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 838e7f2c9b30..f0f40a331dc8 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -109,5 +109,6 @@ void synaptics_module_init(void); | |||
109 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); | 109 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); |
110 | int synaptics_init(struct psmouse *psmouse); | 110 | int synaptics_init(struct psmouse *psmouse); |
111 | void synaptics_reset(struct psmouse *psmouse); | 111 | void synaptics_reset(struct psmouse *psmouse); |
112 | bool synaptics_supported(void); | ||
112 | 113 | ||
113 | #endif /* _SYNAPTICS_H */ | 114 | #endif /* _SYNAPTICS_H */ |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 64b688daf48a..2a5982e532f8 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -524,6 +524,13 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { | |||
524 | */ | 524 | */ |
525 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { | 525 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { |
526 | { | 526 | { |
527 | /* Acer Aspire 5610 */ | ||
528 | .matches = { | ||
529 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
530 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), | ||
531 | }, | ||
532 | }, | ||
533 | { | ||
527 | /* Acer Aspire 5630 */ | 534 | /* Acer Aspire 5630 */ |
528 | .matches = { | 535 | .matches = { |
529 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 536 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |