aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/atmel_serial.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 00:05:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 00:05:31 -0500
commitfb0255fb2941ef6f21742b2bc146d6b9aef4fedc (patch)
tree8334f3485152b1c887ddfe04ba9a95c8a704481c /drivers/tty/serial/atmel_serial.c
parent449fcf3ab0baf3dde9952385e6789f2ca10c3980 (diff)
parent57f5d648c45c3d40a3257c06629c14fd53c383bc (diff)
Merge tag 'tty-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH: "Here is the big tty/serial driver pull request for 4.15-rc1. Lots of serial driver updates in here, some small vt cleanups, and a raft of SPDX and license boilerplate cleanups, messing up the diffstat a bit. Nothing major, with no realy functional changes except better hardware support for some platforms. All of these have been in linux-next for a while with no reported issues" * tag 'tty-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (110 commits) tty: ehv_bytechan: fix spelling mistake tty: serial: meson: allow baud-rates lower than 9600 serial: 8250_fintek: Fix crash with baud rate B0 serial: 8250_fintek: Disable delays for ports != 0 serial: 8250_fintek: Return -EINVAL on invalid configuration tty: Remove redundant license text tty: serdev: Remove redundant license text tty: hvc: Remove redundant license text tty: serial: Remove redundant license text tty: add SPDX identifiers to all remaining files in drivers/tty/ tty: serial: jsm: remove redundant pointer ts tty: serial: jsm: add space before the open parenthesis '(' tty: serial: jsm: fix coding style tty: serial: jsm: delete space between function name and '(' tty: serial: jsm: add blank line after declarations tty: serial: jsm: change the type of local variable tty: serial: imx: remove dead code imx_dma_rxint tty: serial: imx: disable ageing timer interrupt if dma in use serial: 8250: fix potential deadlock in rs485-mode serial: m32r_sio: Drop redundant .data assignment ...
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r--drivers/tty/serial/atmel_serial.c65
1 files changed, 20 insertions, 45 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 7551cab438ff..efa25611ca0c 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+
1/* 2/*
2 * Driver for Atmel AT91 Serial ports 3 * Driver for Atmel AT91 Serial ports
3 * Copyright (C) 2003 Rick Bronson 4 * Copyright (C) 2003 Rick Bronson
@@ -6,21 +7,6 @@
6 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. 7 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
7 * 8 *
8 * DMA support added by Chip Coldwell. 9 * DMA support added by Chip Coldwell.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */ 10 */
25#include <linux/tty.h> 11#include <linux/tty.h>
26#include <linux/ioport.h> 12#include <linux/ioport.h>
@@ -171,6 +157,7 @@ struct atmel_uart_port {
171 bool has_hw_timer; 157 bool has_hw_timer;
172 struct timer_list uart_timer; 158 struct timer_list uart_timer;
173 159
160 bool tx_stopped;
174 bool suspended; 161 bool suspended;
175 unsigned int pending; 162 unsigned int pending;
176 unsigned int pending_status; 163 unsigned int pending_status;
@@ -380,6 +367,10 @@ static int atmel_config_rs485(struct uart_port *port,
380 */ 367 */
381static u_int atmel_tx_empty(struct uart_port *port) 368static u_int atmel_tx_empty(struct uart_port *port)
382{ 369{
370 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
371
372 if (atmel_port->tx_stopped)
373 return TIOCSER_TEMT;
383 return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ? 374 return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ?
384 TIOCSER_TEMT : 375 TIOCSER_TEMT :
385 0; 376 0;
@@ -485,6 +476,7 @@ static void atmel_stop_tx(struct uart_port *port)
485 * is fully transmitted. 476 * is fully transmitted.
486 */ 477 */
487 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS); 478 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
479 atmel_port->tx_stopped = true;
488 480
489 /* Disable interrupts */ 481 /* Disable interrupts */
490 atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); 482 atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
@@ -521,6 +513,7 @@ static void atmel_start_tx(struct uart_port *port)
521 513
522 /* re-enable the transmitter */ 514 /* re-enable the transmitter */
523 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN); 515 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
516 atmel_port->tx_stopped = false;
524} 517}
525 518
526/* 519/*
@@ -1178,10 +1171,11 @@ chan_err:
1178 return -EINVAL; 1171 return -EINVAL;
1179} 1172}
1180 1173
1181static void atmel_uart_timer_callback(unsigned long data) 1174static void atmel_uart_timer_callback(struct timer_list *t)
1182{ 1175{
1183 struct uart_port *port = (void *)data; 1176 struct atmel_uart_port *atmel_port = from_timer(atmel_port, t,
1184 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); 1177 uart_timer);
1178 struct uart_port *port = &atmel_port->uart;
1185 1179
1186 if (!atomic_read(&atmel_port->tasklet_shutdown)) { 1180 if (!atomic_read(&atmel_port->tasklet_shutdown)) {
1187 tasklet_schedule(&atmel_port->tasklet_rx); 1181 tasklet_schedule(&atmel_port->tasklet_rx);
@@ -1667,29 +1661,6 @@ static void atmel_init_property(struct atmel_uart_port *atmel_port,
1667 } 1661 }
1668} 1662}
1669 1663
1670static void atmel_init_rs485(struct uart_port *port,
1671 struct platform_device *pdev)
1672{
1673 struct device_node *np = pdev->dev.of_node;
1674
1675 struct serial_rs485 *rs485conf = &port->rs485;
1676 u32 rs485_delay[2];
1677
1678 /* rs485 properties */
1679 if (of_property_read_u32_array(np, "rs485-rts-delay",
1680 rs485_delay, 2) == 0) {
1681 rs485conf->delay_rts_before_send = rs485_delay[0];
1682 rs485conf->delay_rts_after_send = rs485_delay[1];
1683 rs485conf->flags = 0;
1684 }
1685
1686 if (of_get_property(np, "rs485-rx-during-tx", NULL))
1687 rs485conf->flags |= SER_RS485_RX_DURING_TX;
1688
1689 if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL))
1690 rs485conf->flags |= SER_RS485_ENABLED;
1691}
1692
1693static void atmel_set_ops(struct uart_port *port) 1664static void atmel_set_ops(struct uart_port *port)
1694{ 1665{
1695 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); 1666 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
@@ -1866,10 +1837,9 @@ static int atmel_startup(struct uart_port *port)
1866 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); 1837 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
1867 /* enable xmit & rcvr */ 1838 /* enable xmit & rcvr */
1868 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN); 1839 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
1840 atmel_port->tx_stopped = false;
1869 1841
1870 setup_timer(&atmel_port->uart_timer, 1842 timer_setup(&atmel_port->uart_timer, atmel_uart_timer_callback, 0);
1871 atmel_uart_timer_callback,
1872 (unsigned long)port);
1873 1843
1874 if (atmel_use_pdc_rx(port)) { 1844 if (atmel_use_pdc_rx(port)) {
1875 /* set UART timeout */ 1845 /* set UART timeout */
@@ -2122,6 +2092,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
2122 2092
2123 /* disable receiver and transmitter */ 2093 /* disable receiver and transmitter */
2124 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS); 2094 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
2095 atmel_port->tx_stopped = true;
2125 2096
2126 /* mode */ 2097 /* mode */
2127 if (port->rs485.flags & SER_RS485_ENABLED) { 2098 if (port->rs485.flags & SER_RS485_ENABLED) {
@@ -2207,6 +2178,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
2207 atmel_uart_writel(port, ATMEL_US_BRGR, quot); 2178 atmel_uart_writel(port, ATMEL_US_BRGR, quot);
2208 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); 2179 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
2209 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN); 2180 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
2181 atmel_port->tx_stopped = false;
2210 2182
2211 /* restore interrupts */ 2183 /* restore interrupts */
2212 atmel_uart_writel(port, ATMEL_US_IER, imr); 2184 atmel_uart_writel(port, ATMEL_US_IER, imr);
@@ -2373,7 +2345,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
2373 atmel_init_property(atmel_port, pdev); 2345 atmel_init_property(atmel_port, pdev);
2374 atmel_set_ops(port); 2346 atmel_set_ops(port);
2375 2347
2376 atmel_init_rs485(port, pdev); 2348 of_get_rs485_mode(pdev->dev.of_node, &port->rs485);
2377 2349
2378 port->iotype = UPIO_MEM; 2350 port->iotype = UPIO_MEM;
2379 port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP; 2351 port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
@@ -2450,6 +2422,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
2450 2422
2451 /* Make sure that tx path is actually able to send characters */ 2423 /* Make sure that tx path is actually able to send characters */
2452 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN); 2424 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
2425 atmel_port->tx_stopped = false;
2453 2426
2454 uart_console_write(port, s, count, atmel_console_putchar); 2427 uart_console_write(port, s, count, atmel_console_putchar);
2455 2428
@@ -2511,6 +2484,7 @@ static int __init atmel_console_setup(struct console *co, char *options)
2511{ 2484{
2512 int ret; 2485 int ret;
2513 struct uart_port *port = &atmel_ports[co->index].uart; 2486 struct uart_port *port = &atmel_ports[co->index].uart;
2487 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
2514 int baud = 115200; 2488 int baud = 115200;
2515 int bits = 8; 2489 int bits = 8;
2516 int parity = 'n'; 2490 int parity = 'n';
@@ -2528,6 +2502,7 @@ static int __init atmel_console_setup(struct console *co, char *options)
2528 atmel_uart_writel(port, ATMEL_US_IDR, -1); 2502 atmel_uart_writel(port, ATMEL_US_IDR, -1);
2529 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); 2503 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
2530 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN); 2504 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
2505 atmel_port->tx_stopped = false;
2531 2506
2532 if (options) 2507 if (options)
2533 uart_parse_options(options, &baud, &parity, &bits, &flow); 2508 uart_parse_options(options, &baud, &parity, &bits, &flow);