aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-01-06 13:15:12 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-19 14:18:04 -0500
commit2f946414a080e8f516d267a6722f38104699efd1 (patch)
tree3a61317ba3b82c787fc078aa4ffa515ee16c62da
parent12a26bd342b5828b87e098291d17f9a188a0e7e6 (diff)
USB: serial: ch341: fix modem-control and B0 handling
commit 030ee7ae52a46a2be52ccc8242c4a330aba8d38e upstream. The modem-control signals are managed by the tty-layer during open and should not be asserted prematurely when set_termios is called from driver open. Also make sure that the signals are asserted only when changing speed from B0. Fixes: 664d5df92e88 ("USB: usb-serial ch341: support for DTR/RTS/CTS") Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/ch341.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 22b2c464b468..e98590aab633 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -362,24 +362,24 @@ static void ch341_set_termios(struct tty_struct *tty,
362 baud_rate = tty_get_baud_rate(tty); 362 baud_rate = tty_get_baud_rate(tty);
363 363
364 if (baud_rate) { 364 if (baud_rate) {
365 spin_lock_irqsave(&priv->lock, flags);
366 priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
367 spin_unlock_irqrestore(&priv->lock, flags);
368 priv->baud_rate = baud_rate; 365 priv->baud_rate = baud_rate;
369 ch341_set_baudrate(port->serial->dev, priv); 366 ch341_set_baudrate(port->serial->dev, priv);
370 } else {
371 spin_lock_irqsave(&priv->lock, flags);
372 priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
373 spin_unlock_irqrestore(&priv->lock, flags);
374 } 367 }
375 368
376 ch341_set_handshake(port->serial->dev, priv->line_control);
377
378 /* Unimplemented: 369 /* Unimplemented:
379 * (cflag & CSIZE) : data bits [5, 8] 370 * (cflag & CSIZE) : data bits [5, 8]
380 * (cflag & PARENB) : parity {NONE, EVEN, ODD} 371 * (cflag & PARENB) : parity {NONE, EVEN, ODD}
381 * (cflag & CSTOPB) : stop bits [1, 2] 372 * (cflag & CSTOPB) : stop bits [1, 2]
382 */ 373 */
374
375 spin_lock_irqsave(&priv->lock, flags);
376 if (C_BAUD(tty) == B0)
377 priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
378 else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
379 priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
380 spin_unlock_irqrestore(&priv->lock, flags);
381
382 ch341_set_handshake(port->serial->dev, priv->line_control);
383} 383}
384 384
385static void ch341_break_ctl(struct tty_struct *tty, int break_state) 385static void ch341_break_ctl(struct tty_struct *tty, int break_state)