--- /dev/null
+From f51661105c3c8a0afcd69f995a4f4a10e53da153 Mon Sep 17 00:00:00 2001
+From: Philipp Merkel <mail@philmerk.de>
+Date: Fri, 1 Oct 2010 15:38:59 +0200
+Subject: HID: Fix for problems with eGalax/DWAV multi-touch-screen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Philipp Merkel <mail@philmerk.de>
+
+commit f51661105c3c8a0afcd69f995a4f4a10e53da153 upstream.
+
+This patch fixes three problems with the eGalax/DWAV multi-touch
+screen found in the Eee PC T101MT:
+
+1) While there is a dedicated multitouch driver for the screen
+ (hid-egalax.c), the MULTI_INPUT quirk is also applied, preventing
+ the hid-egalax driver from working. This patch removes the quirk
+ so the hid-egalax driver can handle the device correctly.
+2) The x and y coordinates sent by the screen in multi-touch mode are
+ shifted by three bits from the events sent in single-touch mode, thus
+ the coordinates are out of range, leading to the pointer being stuck
+ in the bottom-right corner if no additional calibration is applied
+ (e.g. in the X evdev driver). This patch shifts the coordinates back.
+ This does not decrease accuracy as the last three bits of the "wrong"
+ coordinates are always 0.
+3) Only multi-touch pressure events are sent, single touch emulation is
+ missing pressure information. This patch adds single-touch
+ ABS_PRESSURE events.
+
+Signed-off-by: Philipp Merkel <mail@philmerk.de>
+Acked-by: Stéphane Chatty <chatty@enac.fr>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/hid-egalax.c | 16 +++++++++++-----
+ drivers/hid/usbhid/hid-quirks.c | 1 -
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/hid/hid-egalax.c
++++ b/drivers/hid/hid-egalax.c
+@@ -31,7 +31,7 @@ struct egalax_data {
+ bool first; /* is this the first finger in the frame? */
+ bool valid; /* valid finger data, or just placeholder? */
+ bool activity; /* at least one active finger previously? */
+- __u16 lastx, lasty; /* latest valid (x, y) in the frame */
++ __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */
+ };
+
+ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -79,6 +79,10 @@ static int egalax_input_mapping(struct h
+ case HID_DG_TIPPRESSURE:
+ hid_map_usage(hi, usage, bit, max,
+ EV_ABS, ABS_MT_PRESSURE);
++ /* touchscreen emulation */
++ input_set_abs_params(hi->input, ABS_PRESSURE,
++ field->logical_minimum,
++ field->logical_maximum, 0, 0);
+ return 1;
+ }
+ return 0;
+@@ -109,8 +113,8 @@ static void egalax_filter_event(struct e
+ if (td->valid) {
+ /* emit multitouch events */
+ input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
+- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
++ input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
++ input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
+ input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
+
+ input_mt_sync(input);
+@@ -121,6 +125,7 @@ static void egalax_filter_event(struct e
+ */
+ td->lastx = td->x;
+ td->lasty = td->y;
++ td->lastz = td->z;
+ }
+
+ /*
+@@ -129,8 +134,9 @@ static void egalax_filter_event(struct e
+ * the oldest on the panel, the one we want for single touch
+ */
+ if (!td->first && td->activity) {
+- input_event(input, EV_ABS, ABS_X, td->lastx);
+- input_event(input, EV_ABS, ABS_Y, td->lasty);
++ input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
++ input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
++ input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
+ }
+
+ if (!td->valid) {
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -34,7 +34,6 @@ static const struct hid_blacklist {
+ { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
+- { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
tty-prevent-dos-in-the-flush_to_ldisc.patch
tty-restore-tty_ldisc_wait_idle.patch
tty_ldisc-fix-bug-on-hangup.patch
+tty-ldisc-fix-open-flag-handling.patch
+tty-don-t-allow-reopen-when-ldisc-is-changing.patch
+tty-open-hangup-race-fixup.patch
+usbnet-fix-usb_autopm_get_interface-failure-v1.patch
+hid-fix-for-problems-with-egalax-dwav-multi-touch-screen.patch
--- /dev/null
+From e2efafbf139d2bfdfe96f2901f03189fecd172e4 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 29 Nov 2010 10:16:53 +0100
+Subject: TTY: don't allow reopen when ldisc is changing
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit e2efafbf139d2bfdfe96f2901f03189fecd172e4 upstream.
+
+There are many WARNINGs like the following reported nowadays:
+WARNING: at drivers/tty/tty_io.c:1331 tty_open+0x2a2/0x49a()
+Hardware name: Latitude E6500
+Modules linked in:
+Pid: 1207, comm: plymouthd Not tainted 2.6.37-rc3-mmotm1123 #3
+Call Trace:
+ [<ffffffff8103b189>] warn_slowpath_common+0x80/0x98
+ [<ffffffff8103b1b6>] warn_slowpath_null+0x15/0x17
+ [<ffffffff8128a3ab>] tty_open+0x2a2/0x49a
+ [<ffffffff810fd53f>] chrdev_open+0x11d/0x146
+...
+
+This means tty_reopen is called without TTY_LDISC set. For further
+considerations, note tty_lock is held in tty_open. TTY_LDISC is cleared in:
+1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this
+section tty_lock is held. However tty_lock is temporarily dropped in
+the middle of the function by tty_ldisc_hangup.
+
+2) tty_release via tty_ldisc_release till the end of tty existence. If
+tty->count <= 1, tty_lock is taken, TTY_CLOSING bit set and then
+tty_ldisc_release called. tty_reopen checks TTY_CLOSING before checking
+TTY_LDISC.
+
+3) tty_set_ldisc from tty_ldisc_halt to tty_ldisc_enable. We:
+ * take tty_lock, set TTY_LDISC_CHANGING, put tty_lock
+ * call tty_ldisc_halt (clear TTY_LDISC), tty_lock is _not_ held
+ * do some other work
+ * take tty_lock, call tty_ldisc_enable (set TTY_LDISC), put
+ tty_lock
+
+I cannot see how 2) can be a problem, as there I see no race. OTOH, 1)
+and 3) can happen without problems. This patch the case 3) by checking
+TTY_LDISC_CHANGING along with TTY_CLOSING in tty_reopen. 1) will be
+fixed in the following patch.
+
+Nicely reproducible with two processes:
+while (1) {
+ fd = open("/dev/ttyS1", O_RDWR);
+ if (fd < 0) {
+ warn("open");
+ continue;
+ }
+ close(fd);
+}
+--------
+while (1) {
+ fd = open("/dev/ttyS1", O_RDWR);
+ ld1 = 0; ld2 = 2;
+ while (1) {
+ ioctl(fd, TIOCSETD, &ld1);
+ ioctl(fd, TIOCSETD, &ld2);
+ }
+ close(fd);
+}
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Reported-by: <Valdis.Kletnieks@vt.edu>
+Cc: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_io.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -1304,7 +1304,8 @@ static int tty_reopen(struct tty_struct
+ {
+ struct tty_driver *driver = tty->driver;
+
+- if (test_bit(TTY_CLOSING, &tty->flags))
++ if (test_bit(TTY_CLOSING, &tty->flags) ||
++ test_bit(TTY_LDISC_CHANGING, &tty->flags))
+ return -EIO;
+
+ if (driver->type == TTY_DRIVER_TYPE_PTY &&
--- /dev/null
+From 7f90cfc505d613f4faf096e0d84ffe99208057d9 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Thu, 25 Nov 2010 00:27:54 +0100
+Subject: TTY: ldisc, fix open flag handling
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 7f90cfc505d613f4faf096e0d84ffe99208057d9 upstream.
+
+When a concrete ldisc open fails in tty_ldisc_open, we forget to clear
+TTY_LDISC_OPEN. This causes a false warning on the next ldisc open:
+WARNING: at drivers/char/tty_ldisc.c:445 tty_ldisc_open+0x26/0x38()
+Hardware name: System Product Name
+Modules linked in: ...
+Pid: 5251, comm: a.out Tainted: G W 2.6.32-5-686 #1
+Call Trace:
+ [<c1030321>] ? warn_slowpath_common+0x5e/0x8a
+ [<c1030357>] ? warn_slowpath_null+0xa/0xc
+ [<c119311c>] ? tty_ldisc_open+0x26/0x38
+ [<c11936c5>] ? tty_set_ldisc+0x218/0x304
+...
+
+So clear the bit when failing...
+
+Introduced in c65c9bc3efa (tty: rewrite the ldisc locking) back in
+2.6.31-rc1.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Cc: Alan Cox <alan@linux.intel.com>
+Reported-by: Sergey Lapin <slapin@ossfans.org>
+Tested-by: Sergey Lapin <slapin@ossfans.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_ldisc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/char/tty_ldisc.c
++++ b/drivers/char/tty_ldisc.c
+@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_str
+ /* BTM here locks versus a hangup event */
+ WARN_ON(!tty_locked());
+ ret = ld->ops->open(tty);
++ if (ret)
++ clear_bit(TTY_LDISC_OPEN, &tty->flags);
+ return ret;
+ }
+ return 0;
--- /dev/null
+From acfa747baf73922021a047f2d87a2d866f5dbab5 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 29 Nov 2010 10:16:54 +0100
+Subject: TTY: open/hangup race fixup
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit acfa747baf73922021a047f2d87a2d866f5dbab5 upstream.
+
+Like in the "TTY: don't allow reopen when ldisc is changing" patch,
+this one fixes a TTY WARNING as described in the option 1) there:
+1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this
+section tty_lock is held. However tty_lock is temporarily dropped in
+the middle of the function by tty_ldisc_hangup.
+
+The fix is to introduce a new flag which we set during the unlocked
+window and check it in tty_reopen too. The flag is TTY_HUPPING and is
+cleared after TTY_HUPPED is set.
+
+While at it, remove duplicate TTY_HUPPED set_bit. The one after
+calling ops->hangup seems to be more correct. But anyway, we hold
+tty_lock, so there should be no difference.
+
+Also document the function it does that kind of crap.
+
+Nicely reproducible with two forked children:
+static void do_work(const char *tty)
+{
+ if (signal(SIGHUP, SIG_IGN) == SIG_ERR) exit(1);
+ setsid();
+ while (1) {
+ int fd = open(tty, O_RDWR|O_NOCTTY);
+ if (fd < 0) continue;
+ if (ioctl(fd, TIOCSCTTY)) continue;
+ if (vhangup()) continue;
+ close(fd);
+ }
+ exit(0);
+}
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Reported-by: <Valdis.Kletnieks@vt.edu>
+Reported-by: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_io.c | 10 +++++++++-
+ include/linux/tty.h | 1 +
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -553,6 +553,9 @@ void __tty_hangup(struct tty_struct *tty
+
+ tty_lock();
+
++ /* some functions below drop BTM, so we need this bit */
++ set_bit(TTY_HUPPING, &tty->flags);
++
+ /* inuse_filps is protected by the single tty lock,
+ this really needs to change if we want to flush the
+ workqueue with the lock held */
+@@ -572,6 +575,10 @@ void __tty_hangup(struct tty_struct *tty
+ }
+ spin_unlock(&tty_files_lock);
+
++ /*
++ * it drops BTM and thus races with reopen
++ * we protect the race by TTY_HUPPING
++ */
+ tty_ldisc_hangup(tty);
+
+ read_lock(&tasklist_lock);
+@@ -609,7 +616,6 @@ void __tty_hangup(struct tty_struct *tty
+ tty->session = NULL;
+ tty->pgrp = NULL;
+ tty->ctrl_status = 0;
+- set_bit(TTY_HUPPED, &tty->flags);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+ /* Account for the p->signal references we killed */
+@@ -635,6 +641,7 @@ void __tty_hangup(struct tty_struct *tty
+ * can't yet guarantee all that.
+ */
+ set_bit(TTY_HUPPED, &tty->flags);
++ clear_bit(TTY_HUPPING, &tty->flags);
+ tty_ldisc_enable(tty);
+
+ tty_unlock();
+@@ -1305,6 +1312,7 @@ static int tty_reopen(struct tty_struct
+ struct tty_driver *driver = tty->driver;
+
+ if (test_bit(TTY_CLOSING, &tty->flags) ||
++ test_bit(TTY_HUPPING, &tty->flags) ||
+ test_bit(TTY_LDISC_CHANGING, &tty->flags))
+ return -EIO;
+
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -365,6 +365,7 @@ struct tty_file_private {
+ #define TTY_HUPPED 18 /* Post driver->hangup() */
+ #define TTY_FLUSHING 19 /* Flushing to ldisc in progress */
+ #define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */
++#define TTY_HUPPING 21 /* ->hangup() in progress */
+
+ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
+
--- /dev/null
+From b0786b430c982dffbb44d8030e6b6088671ce745 Mon Sep 17 00:00:00 2001
+From: Ming Lei <tom.leiming@gmail.com>
+Date: Mon, 1 Nov 2010 07:11:54 -0700
+Subject: usbnet: fix usb_autopm_get_interface failure(v1)
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+commit b0786b430c982dffbb44d8030e6b6088671ce745 upstream.
+
+Since usbnet already took usb runtime pm, we have to
+enable runtime pm for usb interface of usbnet, otherwise
+usb_autopm_get_interface may return failure and cause
+'ifconfig usb0 up' failed if USB_SUSPEND(RUNTIME_PM) is
+enabled.
+
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Joe Perches <joe@perches.com>
+Cc: Oliver Neukum <oliver@neukum.org>
+Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/usb/usbnet.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -45,6 +45,7 @@
+ #include <linux/usb/usbnet.h>
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
++#include <linux/pm_runtime.h>
+
+ #define DRIVER_VERSION "22-Aug-2005"
+
+@@ -1273,6 +1274,16 @@ usbnet_probe (struct usb_interface *udev
+ struct usb_device *xdev;
+ int status;
+ const char *name;
++ struct usb_driver *driver = to_usb_driver(udev->dev.driver);
++
++ /* usbnet already took usb runtime pm, so have to enable the feature
++ * for usb interface, otherwise usb_autopm_get_interface may return
++ * failure if USB_SUSPEND(RUNTIME_PM) is enabled.
++ */
++ if (!driver->supports_autosuspend) {
++ driver->supports_autosuspend = 1;
++ pm_runtime_enable(&udev->dev);
++ }
+
+ name = udev->dev.driver->name;
+ info = (struct driver_info *) prod->driver_info;