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()
diff --git a/arch/arm/mach-davinci/include/mach/keyscan.h b/arch/arm/mach-davinci/include/mach/keyscan.h
index b4e21a2..7a560e0 100644
--- a/arch/arm/mach-davinci/include/mach/keyscan.h
+++ b/arch/arm/mach-davinci/include/mach/keyscan.h
@@ -29,6 +29,7 @@
 };
 
 struct davinci_ks_platform_data {
+	int		(*device_enable)(struct device *dev);
 	unsigned short	*keymap;
 	u32		keymapsize;
 	u8		rep:1;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index dee6706..258c639 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -59,7 +59,8 @@
 	client->head &= EVDEV_BUFFER_SIZE - 1;
 	spin_unlock(&client->buffer_lock);
 
-	kill_fasync(&client->fasync, SIGIO, POLL_IN);
+	if (event->type == EV_SYN)
+		kill_fasync(&client->fasync, SIGIO, POLL_IN);
 }
 
 /*
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ab060710..30b503b 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -24,6 +24,7 @@
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
 #include <linux/smp_lock.h>
+#include "input-compat.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input core");
@@ -764,6 +765,40 @@
 	return error;
 }
 
+#ifdef CONFIG_COMPAT
+
+static int input_bits_to_string(char *buf, int buf_size,
+				unsigned long bits, bool skip_empty)
+{
+	int len = 0;
+
+	if (INPUT_COMPAT_TEST) {
+		u32 dword = bits >> 32;
+		if (dword || !skip_empty)
+			len += snprintf(buf, buf_size, "%x ", dword);
+
+		dword = bits & 0xffffffffUL;
+		if (dword || !skip_empty || len)
+			len += snprintf(buf + len, max(buf_size - len, 0),
+					"%x", dword);
+	} else {
+		if (bits || !skip_empty)
+			len += snprintf(buf, buf_size, "%lx", bits);
+	}
+
+	return len;
+}
+
+#else /* !CONFIG_COMPAT */
+
+static int input_bits_to_string(char *buf, int buf_size,
+				unsigned long bits, bool skip_empty)
+{
+	return bits || !skip_empty ?
+		snprintf(buf, buf_size, "%lx", bits) : 0;
+}
+
+#endif
 
 #ifdef CONFIG_PROC_FS
 
@@ -832,14 +867,25 @@
 				   unsigned long *bitmap, int max)
 {
 	int i;
-
-	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
-		if (bitmap[i])
-			break;
+	bool skip_empty = true;
+	char buf[18];
 
 	seq_printf(seq, "B: %s=", name);
-	for (; i >= 0; i--)
-		seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : "");
+
+	for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) {
+		if (input_bits_to_string(buf, sizeof(buf),
+					 bitmap[i], skip_empty)) {
+			skip_empty = false;
+			seq_printf(seq, "%s%s", buf, i > 0 ? " " : "");
+		}
+	}
+
+	/*
+	 * If no output was produced print a single 0.
+	 */
+	if (skip_empty)
+		seq_puts(seq, "0");
+
 	seq_putc(seq, '\n');
 }
 
@@ -1128,14 +1174,23 @@
 {
 	int i;
 	int len = 0;
+	bool skip_empty = true;
 
-	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
-		if (bitmap[i])
-			break;
+	for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) {
+		len += input_bits_to_string(buf + len, max(buf_size - len, 0),
+					    bitmap[i], skip_empty);
+		if (len) {
+			skip_empty = false;
+			if (i > 0)
+				len += snprintf(buf + len, max(buf_size - len, 0), " ");
+		}
+	}
 
-	for (; i >= 0; i--)
-		len += snprintf(buf + len, max(buf_size - len, 0),
-				"%lx%s", bitmap[i], i > 0 ? " " : "");
+	/*
+	 * If no output was produced print a single 0.
+	 */
+	if (len == 0)
+		len = snprintf(buf, buf_size, "%d", 0);
 
 	if (add_cr)
 		len += snprintf(buf + len, max(buf_size - len, 0), "\n");
