diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 00:05:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 00:05:31 -0500 |
commit | fb0255fb2941ef6f21742b2bc146d6b9aef4fedc (patch) | |
tree | 8334f3485152b1c887ddfe04ba9a95c8a704481c /drivers/tty/serial/atmel_serial.c | |
parent | 449fcf3ab0baf3dde9952385e6789f2ca10c3980 (diff) | |
parent | 57f5d648c45c3d40a3257c06629c14fd53c383bc (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.c | 65 |
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 | */ |
381 | static u_int atmel_tx_empty(struct uart_port *port) | 368 | static 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 | ||
1181 | static void atmel_uart_timer_callback(unsigned long data) | 1174 | static 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 | ||
1670 | static 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 | |||
1693 | static void atmel_set_ops(struct uart_port *port) | 1664 | static 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); |