diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-15 20:37:02 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-15 20:37:02 +0100 |
commit | a9724125ad014decf008d782e60447c811391326 (patch) | |
tree | 4fac069d155f2495907fa9c296cc5426d0eebf55 /drivers/tty/serial/omap-serial.c | |
parent | Merge tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff) | |
parent | serial: 8250: Fix UART_BUG_TXEN workaround (diff) | |
download | linux-a9724125ad014decf008d782e60447c811391326.tar.xz linux-a9724125ad014decf008d782e60447c811391326.zip |
Merge tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver patches from Greg KH:
"Here's the big tty/serial driver update for 3.20-rc1. Nothing huge
here, just lots of driver updates and some core tty layer fixes as
well. All have been in linux-next with no reported issues"
* tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (119 commits)
serial: 8250: Fix UART_BUG_TXEN workaround
serial: driver for ETRAX FS UART
tty: remove unused variable sprop
serial: of-serial: fetch line number from DT
serial: samsung: earlycon support depends on CONFIG_SERIAL_SAMSUNG_CONSOLE
tty/serial: serial8250_set_divisor() can be static
tty/serial: Add Spreadtrum sc9836-uart driver support
Documentation: DT: Add bindings for Spreadtrum SoC Platform
serial: samsung: remove redundant interrupt enabling
tty: Remove external interface for tty_set_termios()
serial: omap: Fix RTS handling
serial: 8250_omap: Use UPSTAT_AUTORTS for RTS handling
serial: core: Rework hw-assisted flow control support
tty/serial: 8250_early: Add support for PXA UARTs
tty/serial: of_serial: add support for PXA/MMP uarts
tty/serial: of_serial: add DT alias ID handling
serial: 8250: Prevent concurrent updates to shadow registers
serial: 8250: Use canary to restart console after suspend
serial: 8250: Refactor XR17V35X divisor calculation
serial: 8250: Refactor divisor programming
...
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 2e1073da6719..10256fa04b40 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -63,7 +63,7 @@ #define UART_ERRATA_i202_MDR1_ACCESS BIT(0) #define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1) -#define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/ +#define DEFAULT_CLK_SPEED 48000000 /* 48Mhz */ /* SCR register bitmasks */ #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) @@ -93,7 +93,7 @@ /* WER = 0x7F * Enable module level wakeup in WER reg */ -#define OMAP_UART_WER_MOD_WKUP 0X7F +#define OMAP_UART_WER_MOD_WKUP 0x7F /* Enable XON/XOFF flow control on output */ #define OMAP_UART_SW_TX 0x08 @@ -114,7 +114,7 @@ struct uart_omap_dma { dma_addr_t tx_buf_dma_phys; unsigned int uart_base; /* - * Buffer for rx dma.It is not required for tx because the buffer + * Buffer for rx dma. It is not required for tx because the buffer * comes from port structure. */ unsigned char *rx_buf; @@ -151,7 +151,7 @@ struct uart_omap_port { int use_dma; /* * Some bits in registers are cleared on a read, so they must - * be saved whenever the register is read but the bits will not + * be saved whenever the register is read, but the bits will not * be immediately processed. */ unsigned int lsr_break_flag; @@ -681,7 +681,7 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port) static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_omap_port *up = to_uart_omap_port(port); - unsigned char mcr = 0, old_mcr; + unsigned char mcr = 0, old_mcr, lcr; dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); if (mctrl & TIOCM_RTS) @@ -701,6 +701,17 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) UART_MCR_DTR | UART_MCR_RTS); up->mcr = old_mcr | mcr; serial_out(up, UART_MCR, up->mcr); + + /* Turn off autoRTS if RTS is lowered; restore autoRTS if RTS raised */ + lcr = serial_in(up, UART_LCR); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) + up->efr |= UART_EFR_RTS; + else + up->efr &= UART_EFR_RTS; + serial_out(up, UART_EFR, up->efr); + serial_out(up, UART_LCR, lcr); + pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); } @@ -756,8 +767,6 @@ static int serial_omap_startup(struct uart_port *port) * (they will be reenabled in set_termios()) */ serial_omap_clear_fifos(up); - /* For Hardware flow control */ - serial_out(up, UART_MCR, UART_MCR_RTS); /* * Clear the interrupt registers. @@ -1053,12 +1062,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); - if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { - /* Enable AUTORTS and AUTOCTS */ - up->efr |= UART_EFR_CTS | UART_EFR_RTS; + up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); - /* Ensure MCR RTS is asserted */ - up->mcr |= UART_MCR_RTS; + if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { + /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ + up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; + up->efr |= UART_EFR_CTS; } else { /* Disable AUTORTS and AUTOCTS */ up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS); @@ -1081,8 +1090,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, * Enable XON/XOFF flow control on output. * Transmit XON1, XOFF1 */ - if (termios->c_iflag & IXOFF) + if (termios->c_iflag & IXOFF) { + up->port.status |= UPSTAT_AUTOXOFF; up->efr |= OMAP_UART_SW_TX; + } /* * IXANY Flag: |