diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-03-31 16:18:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-03-31 16:18:55 -0700 |
commit | 1f944f976d7ef8a29d1ad296253d3a9387c58e62 (patch) | |
tree | 454ef4a50ea47c054171cdde6fdc5eb767ab6d4b /drivers/tty/serial/qcom_geni_serial.c | |
parent | dfabb077d62552797ca0ae7756cb30d3e195ead5 (diff) | |
parent | 8d5b305484e8a3216eeb700ed6c6de870306adbd (diff) |
Merge tag 'tty-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH:
"Here is the big set of TTY / Serial patches for 5.7-rc1
Lots of console fixups and reworking in here, serial core tweaks
(doesn't that ever get old, why are we still creating new serial
devices?), serial driver updates, line-protocol driver updates, and
some vt cleanups and fixes included in here as well.
All have been in linux-next with no reported issues"
* tag 'tty-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (161 commits)
serial: 8250: Optimize irq enable after console write
serial: 8250: Fix rs485 delay after console write
vt: vt_ioctl: fix use-after-free in vt_in_use()
vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console
tty: serial: make SERIAL_SPRD depend on COMMON_CLK
tty: serial: fsl_lpuart: fix return value checking
tty: serial: fsl_lpuart: move dma_request_chan()
ARM: dts: tango4: Make /serial compatible with ns16550a
ARM: dts: mmp*: Make the serial ports compatible with xscale-uart
ARM: dts: mmp*: Fix serial port names
ARM: dts: mmp2-brownstone: Don't redeclare phandle references
ARM: dts: pxa*: Make the serial ports compatible with xscale-uart
ARM: dts: pxa*: Fix serial port names
ARM: dts: pxa*: Don't redeclare phandle references
serial: omap: drop unused dt-bindings header
serial: 8250: 8250_omap: Add DMA support for UARTs on K3 SoCs
serial: 8250: 8250_omap: Work around errata causing spurious IRQs with DMA
serial: 8250: 8250_omap: Extend driver data to pass FIFO trigger info
serial: 8250: 8250_omap: Move locking out from __dma_rx_do_complete()
serial: 8250: 8250_omap: Account for data in flight during DMA teardown
...
Diffstat (limited to 'drivers/tty/serial/qcom_geni_serial.c')
-rw-r--r-- | drivers/tty/serial/qcom_geni_serial.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 0bd1684cabb3..6119090ce045 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -21,6 +21,7 @@ /* UART specific GENI registers */ #define SE_UART_LOOPBACK_CFG 0x22c +#define SE_UART_IO_MACRO_CTRL 0x240 #define SE_UART_TX_TRANS_CFG 0x25c #define SE_UART_TX_WORD_LEN 0x268 #define SE_UART_TX_STOP_BIT_LEN 0x26c @@ -95,6 +96,12 @@ #define CTS_RTS_SORTED BIT(1) #define RX_TX_CTS_RTS_SORTED (RX_TX_SORTED | CTS_RTS_SORTED) +/* UART pin swap value */ +#define DEFAULT_IO_MACRO_IO0_IO1_MASK GENMASK(3, 0) +#define IO_MACRO_IO0_SEL 0x3 +#define DEFAULT_IO_MACRO_IO2_IO3_MASK GENMASK(15, 4) +#define IO_MACRO_IO2_IO3_SWAP 0x4640 + #ifdef CONFIG_CONSOLE_POLL #define CONSOLE_RX_BYTES_PW 1 #else @@ -113,12 +120,14 @@ struct qcom_geni_serial_port { unsigned int baud; unsigned int tx_bytes_pw; unsigned int rx_bytes_pw; - u32 *rx_fifo; + void *rx_fifo; u32 loopback; bool brk; unsigned int tx_remaining; int wakeup_irq; + bool rx_tx_swap; + bool cts_rts_swap; }; static const struct uart_ops qcom_geni_console_pops; @@ -505,7 +514,6 @@ static int handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) { - unsigned char *buf; struct tty_port *tport; struct qcom_geni_serial_port *port = to_dev_port(uport, uport); u32 num_bytes_pw = port->tx_fifo_width / BITS_PER_BYTE; @@ -517,8 +525,7 @@ static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) if (drop) return 0; - buf = (unsigned char *)port->rx_fifo; - ret = tty_insert_flip_string(tport, buf, bytes); + ret = tty_insert_flip_string(tport, port->rx_fifo, bytes); if (ret != bytes) { dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", __func__, ret, bytes); @@ -818,17 +825,7 @@ static void get_tx_fifo_size(struct qcom_geni_serial_port *port) static void qcom_geni_serial_shutdown(struct uart_port *uport) { - unsigned long flags; - - /* Stop the console before stopping the current tx */ - if (uart_console(uport)) - console_stop(uport->cons); - disable_irq(uport->irq); - spin_lock_irqsave(&uport->lock, flags); - qcom_geni_serial_stop_tx(uport); - qcom_geni_serial_stop_rx(uport); - spin_unlock_irqrestore(&uport->lock, flags); } static int qcom_geni_serial_port_setup(struct uart_port *uport) @@ -836,6 +833,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) struct qcom_geni_serial_port *port = to_dev_port(uport, uport); u32 rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT; u32 proto; + u32 pin_swap; if (uart_console(uport)) { port->tx_bytes_pw = 1; @@ -856,6 +854,20 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) get_tx_fifo_size(port); writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT); + + pin_swap = readl(uport->membase + SE_UART_IO_MACRO_CTRL); + if (port->rx_tx_swap) { + pin_swap &= ~DEFAULT_IO_MACRO_IO2_IO3_MASK; + pin_swap |= IO_MACRO_IO2_IO3_SWAP; + } + if (port->cts_rts_swap) { + pin_swap &= ~DEFAULT_IO_MACRO_IO0_IO1_MASK; + pin_swap |= IO_MACRO_IO0_SEL; + } + /* Configure this register if RX-TX, CTS-RTS pins are swapped */ + if (port->rx_tx_swap || port->cts_rts_swap) + writel(pin_swap, uport->membase + SE_UART_IO_MACRO_CTRL); + /* * Make an unconditional cancel on the main sequencer to reset * it else we could end up in data loss scenarios. @@ -868,12 +880,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) false, false, true); geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); geni_se_select_mode(&port->se, GENI_SE_FIFO); - if (!uart_console(uport)) { - port->rx_fifo = devm_kcalloc(uport->dev, - port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); - if (!port->rx_fifo) - return -ENOMEM; - } port->setup = true; return 0; @@ -1284,6 +1290,13 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; + if (!console) { + port->rx_fifo = devm_kcalloc(uport->dev, + port->rx_fifo_depth, sizeof(u32), GFP_KERNEL); + if (!port->rx_fifo) + return -ENOMEM; + } + port->name = devm_kasprintf(uport->dev, GFP_KERNEL, "qcom_geni_serial_%s%d", uart_console(uport) ? "console" : "uart", uport->line); @@ -1299,6 +1312,12 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) if (!console) port->wakeup_irq = platform_get_irq_optional(pdev, 1); + if (of_property_read_bool(pdev->dev.of_node, "rx-tx-swap")) + port->rx_tx_swap = true; + + if (of_property_read_bool(pdev->dev.of_node, "cts-rts-swap")) + port->cts_rts_swap = true; + uport->private_data = drv; platform_set_drvdata(pdev, port); port->handle_rx = console ? handle_rx_console : handle_rx_uart; |