diff options
Diffstat (limited to 'drivers/tty/serial/imx.c')
-rw-r--r-- | drivers/tty/serial/imx.c | 103 |
1 files changed, 48 insertions, 55 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index dfeff3951f93..a67a606c38eb 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
1 | /* | 2 | /* |
2 | * Driver for Motorola/Freescale IMX serial ports | 3 | * Driver for Motorola/Freescale IMX serial ports |
3 | * | 4 | * |
@@ -5,16 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Author: Sascha Hauer <sascha@saschahauer.de> | 7 | * Author: Sascha Hauer <sascha@saschahauer.de> |
7 | * Copyright (C) 2004 Pengutronix | 8 | * Copyright (C) 2004 Pengutronix |
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | 9 | */ |
19 | 10 | ||
20 | #if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 11 | #if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
@@ -334,7 +325,8 @@ static void imx_port_rts_active(struct imx_port *sport, unsigned long *ucr2) | |||
334 | { | 325 | { |
335 | *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); | 326 | *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); |
336 | 327 | ||
337 | mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS); | 328 | sport->port.mctrl |= TIOCM_RTS; |
329 | mctrl_gpio_set(sport->gpios, sport->port.mctrl); | ||
338 | } | 330 | } |
339 | 331 | ||
340 | static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) | 332 | static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) |
@@ -342,7 +334,8 @@ static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) | |||
342 | *ucr2 &= ~UCR2_CTSC; | 334 | *ucr2 &= ~UCR2_CTSC; |
343 | *ucr2 |= UCR2_CTS; | 335 | *ucr2 |= UCR2_CTS; |
344 | 336 | ||
345 | mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS); | 337 | sport->port.mctrl &= ~TIOCM_RTS; |
338 | mctrl_gpio_set(sport->gpios, sport->port.mctrl); | ||
346 | } | 339 | } |
347 | 340 | ||
348 | static void imx_port_rts_auto(struct imx_port *sport, unsigned long *ucr2) | 341 | static void imx_port_rts_auto(struct imx_port *sport, unsigned long *ucr2) |
@@ -714,8 +707,6 @@ static void imx_disable_rx_int(struct imx_port *sport) | |||
714 | { | 707 | { |
715 | unsigned long temp; | 708 | unsigned long temp; |
716 | 709 | ||
717 | sport->dma_is_rxing = 1; | ||
718 | |||
719 | /* disable the receiver ready and aging timer interrupts */ | 710 | /* disable the receiver ready and aging timer interrupts */ |
720 | temp = readl(sport->port.membase + UCR1); | 711 | temp = readl(sport->port.membase + UCR1); |
721 | temp &= ~(UCR1_RRDYEN); | 712 | temp &= ~(UCR1_RRDYEN); |
@@ -732,29 +723,6 @@ static void imx_disable_rx_int(struct imx_port *sport) | |||
732 | } | 723 | } |
733 | 724 | ||
734 | static void clear_rx_errors(struct imx_port *sport); | 725 | static void clear_rx_errors(struct imx_port *sport); |
735 | static int start_rx_dma(struct imx_port *sport); | ||
736 | /* | ||
737 | * If the RXFIFO is filled with some data, and then we | ||
738 | * arise a DMA operation to receive them. | ||
739 | */ | ||
740 | static void imx_dma_rxint(struct imx_port *sport) | ||
741 | { | ||
742 | unsigned long temp; | ||
743 | unsigned long flags; | ||
744 | |||
745 | spin_lock_irqsave(&sport->port.lock, flags); | ||
746 | |||
747 | temp = readl(sport->port.membase + USR2); | ||
748 | if ((temp & USR2_RDR) && !sport->dma_is_rxing) { | ||
749 | |||
750 | imx_disable_rx_int(sport); | ||
751 | |||
752 | /* tell the DMA to receive the data. */ | ||
753 | start_rx_dma(sport); | ||
754 | } | ||
755 | |||
756 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
757 | } | ||
758 | 726 | ||
759 | /* | 727 | /* |
760 | * We have a modem side uart, so the meanings of RTS and CTS are inverted. | 728 | * We have a modem side uart, so the meanings of RTS and CTS are inverted. |
@@ -816,11 +784,8 @@ static irqreturn_t imx_int(int irq, void *dev_id) | |||
816 | sts = readl(sport->port.membase + USR1); | 784 | sts = readl(sport->port.membase + USR1); |
817 | sts2 = readl(sport->port.membase + USR2); | 785 | sts2 = readl(sport->port.membase + USR2); |
818 | 786 | ||
819 | if (sts & (USR1_RRDY | USR1_AGTIM)) { | 787 | if (!sport->dma_is_enabled && (sts & (USR1_RRDY | USR1_AGTIM))) { |
820 | if (sport->dma_is_enabled) | 788 | imx_rxint(irq, dev_id); |
821 | imx_dma_rxint(sport); | ||
822 | else | ||
823 | imx_rxint(irq, dev_id); | ||
824 | ret = IRQ_HANDLED; | 789 | ret = IRQ_HANDLED; |
825 | } | 790 | } |
826 | 791 | ||
@@ -1074,6 +1039,7 @@ static int start_rx_dma(struct imx_port *sport) | |||
1074 | desc->callback_param = sport; | 1039 | desc->callback_param = sport; |
1075 | 1040 | ||
1076 | dev_dbg(dev, "RX: prepare for the DMA.\n"); | 1041 | dev_dbg(dev, "RX: prepare for the DMA.\n"); |
1042 | sport->dma_is_rxing = 1; | ||
1077 | sport->rx_cookie = dmaengine_submit(desc); | 1043 | sport->rx_cookie = dmaengine_submit(desc); |
1078 | dma_async_issue_pending(chan); | 1044 | dma_async_issue_pending(chan); |
1079 | return 0; | 1045 | return 0; |
@@ -1165,7 +1131,7 @@ static int imx_uart_dma_init(struct imx_port *sport) | |||
1165 | goto err; | 1131 | goto err; |
1166 | } | 1132 | } |
1167 | 1133 | ||
1168 | sport->rx_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); | 1134 | sport->rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL); |
1169 | if (!sport->rx_buf) { | 1135 | if (!sport->rx_buf) { |
1170 | ret = -ENOMEM; | 1136 | ret = -ENOMEM; |
1171 | goto err; | 1137 | goto err; |
@@ -1207,10 +1173,6 @@ static void imx_enable_dma(struct imx_port *sport) | |||
1207 | temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN; | 1173 | temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN; |
1208 | writel(temp, sport->port.membase + UCR1); | 1174 | writel(temp, sport->port.membase + UCR1); |
1209 | 1175 | ||
1210 | temp = readl(sport->port.membase + UCR2); | ||
1211 | temp |= UCR2_ATEN; | ||
1212 | writel(temp, sport->port.membase + UCR2); | ||
1213 | |||
1214 | imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA); | 1176 | imx_setup_ufcr(sport, TXTL_DMA, RXTL_DMA); |
1215 | 1177 | ||
1216 | sport->dma_is_enabled = 1; | 1178 | sport->dma_is_enabled = 1; |
@@ -1411,15 +1373,19 @@ static void imx_flush_buffer(struct uart_port *port) | |||
1411 | temp = readl(sport->port.membase + UCR1); | 1373 | temp = readl(sport->port.membase + UCR1); |
1412 | temp &= ~UCR1_TDMAEN; | 1374 | temp &= ~UCR1_TDMAEN; |
1413 | writel(temp, sport->port.membase + UCR1); | 1375 | writel(temp, sport->port.membase + UCR1); |
1414 | sport->dma_is_txing = false; | 1376 | sport->dma_is_txing = 0; |
1415 | } | 1377 | } |
1416 | 1378 | ||
1417 | /* | 1379 | /* |
1418 | * According to the Reference Manual description of the UART SRST bit: | 1380 | * According to the Reference Manual description of the UART SRST bit: |
1381 | * | ||
1419 | * "Reset the transmit and receive state machines, | 1382 | * "Reset the transmit and receive state machines, |
1420 | * all FIFOs and register USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD | 1383 | * all FIFOs and register USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD |
1421 | * and UTS[6-3]". As we don't need to restore the old values from | 1384 | * and UTS[6-3]". |
1422 | * USR1, USR2, URXD, UTXD, only save/restore the other four registers | 1385 | * |
1386 | * We don't need to restore the old values from USR1, USR2, URXD and | ||
1387 | * UTXD. UBRC is read only, so only save/restore the other three | ||
1388 | * registers. | ||
1423 | */ | 1389 | */ |
1424 | ubir = readl(sport->port.membase + UBIR); | 1390 | ubir = readl(sport->port.membase + UBIR); |
1425 | ubmr = readl(sport->port.membase + UBMR); | 1391 | ubmr = readl(sport->port.membase + UBMR); |
@@ -2051,6 +2017,8 @@ static int serial_imx_probe_dt(struct imx_port *sport, | |||
2051 | if (of_get_property(np, "rts-gpios", NULL)) | 2017 | if (of_get_property(np, "rts-gpios", NULL)) |
2052 | sport->have_rtsgpio = 1; | 2018 | sport->have_rtsgpio = 1; |
2053 | 2019 | ||
2020 | of_get_rs485_mode(np, &sport->port.rs485); | ||
2021 | |||
2054 | return 0; | 2022 | return 0; |
2055 | } | 2023 | } |
2056 | #else | 2024 | #else |
@@ -2112,12 +2080,9 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
2112 | sport->port.fifosize = 32; | 2080 | sport->port.fifosize = 32; |
2113 | sport->port.ops = &imx_pops; | 2081 | sport->port.ops = &imx_pops; |
2114 | sport->port.rs485_config = imx_rs485_config; | 2082 | sport->port.rs485_config = imx_rs485_config; |
2115 | sport->port.rs485.flags = | 2083 | sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND; |
2116 | SER_RS485_RTS_ON_SEND | SER_RS485_RX_DURING_TX; | ||
2117 | sport->port.flags = UPF_BOOT_AUTOCONF; | 2084 | sport->port.flags = UPF_BOOT_AUTOCONF; |
2118 | init_timer(&sport->timer); | 2085 | setup_timer(&sport->timer, imx_timeout, (unsigned long)sport); |
2119 | sport->timer.function = imx_timeout; | ||
2120 | sport->timer.data = (unsigned long)sport; | ||
2121 | 2086 | ||
2122 | sport->gpios = mctrl_gpio_init(&sport->port, 0); | 2087 | sport->gpios = mctrl_gpio_init(&sport->port, 0); |
2123 | if (IS_ERR(sport->gpios)) | 2088 | if (IS_ERR(sport->gpios)) |
@@ -2346,11 +2311,39 @@ static int imx_serial_port_resume(struct device *dev) | |||
2346 | return 0; | 2311 | return 0; |
2347 | } | 2312 | } |
2348 | 2313 | ||
2314 | static int imx_serial_port_freeze(struct device *dev) | ||
2315 | { | ||
2316 | struct platform_device *pdev = to_platform_device(dev); | ||
2317 | struct imx_port *sport = platform_get_drvdata(pdev); | ||
2318 | |||
2319 | uart_suspend_port(&imx_reg, &sport->port); | ||
2320 | |||
2321 | /* Needed to enable clock in suspend_noirq */ | ||
2322 | return clk_prepare(sport->clk_ipg); | ||
2323 | } | ||
2324 | |||
2325 | static int imx_serial_port_thaw(struct device *dev) | ||
2326 | { | ||
2327 | struct platform_device *pdev = to_platform_device(dev); | ||
2328 | struct imx_port *sport = platform_get_drvdata(pdev); | ||
2329 | |||
2330 | uart_resume_port(&imx_reg, &sport->port); | ||
2331 | |||
2332 | clk_unprepare(sport->clk_ipg); | ||
2333 | |||
2334 | return 0; | ||
2335 | } | ||
2336 | |||
2349 | static const struct dev_pm_ops imx_serial_port_pm_ops = { | 2337 | static const struct dev_pm_ops imx_serial_port_pm_ops = { |
2350 | .suspend_noirq = imx_serial_port_suspend_noirq, | 2338 | .suspend_noirq = imx_serial_port_suspend_noirq, |
2351 | .resume_noirq = imx_serial_port_resume_noirq, | 2339 | .resume_noirq = imx_serial_port_resume_noirq, |
2340 | .freeze_noirq = imx_serial_port_suspend_noirq, | ||
2341 | .restore_noirq = imx_serial_port_resume_noirq, | ||
2352 | .suspend = imx_serial_port_suspend, | 2342 | .suspend = imx_serial_port_suspend, |
2353 | .resume = imx_serial_port_resume, | 2343 | .resume = imx_serial_port_resume, |
2344 | .freeze = imx_serial_port_freeze, | ||
2345 | .thaw = imx_serial_port_thaw, | ||
2346 | .restore = imx_serial_port_thaw, | ||
2354 | }; | 2347 | }; |
2355 | 2348 | ||
2356 | static struct platform_driver serial_imx_driver = { | 2349 | static struct platform_driver serial_imx_driver = { |