@@ -1150,7 +1205,8 @@
 {									\
 	struct input_dev *input_dev = to_input_dev(dev);		\
 	int len = input_print_bitmap(buf, PAGE_SIZE,			\
-				     input_dev->bm##bit, ev##_MAX, 1);	\
+				     input_dev->bm##bit, ev##_MAX,	\
+				     true);				\
 	return min_t(int, len, PAGE_SIZE);				\
 }									\
 static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
@@ -1214,7 +1270,7 @@
 
 	len = input_print_bitmap(&env->buf[env->buflen - 1],
 				 sizeof(env->buf) - env->buflen,
-				 bitmap, max, 0);
+				 bitmap, max, false);
 	if (len >= (sizeof(env->buf) - env->buflen))
 		return -ENOMEM;
 
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index 67c207f..45ac70e 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -277,7 +277,7 @@
 	}
 
 #ifdef RESET_WORKS
-	if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) ||
+	if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) &&
 	    (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) {
 		err = -ENODEV;
 		goto fail2;
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 482cb12..8a28fb7 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -446,7 +446,7 @@
 	}
 
 exit:
-	retval = usb_submit_urb (urb, GFP_ATOMIC);
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
 		     __func__, retval);
@@ -571,7 +571,7 @@
 		xpad->odata[6] = 0x00;
 		xpad->odata[7] = 0x00;
 		xpad->irq_out->transfer_buffer_length = 8;
-		usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+		usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
 	}
 
 	return 0;
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 1f5e2ce..7b40562 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -225,8 +225,10 @@
 
 	struct delayed_work event_work;
 	unsigned long event_jiffies;
-	struct mutex event_mutex;
 	unsigned long event_mask;
+
+	/* Serializes reconnect(), attr->set() and event work */
+	struct mutex mutex;
 };
 
 /*
@@ -577,7 +579,7 @@
 {
 	struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work);
 
-	mutex_lock(&atkbd->event_mutex);
+	mutex_lock(&atkbd->mutex);
 
 	if (!atkbd->enabled) {
 		/*
@@ -596,7 +598,7 @@
 			atkbd_set_repeat_rate(atkbd);
 	}
 
-	mutex_unlock(&atkbd->event_mutex);
+	mutex_unlock(&atkbd->mutex);
 }
 
 /*
@@ -612,7 +614,7 @@
 
 	atkbd->event_jiffies = jiffies;
 	set_bit(event_bit, &atkbd->event_mask);
-	wmb();
+	mb();
 	schedule_delayed_work(&atkbd->event_work, delay);
 }
 
@@ -849,13 +851,20 @@
 {
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 
+	sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
+
 	atkbd_disable(atkbd);
 
-	/* make sure we don't have a command in flight */
+	input_unregister_device(atkbd->dev);
+
+	/*
+	 * Make sure we don't have a command in flight.
+	 * Note that since atkbd->enabled is false event work will keep
+	 * rescheduling itself until it gets canceled and will not try
+	 * accessing freed input device or serio port.
+	 */
 	cancel_delayed_work_sync(&atkbd->event_work);
 
-	sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
-	input_unregister_device(atkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(atkbd);
@@ -1087,7 +1096,7 @@
 	atkbd->dev = dev;
 	ps2_init(&atkbd->ps2dev, serio);
 	INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work);
