summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2014-05-26 19:22:54 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-30 20:09:43 -0700
commit181eb8df48afdc364e422dbb38a64cd214abe51d (patch)
tree6c082b7306592a7d5191b53d96c5bf385d9b9739
parented02383a98177b99320602186eed08be351f53b3 (diff)
USB: sierra: fix remote wakeup
commit 80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a upstream. Make sure that needs_remote_wake up is always set when there are open ports. Currently close() would unconditionally set needs_remote_wakeup to 0 even though there might still be open ports. This could lead to blocked input and possibly dropped data on devices that do not support remote wakeup (and which must therefore not be runtime suspended while open). Add an open_ports counter (protected by the susp_lock) and only clear needs_remote_wakeup when the last port is closed. Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while online") Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/sierra.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 0d7d4c93cafb..4e4590854123 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -58,6 +58,7 @@ struct sierra_intf_private {
spinlock_t susp_lock;
unsigned int suspended:1;
int in_flight;
+ unsigned int open_ports;
};
static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
@@ -776,7 +777,6 @@ static void sierra_close(struct usb_serial_port *port)
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected) {
- serial->interface->needs_remote_wakeup = 0;
/* odd error handling due to pm counters */
if (!usb_autopm_get_interface(serial->interface))
sierra_send_setup(port);
@@ -787,6 +787,8 @@ static void sierra_close(struct usb_serial_port *port)
mutex_unlock(&serial->disc_mutex);
spin_lock_irq(&intfdata->susp_lock);
portdata->opened = 0;
+ if (--intfdata->open_ports == 0)
+ serial->interface->needs_remote_wakeup = 0;
spin_unlock_irq(&intfdata->susp_lock);
for (;;) {
@@ -842,9 +844,10 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
sierra_send_setup(port);
- serial->interface->needs_remote_wakeup = 1;
spin_lock_irq(&intfdata->susp_lock);
portdata->opened = 1;
+ if (++intfdata->open_ports == 1)
+ serial->interface->needs_remote_wakeup = 1;
spin_unlock_irq(&intfdata->susp_lock);
usb_autopm_put_interface(serial->interface);