diff options
author | Johan Hovold <jhovold@gmail.com> | 2014-01-02 16:49:28 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-03 15:42:24 -0500 |
commit | ac035628a95f20ff4c53b80c4b80e12287231e1a (patch) | |
tree | 52ea124954a8515415f68890a2e6b267657c6f8a /drivers/usb | |
parent | ab62a585a02af4dae2d615d4476e1bf493ff1be8 (diff) |
USB: ch341: refactor line-status handling
Refactor line-status handling.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/ch341.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 8908760cca9f..f647dbdcb27d 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -440,6 +440,33 @@ static int ch341_tiocmset(struct tty_struct *tty, | |||
440 | return ch341_set_handshake(port->serial->dev, control); | 440 | return ch341_set_handshake(port->serial->dev, control); |
441 | } | 441 | } |
442 | 442 | ||
443 | static void ch341_update_line_status(struct usb_serial_port *port, | ||
444 | unsigned char *data, size_t len) | ||
445 | { | ||
446 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
447 | unsigned long flags; | ||
448 | u8 prev_line_status = priv->line_status; | ||
449 | |||
450 | if (len < 4) | ||
451 | return; | ||
452 | |||
453 | spin_lock_irqsave(&priv->lock, flags); | ||
454 | priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; | ||
455 | if ((data[1] & CH341_MULT_STAT)) | ||
456 | priv->multi_status_change = 1; | ||
457 | spin_unlock_irqrestore(&priv->lock, flags); | ||
458 | |||
459 | if ((priv->line_status ^ prev_line_status) & CH341_BIT_DCD) { | ||
460 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
461 | if (tty) | ||
462 | usb_serial_handle_dcd_change(port, tty, | ||
463 | priv->line_status & CH341_BIT_DCD); | ||
464 | tty_kref_put(tty); | ||
465 | } | ||
466 | |||
467 | wake_up_interruptible(&port->port.delta_msr_wait); | ||
468 | } | ||
469 | |||
443 | static void ch341_read_int_callback(struct urb *urb) | 470 | static void ch341_read_int_callback(struct urb *urb) |
444 | { | 471 | { |
445 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | 472 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; |
@@ -466,29 +493,7 @@ static void ch341_read_int_callback(struct urb *urb) | |||
466 | 493 | ||
467 | usb_serial_debug_data(&port->dev, __func__, | 494 | usb_serial_debug_data(&port->dev, __func__, |
468 | urb->actual_length, urb->transfer_buffer); | 495 | urb->actual_length, urb->transfer_buffer); |
469 | 496 | ch341_update_line_status(port, data, actual_length); | |
470 | if (actual_length >= 4) { | ||
471 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
472 | unsigned long flags; | ||
473 | u8 prev_line_status = priv->line_status; | ||
474 | |||
475 | spin_lock_irqsave(&priv->lock, flags); | ||
476 | priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; | ||
477 | if ((data[1] & CH341_MULT_STAT)) | ||
478 | priv->multi_status_change = 1; | ||
479 | spin_unlock_irqrestore(&priv->lock, flags); | ||
480 | |||
481 | if ((priv->line_status ^ prev_line_status) & CH341_BIT_DCD) { | ||
482 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
483 | if (tty) | ||
484 | usb_serial_handle_dcd_change(port, tty, | ||
485 | priv->line_status & CH341_BIT_DCD); | ||
486 | tty_kref_put(tty); | ||
487 | } | ||
488 | |||
489 | wake_up_interruptible(&port->port.delta_msr_wait); | ||
490 | } | ||
491 | |||
492 | exit: | 497 | exit: |
493 | status = usb_submit_urb(urb, GFP_ATOMIC); | 498 | status = usb_submit_urb(urb, GFP_ATOMIC); |
494 | if (status) | 499 | if (status) |