summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/omap-serial.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 20:37:02 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 20:37:02 +0100
commita9724125ad014decf008d782e60447c811391326 (patch)
tree4fac069d155f2495907fa9c296cc5426d0eebf55 /drivers/tty/serial/omap-serial.c
parentMerge tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff)
parentserial: 8250: Fix UART_BUG_TXEN workaround (diff)
downloadlinux-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.c37
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: