aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2014-01-02 16:49:32 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-03 15:42:24 -0500
commit5e409a265d9327689eef15a8fff1ffcb7f8fc2e1 (patch)
tree1dc4813550ff776ccbc4ef50af5da6441c6b529b /drivers/usb/serial
parentd984fe91a85e49841449b120cda5a50fed1fb126 (diff)
USB: ch341: switch to generic TIOCMIWAIT implementation
Switch to the generic TIOCMIWAIT implementation which does not suffer from the races involved when using the deprecated sleep_on functions. Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/ch341.c49
1 files changed, 8 insertions, 41 deletions
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index acc88650ac0a..ac21618ace19 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -463,7 +463,14 @@ static void ch341_update_line_status(struct usb_serial_port *port,
463 if (!delta) 463 if (!delta)
464 return; 464 return;
465 465
466 if (delta & CH341_BIT_CTS)
467 port->icount.cts++;
468 if (delta & CH341_BIT_DSR)
469 port->icount.dsr++;
470 if (delta & CH341_BIT_RI)
471 port->icount.rng++;
466 if (delta & CH341_BIT_DCD) { 472 if (delta & CH341_BIT_DCD) {
473 port->icount.dcd++;
467 tty = tty_port_tty_get(&port->port); 474 tty = tty_port_tty_get(&port->port);
468 if (tty) { 475 if (tty) {
469 usb_serial_handle_dcd_change(port, tty, 476 usb_serial_handle_dcd_change(port, tty,
@@ -510,46 +517,6 @@ exit:
510 __func__, status); 517 __func__, status);
511} 518}
512 519
513static int ch341_tiocmiwait(struct tty_struct *tty, unsigned long arg)
514{
515 struct usb_serial_port *port = tty->driver_data;
516 struct ch341_private *priv = usb_get_serial_port_data(port);
517 unsigned long flags;
518 u8 prevstatus;
519 u8 status;
520 u8 changed;
521
522 spin_lock_irqsave(&priv->lock, flags);
523 prevstatus = priv->line_status;
524 spin_unlock_irqrestore(&priv->lock, flags);
525
526 for (;;) {
527 interruptible_sleep_on(&port->port.delta_msr_wait);
528 /* see if a signal did it */
529 if (signal_pending(current))
530 return -ERESTARTSYS;
531
532 if (port->serial->disconnected)
533 return -EIO;
534
535 spin_lock_irqsave(&priv->lock, flags);
536 status = priv->line_status;
537 spin_unlock_irqrestore(&priv->lock, flags);
538
539 changed = prevstatus ^ status;
540
541 if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) ||
542 ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) ||
543 ((arg & TIOCM_CD) && (changed & CH341_BIT_DCD)) ||
544 ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) {
545 return 0;
546 }
547 prevstatus = status;
548 }
549
550 return 0;
551}
552
553static int ch341_tiocmget(struct tty_struct *tty) 520static int ch341_tiocmget(struct tty_struct *tty)
554{ 521{
555 struct usb_serial_port *port = tty->driver_data; 522 struct usb_serial_port *port = tty->driver_data;
@@ -603,7 +570,7 @@ static struct usb_serial_driver ch341_device = {
603 .break_ctl = ch341_break_ctl, 570 .break_ctl = ch341_break_ctl,
604 .tiocmget = ch341_tiocmget, 571 .tiocmget = ch341_tiocmget,
605 .tiocmset = ch341_tiocmset, 572 .tiocmset = ch341_tiocmset,
606 .tiocmiwait = ch341_tiocmiwait, 573 .tiocmiwait = usb_serial_generic_tiocmiwait,
607 .read_int_callback = ch341_read_int_callback, 574 .read_int_callback = ch341_read_int_callback,
608 .port_probe = ch341_port_probe, 575 .port_probe = ch341_port_probe,
609 .port_remove = ch341_port_remove, 576 .port_remove = ch341_port_remove,