-	mutex_init(&atkbd->event_mutex);
+	mutex_init(&atkbd->mutex);
 
 	switch (serio->id.type) {
 
@@ -1160,19 +1169,23 @@
 {
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 	struct serio_driver *drv = serio->drv;
+	int retval = -1;
 
 	if (!atkbd || !drv) {
 		printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
 
+	mutex_lock(&atkbd->mutex);
+
 	atkbd_disable(atkbd);
 
 	if (atkbd->write) {
 		if (atkbd_probe(atkbd))
-			return -1;
+			goto out;
+
 		if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
-			return -1;
+			goto out;
 
 		atkbd_activate(atkbd);
 
@@ -1190,8 +1203,11 @@
 	}
 
 	atkbd_enable(atkbd);
+	retval = 0;
 
-	return 0;
+ out:
+	mutex_unlock(&atkbd->mutex);
+	return retval;
 }
 
 static struct serio_device_id atkbd_serio_ids[] = {
@@ -1235,47 +1251,28 @@
 				ssize_t (*handler)(struct atkbd *, char *))
 {
 	struct serio *serio = to_serio_port(dev);
-	int retval;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 
-	retval = serio_pin_driver(serio);
-	if (retval)
-		return retval;
-
-	if (serio->drv != &atkbd_drv) {
-		retval = -ENODEV;
-		goto out;
-	}
-
-	retval = handler((struct atkbd *)serio_get_drvdata(serio), buf);
-
-out:
-	serio_unpin_driver(serio);
-	return retval;
+	return handler(atkbd, buf);
 }
 
 static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
 				ssize_t (*handler)(struct atkbd *, const char *, size_t))
 {
 	struct serio *serio = to_serio_port(dev);
-	struct atkbd *atkbd;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 	int retval;
 
-	retval = serio_pin_driver(serio);
+	retval = mutex_lock_interruptible(&atkbd->mutex);
 	if (retval)
 		return retval;
 
-	if (serio->drv != &atkbd_drv) {
-		retval = -ENODEV;
-		goto out;
-	}
-
-	atkbd = serio_get_drvdata(serio);
 	atkbd_disable(atkbd);
 	retval = handler(atkbd, buf, count);
 	atkbd_enable(atkbd);
 
-out:
-	serio_unpin_driver(serio);
+	mutex_unlock(&atkbd->mutex);
+
 	return retval;
 }
 
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c
index 6e52d85..d410d7a 100644
--- a/drivers/input/keyboard/davinci_keyscan.c
+++ b/drivers/input/keyboard/davinci_keyscan.c
@@ -174,6 +174,14 @@
 	struct davinci_ks_platform_data *pdata = pdev->dev.platform_data;
 	int error, i;
 
+	if (pdata->device_enable) {
+		error = pdata->device_enable(dev);
+		if (error < 0) {
+			dev_dbg(dev, "device enable function failed\n");
+			return error;
+		}
+	}
+
 	if (!pdata->keymap) {
 		dev_dbg(dev, "no keymap from pdata\n");
 		return -EINVAL;
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 0d1d334..4f8fe08 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -139,6 +139,7 @@
 /* trackpad finger data size, empirically at least ten fingers */
 #define SIZEOF_FINGER		sizeof(struct tp_finger)
 #define SIZEOF_ALL_FINGERS	(16 * SIZEOF_FINGER)
+#define MAX_FINGER_ORIENTATION	16384
 
 /* device-specific parameters */
 struct bcm5974_param {
@@ -284,6 +285,26 @@
 	input_set_abs_params(input_dev, ABS_Y,
 				0, cfg->y.dim, cfg->y.fuzz, 0);
 
+	/* finger touch area */
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	/* finger approach area */
+	input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	/* finger orientation */
+	input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
+			     -MAX_FINGER_ORIENTATION,
+			     MAX_FINGER_ORIENTATION, 0, 0);
+	/* finger position */
+	input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+			     cfg->x.devmin, cfg->x.devmax, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+			     cfg->y.devmin, cfg->y.devmax, 0, 0);
+
 	__set_bit(EV_KEY, input_dev->evbit);
 	__set_bit(BTN_TOUCH, input_dev->keybit);
 	__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
@@ -310,13 +331,29 @@
 	return 0;
 }
 
+static void report_finger_data(struct input_dev *input,
+			       const struct bcm5974_config *cfg,
+			       const struct tp_finger *f)
+{
+	input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major));
+	input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor));
+	input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major));
+	input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor));
+	input_report_abs(input, ABS_MT_ORIENTATION,
+			 MAX_FINGER_ORIENTATION - raw2int(f->orientation));
+	input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x));
+	input_report_abs(input, ABS_MT_POSITION_Y,
+			 cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y));
+	input_mt_sync(input);
+}
+
 /* report trackpad data as logical trackpad state */
 static int report_tp_state(struct bcm5974 *dev, int size)
 {
 	const struct bcm5974_config *c = &dev->cfg;
 	const struct tp_finger *f;
 	struct input_dev *input = dev->input;
-	int raw_p, raw_w, raw_x, raw_y, raw_n;
+	int raw_p, raw_w, raw_x, raw_y, raw_n, i;
 	int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
 	int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
 
@@ -329,6 +366,11 @@
 
 	/* always track the first finger; when detached, start over */
 	if (raw_n) {
+
+		/* report raw trackpad data */
+		for (i = 0; i < raw_n; i++)
+			report_finger_data(input, c, &f[i]);
+
 		raw_p = raw2int(f->force_major);
 		raw_w = raw2int(f->size_major);
 		raw_x = raw2int(f->abs_x);
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 401ac6b..9774bdf 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -627,8 +627,15 @@
 		synaptics_hardware = true;
 
 		if (max_proto > PSMOUSE_IMEX) {
-			if (!set_properties || synaptics_init(psmouse) == 0)
+/*
+ * Try activating protocol, but check if support is enabled first, since
+ * we try detecting Synaptics even when protocol is disabled.
+ */
+			if (synaptics_supported() &&
+			    (!set_properties || synaptics_init(psmouse) == 0)) {
 				return PSMOUSE_SYNAPTICS;
+			}
+
 /*
  * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
  * Unfortunately Logitech/Genius probes confuse some firmware versions so
@@ -683,19 +690,6 @@
 		max_proto = PSMOUSE_IMEX;
 	}
 
-/*
- * Try Finger Sensing Pad
- */
-	if (max_proto > PSMOUSE_IMEX) {
-		if (fsp_detect(psmouse, set_properties) == 0) {
-			if (!set_properties || fsp_init(psmouse) == 0)
-				return PSMOUSE_FSP;
-/*
- * Init failed, try basic relative protocols
- */
-			max_proto = PSMOUSE_IMEX;
-		}
-	}
 
 	if (max_proto > PSMOUSE_IMEX) {
 		if (genius_detect(psmouse, set_properties) == 0)
@@ -712,6 +706,21 @@
 	}
 
 /*
+ * Try Finger Sensing Pad. We do it here because its probe upsets
+ * Trackpoint devices (causing TP_READ_ID command to time out).
+ */
+	if (max_proto > PSMOUSE_IMEX) {
+		if (fsp_detect(psmouse, set_properties) == 0) {
+			if (!set_properties || fsp_init(psmouse) == 0)
+				return PSMOUSE_FSP;
+/*
+ * Init failed, try basic relative protocols
+ */
+			max_proto = PSMOUSE_IMEX;
+		}
+	}
+
+/*
  * Reset to defaults in case the device got confused by extended
  * protocol probes. Note that we follow up with full reset because
  * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
@@ -1450,24 +1459,10 @@
 	struct serio *serio = to_serio_port(dev);
 	struct psmouse_attribute *attr = to_psmouse_attr(devattr);
 	struct psmouse *psmouse;
-	int retval;
-
-	retval = serio_pin_driver(serio);
-	if (retval)
-		return retval;
-
-	if (serio->drv != &psmouse_drv) {
-		retval = -ENODEV;
-		goto out;
-	}
 
 	psmouse = serio_get_drvdata(serio);
 
-	retval = attr->show(psmouse, attr->data, buf);
-
-out:
-	serio_unpin_driver(serio);
-	return retval;
+	return attr->show(psmouse, attr->data, buf);
 }
 
 ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr,
@@ -1478,18 +1473,9 @@
 	struct psmouse *psmouse, *parent = NULL;
 	int retval;
 
-	retval = serio_pin_driver(serio);
-	if (retval)
-		return retval;
-
-	if (serio->drv != &psmouse_drv) {
-		retval = -ENODEV;
-		goto out_unpin;
-	}
-
 	retval = mutex_lock_interruptible(&psmouse_mutex);
 	if (retval)
-		goto out_unpin;
+		goto out;
 
 	psmouse = serio_get_drvdata(serio);
 
@@ -1519,8 +1505,7 @@
 
  out_unlock:
 	mutex_unlock(&psmouse_mutex);
- out_unpin:
-	serio_unpin_driver(serio);
+ out:
 	return retval;
 }
 
@@ -1582,9 +1567,7 @@
 		}
 
 		mutex_unlock(&psmouse_mutex);
-		serio_unpin_driver(serio);
 		serio_unregister_child_port(serio);
-		serio_pin_driver_uninterruptible(serio);
 		mutex_lock(&psmouse_mutex);
 
 		if (serio->drv != &psmouse_drv) {
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 77b9fd0..81a6b81 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -2,7 +2,7 @@
  * Finger Sensing Pad PS/2 mouse driver.
  *
  * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
- * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
+ * Copyright (C) 2005-2010 Tai-hwa Liang, Sentelic Corporation.
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License
@@ -658,9 +658,9 @@
 			if (packet[3] & BIT(1))
 				button_status |= 0x0f;	/* wheel up */
 			if (packet[3] & BIT(2))
-				button_status |= BIT(5);/* horizontal left */
+				button_status |= BIT(4);/* horizontal left */
 			if (packet[3] & BIT(3))
-				button_status |= BIT(4);/* horizontal right */
+				button_status |= BIT(5);/* horizontal right */
 			/* push back to packet queue */
 			if (button_status != 0)
 				packet[3] = button_status;
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 05689e7..d3f5243 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -743,6 +743,11 @@
 	return -1;
 }
 
+bool synaptics_supported(void)
+{
+	return true;
+}
+
 #else /* CONFIG_MOUSE_PS2_SYNAPTICS */
 
 void __init synaptics_module_init(void)
@@ -754,5 +759,10 @@
 	return -ENOSYS;
 }
 
+bool synaptics_supported(void)
+{
+	return false;
+}
+
 #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
 
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 838e7f2..f0f40a3 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -109,5 +109,6 @@
 int synaptics_detect(struct psmouse *psmouse, bool set_properties);
 int synaptics_init(struct psmouse *psmouse);
 void synaptics_reset(struct psmouse *psmouse);
+bool synaptics_supported(void);
 
 #endif /* _SYNAPTICS_H */
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 64b688d..2a5982e 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_dritek_table[] = {
 	{
+		/* Acer Aspire 5610 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+		},
+	},
+	{
 		/* Acer Aspire 5630 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
diff --git a/include/linux/serio.h b/include/linux/serio.h
index e2f3044..813d26c 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -136,25 +136,6 @@
 	spin_unlock_irq(&serio->lock);
 }
 
-/*
- * Use the following functions to pin serio's driver in process context
- */
-static inline int serio_pin_driver(struct serio *serio)
-{
-	return mutex_lock_interruptible(&serio->drv_mutex);
-}
-
-static inline void serio_pin_driver_uninterruptible(struct serio *serio)
-{
-	mutex_lock(&serio->drv_mutex);
-}
-
-static inline void serio_unpin_driver(struct serio *serio)
-{
-	mutex_unlock(&serio->drv_mutex);
-}
-
-
 #endif
 
 /*