blob: 8854ac6f383d848a13719efbaa61f022539697f2 [file] [log] [blame]
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001/*
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002 * Driver for Atmel AT91 / AT32 Serial ports
Andrew Victor1e6c9c22006-01-10 16:59:27 +00003 * Copyright (C) 2003 Rick Bronson
4 *
5 * Based on drivers/char/serial_sa1100.c, by Deep Blue Solutions Ltd.
6 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
7 *
Chip Coldwella6670612008-02-08 04:21:06 -08008 * DMA support added by Chip Coldwell.
9 *
Andrew Victor1e6c9c22006-01-10 16:59:27 +000010 * 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 */
Andrew Victor1e6c9c22006-01-10 16:59:27 +000025#include <linux/tty.h>
26#include <linux/ioport.h>
27#include <linux/slab.h>
28#include <linux/init.h>
29#include <linux/serial.h>
Andrew Victorafefc412006-06-19 19:53:19 +010030#include <linux/clk.h>
Andrew Victor1e6c9c22006-01-10 16:59:27 +000031#include <linux/console.h>
32#include <linux/sysrq.h>
33#include <linux/tty_flip.h>
Andrew Victorafefc412006-06-19 19:53:19 +010034#include <linux/platform_device.h>
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +020035#include <linux/of.h>
36#include <linux/of_device.h>
Linus Walleij354e57f2013-11-07 10:25:55 +010037#include <linux/of_gpio.h>
Chip Coldwella6670612008-02-08 04:21:06 -080038#include <linux/dma-mapping.h>
Vinod Koul6b997ba2014-10-16 12:59:06 +053039#include <linux/dmaengine.h>
Andrew Victor93a3ddc2007-02-08 11:31:22 +010040#include <linux/atmel_pdc.h>
Guennadi Liakhovetskifa3218d2008-01-29 15:43:13 +010041#include <linux/atmel_serial.h>
Claudio Scordinoe8faff72010-05-03 13:31:28 +010042#include <linux/uaccess.h>
Jean-Christophe PLAGNIOL-VILLARDbcd23602012-10-30 05:12:23 +080043#include <linux/platform_data/atmel.h>
Elen Song2e68c222013-07-22 16:30:30 +080044#include <linux/timer.h>
Linus Walleij354e57f2013-11-07 10:25:55 +010045#include <linux/gpio.h>
Richard Genoude0b0baa2014-05-13 20:20:44 +020046#include <linux/gpio/consumer.h>
47#include <linux/err.h>
Richard Genoudab5e4e42014-05-13 20:20:45 +020048#include <linux/irq.h>
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +010049#include <linux/suspend.h>
Andrew Victor1e6c9c22006-01-10 16:59:27 +000050
51#include <asm/io.h>
Peter Huewef7512e72010-06-29 19:35:39 +020052#include <asm/ioctls.h>
Andrew Victor1e6c9c22006-01-10 16:59:27 +000053
Chip Coldwella6670612008-02-08 04:21:06 -080054#define PDC_BUFFER_SIZE 512
55/* Revisit: We should calculate this based on the actual port settings */
56#define PDC_RX_TIMEOUT (3 * 10) /* 3 bytes */
57
Cyrille Pitchenb5199d42015-07-02 15:18:12 +020058/* The minium number of data FIFOs should be able to contain */
59#define ATMEL_MIN_FIFO_SIZE 8
60/*
61 * These two offsets are substracted from the RX FIFO size to define the RTS
62 * high and low thresholds
63 */
64#define ATMEL_RTS_HIGH_OFFSET 16
65#define ATMEL_RTS_LOW_OFFSET 20
66
Haavard Skinnemoen749c4e62006-10-04 16:02:02 +020067#if defined(CONFIG_SERIAL_ATMEL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
Andrew Victor1e6c9c22006-01-10 16:59:27 +000068#define SUPPORT_SYSRQ
69#endif
70
71#include <linux/serial_core.h>
72
Richard Genoude0b0baa2014-05-13 20:20:44 +020073#include "serial_mctrl_gpio.h"
74
Claudio Scordinoe8faff72010-05-03 13:31:28 +010075static void atmel_start_rx(struct uart_port *port);
76static void atmel_stop_rx(struct uart_port *port);
77
Haavard Skinnemoen749c4e62006-10-04 16:02:02 +020078#ifdef CONFIG_SERIAL_ATMEL_TTYAT
Andrew Victor1e6c9c22006-01-10 16:59:27 +000079
80/* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we
81 * should coexist with the 8250 driver, such as if we have an external 16C550
82 * UART. */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +020083#define SERIAL_ATMEL_MAJOR 204
Andrew Victor1e6c9c22006-01-10 16:59:27 +000084#define MINOR_START 154
Haavard Skinnemoen7192f922006-10-04 16:02:05 +020085#define ATMEL_DEVICENAME "ttyAT"
Andrew Victor1e6c9c22006-01-10 16:59:27 +000086
87#else
88
89/* Use device name ttyS, major 4, minor 64-68. This is the usual serial port
90 * name, but it is legally reserved for the 8250 driver. */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +020091#define SERIAL_ATMEL_MAJOR TTY_MAJOR
Andrew Victor1e6c9c22006-01-10 16:59:27 +000092#define MINOR_START 64
Haavard Skinnemoen7192f922006-10-04 16:02:05 +020093#define ATMEL_DEVICENAME "ttyS"
Andrew Victor1e6c9c22006-01-10 16:59:27 +000094
95#endif
96
Haavard Skinnemoen7192f922006-10-04 16:02:05 +020097#define ATMEL_ISR_PASS_LIMIT 256
Andrew Victor1e6c9c22006-01-10 16:59:27 +000098
Chip Coldwella6670612008-02-08 04:21:06 -080099struct atmel_dma_buffer {
100 unsigned char *buf;
101 dma_addr_t dma_addr;
102 unsigned int dma_size;
103 unsigned int ofs;
104};
105
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800106struct atmel_uart_char {
107 u16 status;
108 u16 ch;
109};
110
111#define ATMEL_SERIAL_RINGSIZE 1024
112
Andrew Victorafefc412006-06-19 19:53:19 +0100113/*
Alexandre Belloni9af92fb2015-09-10 11:29:03 +0200114 * at91: 6 USARTs and one DBGU port (SAM9260)
115 * avr32: 4
116 */
117#define ATMEL_MAX_UART 7
118
119/*
Andrew Victorafefc412006-06-19 19:53:19 +0100120 * We wrap our port structure around the generic uart_port.
121 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200122struct atmel_uart_port {
Andrew Victorafefc412006-06-19 19:53:19 +0100123 struct uart_port uart; /* uart */
124 struct clk *clk; /* uart clock */
Anti Sullinf05596d2008-09-22 13:57:54 -0700125 int may_wakeup; /* cached value of device_may_wakeup for times we need to disable it */
126 u32 backup_imr; /* IMR saved during suspend */
Haavard Skinnemoen9e6077b2007-07-15 23:40:36 -0700127 int break_active; /* break being received */
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800128
Elen Song34df42f2013-07-22 16:30:27 +0800129 bool use_dma_rx; /* enable DMA receiver */
Elen Song64e22eb2013-07-22 16:30:24 +0800130 bool use_pdc_rx; /* enable PDC receiver */
Chip Coldwella6670612008-02-08 04:21:06 -0800131 short pdc_rx_idx; /* current PDC RX buffer */
132 struct atmel_dma_buffer pdc_rx[2]; /* PDC receier */
133
Elen Song08f738b2013-07-22 16:30:26 +0800134 bool use_dma_tx; /* enable DMA transmitter */
Elen Song64e22eb2013-07-22 16:30:24 +0800135 bool use_pdc_tx; /* enable PDC transmitter */
Chip Coldwella6670612008-02-08 04:21:06 -0800136 struct atmel_dma_buffer pdc_tx; /* PDC transmitter */
137
Elen Song08f738b2013-07-22 16:30:26 +0800138 spinlock_t lock_tx; /* port lock */
Elen Song34df42f2013-07-22 16:30:27 +0800139 spinlock_t lock_rx; /* port lock */
Elen Song08f738b2013-07-22 16:30:26 +0800140 struct dma_chan *chan_tx;
Elen Song34df42f2013-07-22 16:30:27 +0800141 struct dma_chan *chan_rx;
Elen Song08f738b2013-07-22 16:30:26 +0800142 struct dma_async_tx_descriptor *desc_tx;
Elen Song34df42f2013-07-22 16:30:27 +0800143 struct dma_async_tx_descriptor *desc_rx;
Elen Song08f738b2013-07-22 16:30:26 +0800144 dma_cookie_t cookie_tx;
Elen Song34df42f2013-07-22 16:30:27 +0800145 dma_cookie_t cookie_rx;
Elen Song08f738b2013-07-22 16:30:26 +0800146 struct scatterlist sg_tx;
Elen Song34df42f2013-07-22 16:30:27 +0800147 struct scatterlist sg_rx;
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800148 struct tasklet_struct tasklet;
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800149 unsigned int irq_status_prev;
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200150 unsigned int tx_len;
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800151
152 struct circ_buf rx_ring;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100153
Richard Genoude0b0baa2014-05-13 20:20:44 +0200154 struct mctrl_gpios *gpios;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100155 unsigned int tx_done_mask;
Cyrille Pitchenb5199d42015-07-02 15:18:12 +0200156 u32 fifo_size;
157 u32 rts_high;
158 u32 rts_low;
Richard Genoudab5e4e42014-05-13 20:20:45 +0200159 bool ms_irq_enabled;
Ludovic Desroches2958cce2016-02-22 15:18:55 +0100160 u32 rtor; /* address of receiver timeout register if it exists */
Nicolas Ferre4b769372016-01-26 11:26:14 +0100161 bool has_hw_timer;
162 struct timer_list uart_timer;
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +0100163
164 bool suspended;
165 unsigned int pending;
166 unsigned int pending_status;
167 spinlock_t lock_suspended;
168
Elen Songa930e522013-07-22 16:30:25 +0800169 int (*prepare_rx)(struct uart_port *port);
170 int (*prepare_tx)(struct uart_port *port);
171 void (*schedule_rx)(struct uart_port *port);
172 void (*schedule_tx)(struct uart_port *port);
173 void (*release_rx)(struct uart_port *port);
174 void (*release_tx)(struct uart_port *port);
Andrew Victorafefc412006-06-19 19:53:19 +0100175};
176
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200177static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
Pawel Wieczorkiewicz503bded2013-02-20 17:26:20 +0100178static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART);
Andrew Victorafefc412006-06-19 19:53:19 +0100179
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000180#ifdef SUPPORT_SYSRQ
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200181static struct console atmel_console;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000182#endif
183
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +0200184#if defined(CONFIG_OF)
185static const struct of_device_id atmel_serial_dt_ids[] = {
186 { .compatible = "atmel,at91rm9200-usart" },
187 { .compatible = "atmel,at91sam9260-usart" },
188 { /* sentinel */ }
189};
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +0200190#endif
191
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -0800192static inline struct atmel_uart_port *
193to_atmel_uart_port(struct uart_port *uart)
194{
195 return container_of(uart, struct atmel_uart_port, uart);
196}
197
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200198static inline u32 atmel_uart_readl(struct uart_port *port, u32 reg)
199{
200 return __raw_readl(port->membase + reg);
201}
202
203static inline void atmel_uart_writel(struct uart_port *port, u32 reg, u32 value)
204{
205 __raw_writel(value, port->membase + reg);
206}
207
Cyrille Pitchena6499432015-07-30 16:33:38 +0200208#ifdef CONFIG_AVR32
209
210/* AVR32 cannot handle 8 or 16bit I/O accesses but only 32bit I/O accesses */
211static inline u8 atmel_uart_read_char(struct uart_port *port)
Cyrille Pitchenb5199d42015-07-02 15:18:12 +0200212{
Cyrille Pitchena6499432015-07-30 16:33:38 +0200213 return __raw_readl(port->membase + ATMEL_US_RHR);
Cyrille Pitchenb5199d42015-07-02 15:18:12 +0200214}
215
Cyrille Pitchena6499432015-07-30 16:33:38 +0200216static inline void atmel_uart_write_char(struct uart_port *port, u8 value)
Cyrille Pitchenb5199d42015-07-02 15:18:12 +0200217{
Cyrille Pitchena6499432015-07-30 16:33:38 +0200218 __raw_writel(value, port->membase + ATMEL_US_THR);
Cyrille Pitchenb5199d42015-07-02 15:18:12 +0200219}
220
Cyrille Pitchena6499432015-07-30 16:33:38 +0200221#else
222
223static inline u8 atmel_uart_read_char(struct uart_port *port)
224{
225 return __raw_readb(port->membase + ATMEL_US_RHR);
226}
227
228static inline void atmel_uart_write_char(struct uart_port *port, u8 value)
229{
230 __raw_writeb(value, port->membase + ATMEL_US_THR);
231}
232
233#endif
234
Chip Coldwella6670612008-02-08 04:21:06 -0800235#ifdef CONFIG_SERIAL_ATMEL_PDC
Elen Song64e22eb2013-07-22 16:30:24 +0800236static bool atmel_use_pdc_rx(struct uart_port *port)
Chip Coldwella6670612008-02-08 04:21:06 -0800237{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -0800238 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Chip Coldwella6670612008-02-08 04:21:06 -0800239
Elen Song64e22eb2013-07-22 16:30:24 +0800240 return atmel_port->use_pdc_rx;
Chip Coldwella6670612008-02-08 04:21:06 -0800241}
242
Elen Song64e22eb2013-07-22 16:30:24 +0800243static bool atmel_use_pdc_tx(struct uart_port *port)
Chip Coldwella6670612008-02-08 04:21:06 -0800244{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -0800245 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Chip Coldwella6670612008-02-08 04:21:06 -0800246
Elen Song64e22eb2013-07-22 16:30:24 +0800247 return atmel_port->use_pdc_tx;
Chip Coldwella6670612008-02-08 04:21:06 -0800248}
249#else
Elen Song64e22eb2013-07-22 16:30:24 +0800250static bool atmel_use_pdc_rx(struct uart_port *port)
Chip Coldwella6670612008-02-08 04:21:06 -0800251{
252 return false;
253}
254
Elen Song64e22eb2013-07-22 16:30:24 +0800255static bool atmel_use_pdc_tx(struct uart_port *port)
Chip Coldwella6670612008-02-08 04:21:06 -0800256{
257 return false;
258}
259#endif
260
Elen Song08f738b2013-07-22 16:30:26 +0800261static bool atmel_use_dma_tx(struct uart_port *port)
262{
263 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
264
265 return atmel_port->use_dma_tx;
266}
267
Elen Song34df42f2013-07-22 16:30:27 +0800268static bool atmel_use_dma_rx(struct uart_port *port)
269{
270 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
271
272 return atmel_port->use_dma_rx;
273}
274
Alexandre Belloni5be605a2016-04-12 14:51:40 +0200275static bool atmel_use_fifo(struct uart_port *port)
276{
277 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
278
279 return atmel_port->fifo_size;
280}
281
Richard Genoude0b0baa2014-05-13 20:20:44 +0200282static unsigned int atmel_get_lines_status(struct uart_port *port)
283{
284 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
285 unsigned int status, ret = 0;
286
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200287 status = atmel_uart_readl(port, ATMEL_US_CSR);
Richard Genoude0b0baa2014-05-13 20:20:44 +0200288
289 mctrl_gpio_get(atmel_port->gpios, &ret);
290
291 if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
292 UART_GPIO_CTS))) {
293 if (ret & TIOCM_CTS)
294 status &= ~ATMEL_US_CTS;
295 else
296 status |= ATMEL_US_CTS;
297 }
298
299 if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
300 UART_GPIO_DSR))) {
301 if (ret & TIOCM_DSR)
302 status &= ~ATMEL_US_DSR;
303 else
304 status |= ATMEL_US_DSR;
305 }
306
307 if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
308 UART_GPIO_RI))) {
309 if (ret & TIOCM_RI)
310 status &= ~ATMEL_US_RI;
311 else
312 status |= ATMEL_US_RI;
313 }
314
315 if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
316 UART_GPIO_DCD))) {
317 if (ret & TIOCM_CD)
318 status &= ~ATMEL_US_DCD;
319 else
320 status |= ATMEL_US_DCD;
321 }
322
323 return status;
324}
325
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100326/* Enable or disable the rs485 support */
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +0100327static int atmel_config_rs485(struct uart_port *port,
328 struct serial_rs485 *rs485conf)
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100329{
330 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
331 unsigned int mode;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100332
333 /* Disable interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200334 atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100335
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200336 mode = atmel_uart_readl(port, ATMEL_US_MR);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100337
338 /* Resetting serial mode to RS232 (0x0) */
339 mode &= ~ATMEL_US_USMODE;
340
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +0100341 port->rs485 = *rs485conf;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100342
343 if (rs485conf->flags & SER_RS485_ENABLED) {
344 dev_dbg(port->dev, "Setting UART to RS485\n");
345 atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200346 atmel_uart_writel(port, ATMEL_US_TTGR,
347 rs485conf->delay_rts_after_send);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100348 mode |= ATMEL_US_USMODE_RS485;
349 } else {
350 dev_dbg(port->dev, "Setting UART to RS232\n");
Elen Song64e22eb2013-07-22 16:30:24 +0800351 if (atmel_use_pdc_tx(port))
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100352 atmel_port->tx_done_mask = ATMEL_US_ENDTX |
353 ATMEL_US_TXBUFE;
354 else
355 atmel_port->tx_done_mask = ATMEL_US_TXRDY;
356 }
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200357 atmel_uart_writel(port, ATMEL_US_MR, mode);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100358
359 /* Enable interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200360 atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100361
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +0100362 return 0;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100363}
364
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000365/*
366 * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
367 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200368static u_int atmel_tx_empty(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000369{
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200370 return (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXEMPTY) ?
371 TIOCSER_TEMT :
372 0;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000373}
374
375/*
376 * Set state of the modem control output lines
377 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200378static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000379{
380 unsigned int control = 0;
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200381 unsigned int mode = atmel_uart_readl(port, ATMEL_US_MR);
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +0100382 unsigned int rts_paused, rts_ready;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100383 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000384
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +0100385 /* override mode to RS485 if needed, otherwise keep the current mode */
386 if (port->rs485.flags & SER_RS485_ENABLED) {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200387 atmel_uart_writel(port, ATMEL_US_TTGR,
388 port->rs485.delay_rts_after_send);
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +0100389 mode &= ~ATMEL_US_USMODE;
390 mode |= ATMEL_US_USMODE_RS485;
391 }
392
393 /* set the RTS line state according to the mode */
394 if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) {
395 /* force RTS line to high level */
396 rts_paused = ATMEL_US_RTSEN;
397
398 /* give the control of the RTS line back to the hardware */
399 rts_ready = ATMEL_US_RTSDIS;
400 } else {
401 /* force RTS line to high level */
402 rts_paused = ATMEL_US_RTSDIS;
403
404 /* force RTS line to low level */
405 rts_ready = ATMEL_US_RTSEN;
406 }
407
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000408 if (mctrl & TIOCM_RTS)
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +0100409 control |= rts_ready;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000410 else
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +0100411 control |= rts_paused;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000412
413 if (mctrl & TIOCM_DTR)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200414 control |= ATMEL_US_DTREN;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000415 else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200416 control |= ATMEL_US_DTRDIS;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000417
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200418 atmel_uart_writel(port, ATMEL_US_CR, control);
Andrew Victorafefc412006-06-19 19:53:19 +0100419
Richard Genoude0b0baa2014-05-13 20:20:44 +0200420 mctrl_gpio_set(atmel_port->gpios, mctrl);
421
Andrew Victorafefc412006-06-19 19:53:19 +0100422 /* Local loopback mode? */
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +0100423 mode &= ~ATMEL_US_CHMODE;
Andrew Victorafefc412006-06-19 19:53:19 +0100424 if (mctrl & TIOCM_LOOP)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200425 mode |= ATMEL_US_CHMODE_LOC_LOOP;
Andrew Victorafefc412006-06-19 19:53:19 +0100426 else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200427 mode |= ATMEL_US_CHMODE_NORMAL;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100428
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200429 atmel_uart_writel(port, ATMEL_US_MR, mode);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000430}
431
432/*
433 * Get state of the modem control input lines
434 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200435static u_int atmel_get_mctrl(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000436{
Richard Genoude0b0baa2014-05-13 20:20:44 +0200437 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
438 unsigned int ret = 0, status;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000439
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200440 status = atmel_uart_readl(port, ATMEL_US_CSR);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000441
442 /*
443 * The control signals are active low.
444 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200445 if (!(status & ATMEL_US_DCD))
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000446 ret |= TIOCM_CD;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200447 if (!(status & ATMEL_US_CTS))
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000448 ret |= TIOCM_CTS;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200449 if (!(status & ATMEL_US_DSR))
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000450 ret |= TIOCM_DSR;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200451 if (!(status & ATMEL_US_RI))
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000452 ret |= TIOCM_RI;
453
Richard Genoude0b0baa2014-05-13 20:20:44 +0200454 return mctrl_gpio_get(atmel_port->gpios, &ret);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000455}
456
457/*
458 * Stop transmitting.
459 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200460static void atmel_stop_tx(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000461{
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100462 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
463
Elen Song64e22eb2013-07-22 16:30:24 +0800464 if (atmel_use_pdc_tx(port)) {
Chip Coldwella6670612008-02-08 04:21:06 -0800465 /* disable PDC transmit */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200466 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100467 }
468 /* Disable interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200469 atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100470
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +0100471 if ((port->rs485.flags & SER_RS485_ENABLED) &&
472 !(port->rs485.flags & SER_RS485_RX_DURING_TX))
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100473 atmel_start_rx(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000474}
475
476/*
477 * Start transmitting.
478 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200479static void atmel_start_tx(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000480{
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100481 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
482
Elen Song64e22eb2013-07-22 16:30:24 +0800483 if (atmel_use_pdc_tx(port)) {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200484 if (atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN)
Chip Coldwella6670612008-02-08 04:21:06 -0800485 /* The transmitter is already running. Yes, we
486 really need this.*/
487 return;
488
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +0100489 if ((port->rs485.flags & SER_RS485_ENABLED) &&
490 !(port->rs485.flags & SER_RS485_RX_DURING_TX))
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100491 atmel_stop_rx(port);
492
Chip Coldwella6670612008-02-08 04:21:06 -0800493 /* re-enable PDC transmit */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200494 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100495 }
496 /* Enable interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200497 atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100498}
499
500/*
501 * start receiving - port is in process of being opened.
502 */
503static void atmel_start_rx(struct uart_port *port)
504{
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200505 /* reset status and receiver */
506 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100507
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200508 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RXEN);
Siftar, Gabe57c36862012-03-29 15:40:05 +0200509
Elen Song64e22eb2013-07-22 16:30:24 +0800510 if (atmel_use_pdc_rx(port)) {
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100511 /* enable PDC controller */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200512 atmel_uart_writel(port, ATMEL_US_IER,
513 ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
514 port->read_status_mask);
515 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100516 } else {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200517 atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_RXRDY);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100518 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000519}
520
521/*
522 * Stop receiving - port is in process of being closed.
523 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200524static void atmel_stop_rx(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000525{
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200526 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RXDIS);
Siftar, Gabe57c36862012-03-29 15:40:05 +0200527
Elen Song64e22eb2013-07-22 16:30:24 +0800528 if (atmel_use_pdc_rx(port)) {
Chip Coldwella6670612008-02-08 04:21:06 -0800529 /* disable PDC receive */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200530 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS);
531 atmel_uart_writel(port, ATMEL_US_IDR,
532 ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
533 port->read_status_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100534 } else {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200535 atmel_uart_writel(port, ATMEL_US_IDR, ATMEL_US_RXRDY);
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100536 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000537}
538
539/*
540 * Enable modem status interrupts
541 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200542static void atmel_enable_ms(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000543{
Richard Genoudab5e4e42014-05-13 20:20:45 +0200544 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
545 uint32_t ier = 0;
546
547 /*
548 * Interrupt should not be enabled twice
549 */
550 if (atmel_port->ms_irq_enabled)
551 return;
552
553 atmel_port->ms_irq_enabled = true;
554
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200555 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS))
Richard Genoudab5e4e42014-05-13 20:20:45 +0200556 ier |= ATMEL_US_CTSIC;
557
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200558 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DSR))
Richard Genoudab5e4e42014-05-13 20:20:45 +0200559 ier |= ATMEL_US_DSRIC;
560
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200561 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_RI))
Richard Genoudab5e4e42014-05-13 20:20:45 +0200562 ier |= ATMEL_US_RIIC;
563
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200564 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DCD))
Richard Genoudab5e4e42014-05-13 20:20:45 +0200565 ier |= ATMEL_US_DCDIC;
566
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200567 atmel_uart_writel(port, ATMEL_US_IER, ier);
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200568
569 mctrl_gpio_enable_ms(atmel_port->gpios);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000570}
571
572/*
Richard Genoud35b675b2014-09-03 18:09:26 +0200573 * Disable modem status interrupts
574 */
575static void atmel_disable_ms(struct uart_port *port)
576{
577 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
578 uint32_t idr = 0;
579
580 /*
581 * Interrupt should not be disabled twice
582 */
583 if (!atmel_port->ms_irq_enabled)
584 return;
585
586 atmel_port->ms_irq_enabled = false;
587
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200588 mctrl_gpio_disable_ms(atmel_port->gpios);
589
590 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS))
Richard Genoud35b675b2014-09-03 18:09:26 +0200591 idr |= ATMEL_US_CTSIC;
592
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200593 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DSR))
Richard Genoud35b675b2014-09-03 18:09:26 +0200594 idr |= ATMEL_US_DSRIC;
595
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200596 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_RI))
Richard Genoud35b675b2014-09-03 18:09:26 +0200597 idr |= ATMEL_US_RIIC;
598
Uwe Kleine-König18dfef92015-10-18 21:34:45 +0200599 if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_DCD))
Richard Genoud35b675b2014-09-03 18:09:26 +0200600 idr |= ATMEL_US_DCDIC;
601
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200602 atmel_uart_writel(port, ATMEL_US_IDR, idr);
Richard Genoud35b675b2014-09-03 18:09:26 +0200603}
604
605/*
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000606 * Control the transmission of a break signal
607 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200608static void atmel_break_ctl(struct uart_port *port, int break_state)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000609{
610 if (break_state != 0)
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200611 /* start break */
612 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTBRK);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000613 else
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200614 /* stop break */
615 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STPBRK);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000616}
617
618/*
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800619 * Stores the incoming character in the ring buffer
620 */
621static void
622atmel_buffer_rx_char(struct uart_port *port, unsigned int status,
623 unsigned int ch)
624{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -0800625 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800626 struct circ_buf *ring = &atmel_port->rx_ring;
627 struct atmel_uart_char *c;
628
629 if (!CIRC_SPACE(ring->head, ring->tail, ATMEL_SERIAL_RINGSIZE))
630 /* Buffer overflow, ignore char */
631 return;
632
633 c = &((struct atmel_uart_char *)ring->buf)[ring->head];
634 c->status = status;
635 c->ch = ch;
636
637 /* Make sure the character is stored before we update head. */
638 smp_wmb();
639
640 ring->head = (ring->head + 1) & (ATMEL_SERIAL_RINGSIZE - 1);
641}
642
643/*
Chip Coldwella6670612008-02-08 04:21:06 -0800644 * Deal with parity, framing and overrun errors.
645 */
646static void atmel_pdc_rxerr(struct uart_port *port, unsigned int status)
647{
648 /* clear error */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200649 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);
Chip Coldwella6670612008-02-08 04:21:06 -0800650
651 if (status & ATMEL_US_RXBRK) {
652 /* ignore side-effect */
653 status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME);
654 port->icount.brk++;
655 }
656 if (status & ATMEL_US_PARE)
657 port->icount.parity++;
658 if (status & ATMEL_US_FRAME)
659 port->icount.frame++;
660 if (status & ATMEL_US_OVRE)
661 port->icount.overrun++;
662}
663
664/*
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000665 * Characters received (called from interrupt handler)
666 */
David Howells7d12e782006-10-05 14:55:46 +0100667static void atmel_rx_chars(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000668{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -0800669 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800670 unsigned int status, ch;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000671
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200672 status = atmel_uart_readl(port, ATMEL_US_CSR);
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200673 while (status & ATMEL_US_RXRDY) {
Cyrille Pitchena6499432015-07-30 16:33:38 +0200674 ch = atmel_uart_read_char(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000675
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000676 /*
677 * note that the error handling code is
678 * out of the main execution path
679 */
Haavard Skinnemoen9e6077b2007-07-15 23:40:36 -0700680 if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME
681 | ATMEL_US_OVRE | ATMEL_US_RXBRK)
682 || atmel_port->break_active)) {
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800683
Remy Bohmerb843aa22008-02-08 04:21:01 -0800684 /* clear error */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200685 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800686
Haavard Skinnemoen9e6077b2007-07-15 23:40:36 -0700687 if (status & ATMEL_US_RXBRK
688 && !atmel_port->break_active) {
Haavard Skinnemoen9e6077b2007-07-15 23:40:36 -0700689 atmel_port->break_active = 1;
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200690 atmel_uart_writel(port, ATMEL_US_IER,
691 ATMEL_US_RXBRK);
Haavard Skinnemoen9e6077b2007-07-15 23:40:36 -0700692 } else {
693 /*
694 * This is either the end-of-break
695 * condition or we've received at
696 * least one character without RXBRK
697 * being set. In both cases, the next
698 * RXBRK will indicate start-of-break.
699 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200700 atmel_uart_writel(port, ATMEL_US_IDR,
701 ATMEL_US_RXBRK);
Haavard Skinnemoen9e6077b2007-07-15 23:40:36 -0700702 status &= ~ATMEL_US_RXBRK;
703 atmel_port->break_active = 0;
Andrew Victorafefc412006-06-19 19:53:19 +0100704 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000705 }
706
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800707 atmel_buffer_rx_char(port, status, ch);
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200708 status = atmel_uart_readl(port, ATMEL_US_CSR);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000709 }
710
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800711 tasklet_schedule(&atmel_port->tasklet);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000712}
713
714/*
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800715 * Transmit characters (called from tasklet with TXRDY interrupt
716 * disabled)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000717 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +0200718static void atmel_tx_chars(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000719{
Alan Coxebd2c8f2009-09-19 13:13:28 -0700720 struct circ_buf *xmit = &port->state->xmit;
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100721 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000722
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200723 if (port->x_char &&
724 (atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask)) {
Cyrille Pitchena6499432015-07-30 16:33:38 +0200725 atmel_uart_write_char(port, port->x_char);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000726 port->icount.tx++;
727 port->x_char = 0;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000728 }
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800729 if (uart_circ_empty(xmit) || uart_tx_stopped(port))
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000730 return;
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000731
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200732 while (atmel_uart_readl(port, ATMEL_US_CSR) &
733 atmel_port->tx_done_mask) {
Cyrille Pitchena6499432015-07-30 16:33:38 +0200734 atmel_uart_write_char(port, xmit->buf[xmit->tail]);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000735 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
736 port->icount.tx++;
737 if (uart_circ_empty(xmit))
738 break;
739 }
740
741 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
742 uart_write_wakeup(port);
743
Remy Bohmer1ecc26b2008-02-08 04:21:05 -0800744 if (!uart_circ_empty(xmit))
Claudio Scordinoe8faff72010-05-03 13:31:28 +0100745 /* Enable interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200746 atmel_uart_writel(port, ATMEL_US_IER,
747 atmel_port->tx_done_mask);
Andrew Victor1e6c9c22006-01-10 16:59:27 +0000748}
749
Elen Song08f738b2013-07-22 16:30:26 +0800750static void atmel_complete_tx_dma(void *arg)
751{
752 struct atmel_uart_port *atmel_port = arg;
753 struct uart_port *port = &atmel_port->uart;
754 struct circ_buf *xmit = &port->state->xmit;
755 struct dma_chan *chan = atmel_port->chan_tx;
756 unsigned long flags;
757
758 spin_lock_irqsave(&port->lock, flags);
759
760 if (chan)
761 dmaengine_terminate_all(chan);
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200762 xmit->tail += atmel_port->tx_len;
Elen Song08f738b2013-07-22 16:30:26 +0800763 xmit->tail &= UART_XMIT_SIZE - 1;
764
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200765 port->icount.tx += atmel_port->tx_len;
Elen Song08f738b2013-07-22 16:30:26 +0800766
767 spin_lock_irq(&atmel_port->lock_tx);
768 async_tx_ack(atmel_port->desc_tx);
769 atmel_port->cookie_tx = -EINVAL;
770 atmel_port->desc_tx = NULL;
771 spin_unlock_irq(&atmel_port->lock_tx);
772
773 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
774 uart_write_wakeup(port);
775
Cyrille Pitchen1842dc2e2014-12-09 14:31:36 +0100776 /*
777 * xmit is a circular buffer so, if we have just send data from
778 * xmit->tail to the end of xmit->buf, now we have to transmit the
779 * remaining data from the beginning of xmit->buf to xmit->head.
780 */
Elen Song08f738b2013-07-22 16:30:26 +0800781 if (!uart_circ_empty(xmit))
782 tasklet_schedule(&atmel_port->tasklet);
783
784 spin_unlock_irqrestore(&port->lock, flags);
785}
786
787static void atmel_release_tx_dma(struct uart_port *port)
788{
789 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
790 struct dma_chan *chan = atmel_port->chan_tx;
791
792 if (chan) {
793 dmaengine_terminate_all(chan);
794 dma_release_channel(chan);
795 dma_unmap_sg(port->dev, &atmel_port->sg_tx, 1,
Wolfram Sang48479142014-07-21 11:42:04 +0200796 DMA_TO_DEVICE);
Elen Song08f738b2013-07-22 16:30:26 +0800797 }
798
799 atmel_port->desc_tx = NULL;
800 atmel_port->chan_tx = NULL;
801 atmel_port->cookie_tx = -EINVAL;
802}
803
804/*
805 * Called from tasklet with TXRDY interrupt is disabled.
806 */
807static void atmel_tx_dma(struct uart_port *port)
808{
809 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
810 struct circ_buf *xmit = &port->state->xmit;
811 struct dma_chan *chan = atmel_port->chan_tx;
812 struct dma_async_tx_descriptor *desc;
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200813 struct scatterlist sgl[2], *sg, *sg_tx = &atmel_port->sg_tx;
814 unsigned int tx_len, part1_len, part2_len, sg_len;
815 dma_addr_t phys_addr;
Elen Song08f738b2013-07-22 16:30:26 +0800816
817 /* Make sure we have an idle channel */
818 if (atmel_port->desc_tx != NULL)
819 return;
820
821 if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {
822 /*
823 * DMA is idle now.
824 * Port xmit buffer is already mapped,
825 * and it is one page... Just adjust
826 * offsets and lengths. Since it is a circular buffer,
827 * we have to transmit till the end, and then the rest.
828 * Take the port lock to get a
829 * consistent xmit buffer state.
830 */
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200831 tx_len = CIRC_CNT_TO_END(xmit->head,
832 xmit->tail,
833 UART_XMIT_SIZE);
834
835 if (atmel_port->fifo_size) {
836 /* multi data mode */
837 part1_len = (tx_len & ~0x3); /* DWORD access */
838 part2_len = (tx_len & 0x3); /* BYTE access */
839 } else {
840 /* single data (legacy) mode */
841 part1_len = 0;
842 part2_len = tx_len; /* BYTE access only */
843 }
844
845 sg_init_table(sgl, 2);
846 sg_len = 0;
847 phys_addr = sg_dma_address(sg_tx) + xmit->tail;
848 if (part1_len) {
849 sg = &sgl[sg_len++];
850 sg_dma_address(sg) = phys_addr;
851 sg_dma_len(sg) = part1_len;
852
853 phys_addr += part1_len;
854 }
855
856 if (part2_len) {
857 sg = &sgl[sg_len++];
858 sg_dma_address(sg) = phys_addr;
859 sg_dma_len(sg) = part2_len;
860 }
861
862 /*
863 * save tx_len so atmel_complete_tx_dma() will increase
864 * xmit->tail correctly
865 */
866 atmel_port->tx_len = tx_len;
Elen Song08f738b2013-07-22 16:30:26 +0800867
868 desc = dmaengine_prep_slave_sg(chan,
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200869 sgl,
870 sg_len,
Cyrille Pitchen1842dc2e2014-12-09 14:31:36 +0100871 DMA_MEM_TO_DEV,
872 DMA_PREP_INTERRUPT |
873 DMA_CTRL_ACK);
Elen Song08f738b2013-07-22 16:30:26 +0800874 if (!desc) {
875 dev_err(port->dev, "Failed to send via dma!\n");
876 return;
877 }
878
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200879 dma_sync_sg_for_device(port->dev, sg_tx, 1, DMA_TO_DEVICE);
Elen Song08f738b2013-07-22 16:30:26 +0800880
881 atmel_port->desc_tx = desc;
882 desc->callback = atmel_complete_tx_dma;
883 desc->callback_param = atmel_port;
884 atmel_port->cookie_tx = dmaengine_submit(desc);
885
886 } else {
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +0100887 if (port->rs485.flags & SER_RS485_ENABLED) {
Elen Song08f738b2013-07-22 16:30:26 +0800888 /* DMA done, stop TX, start RX for RS485 */
889 atmel_start_rx(port);
890 }
891 }
892
893 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
894 uart_write_wakeup(port);
895}
896
897static int atmel_prepare_tx_dma(struct uart_port *port)
898{
899 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
900 dma_cap_mask_t mask;
901 struct dma_slave_config config;
902 int ret, nent;
903
904 dma_cap_zero(mask);
905 dma_cap_set(DMA_SLAVE, mask);
906
907 atmel_port->chan_tx = dma_request_slave_channel(port->dev, "tx");
908 if (atmel_port->chan_tx == NULL)
909 goto chan_err;
910 dev_info(port->dev, "using %s for tx DMA transfers\n",
911 dma_chan_name(atmel_port->chan_tx));
912
913 spin_lock_init(&atmel_port->lock_tx);
914 sg_init_table(&atmel_port->sg_tx, 1);
915 /* UART circular tx buffer is an aligned page. */
Leilei Zhao2c277052015-02-27 16:07:14 +0800916 BUG_ON(!PAGE_ALIGNED(port->state->xmit.buf));
Elen Song08f738b2013-07-22 16:30:26 +0800917 sg_set_page(&atmel_port->sg_tx,
918 virt_to_page(port->state->xmit.buf),
919 UART_XMIT_SIZE,
Uwe Kleine-Königc8d1f022015-09-30 10:19:38 +0200920 (unsigned long)port->state->xmit.buf & ~PAGE_MASK);
Elen Song08f738b2013-07-22 16:30:26 +0800921 nent = dma_map_sg(port->dev,
922 &atmel_port->sg_tx,
923 1,
Wolfram Sang48479142014-07-21 11:42:04 +0200924 DMA_TO_DEVICE);
Elen Song08f738b2013-07-22 16:30:26 +0800925
926 if (!nent) {
927 dev_dbg(port->dev, "need to release resource of dma\n");
928 goto chan_err;
929 } else {
Uwe Kleine-Königc8d1f022015-09-30 10:19:38 +0200930 dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__,
Elen Song08f738b2013-07-22 16:30:26 +0800931 sg_dma_len(&atmel_port->sg_tx),
932 port->state->xmit.buf,
Uwe Kleine-Königc8d1f022015-09-30 10:19:38 +0200933 &sg_dma_address(&atmel_port->sg_tx));
Elen Song08f738b2013-07-22 16:30:26 +0800934 }
935
936 /* Configure the slave DMA */
937 memset(&config, 0, sizeof(config));
938 config.direction = DMA_MEM_TO_DEV;
Cyrille Pitchen5f258b32015-07-02 15:18:13 +0200939 config.dst_addr_width = (atmel_port->fifo_size) ?
940 DMA_SLAVE_BUSWIDTH_4_BYTES :
941 DMA_SLAVE_BUSWIDTH_1_BYTE;
Elen Song08f738b2013-07-22 16:30:26 +0800942 config.dst_addr = port->mapbase + ATMEL_US_THR;
Ludovic Desrochesa8d4e012015-04-16 16:58:12 +0200943 config.dst_maxburst = 1;
Elen Song08f738b2013-07-22 16:30:26 +0800944
Maxime Ripard5483c102014-10-22 17:43:16 +0200945 ret = dmaengine_slave_config(atmel_port->chan_tx,
946 &config);
Elen Song08f738b2013-07-22 16:30:26 +0800947 if (ret) {
948 dev_err(port->dev, "DMA tx slave configuration failed\n");
949 goto chan_err;
950 }
951
952 return 0;
953
954chan_err:
955 dev_err(port->dev, "TX channel not available, switch to pio\n");
956 atmel_port->use_dma_tx = 0;
957 if (atmel_port->chan_tx)
958 atmel_release_tx_dma(port);
959 return -EINVAL;
960}
961
Elen Song34df42f2013-07-22 16:30:27 +0800962static void atmel_complete_rx_dma(void *arg)
963{
964 struct uart_port *port = arg;
965 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
966
967 tasklet_schedule(&atmel_port->tasklet);
968}
969
970static void atmel_release_rx_dma(struct uart_port *port)
971{
972 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
973 struct dma_chan *chan = atmel_port->chan_rx;
974
975 if (chan) {
976 dmaengine_terminate_all(chan);
977 dma_release_channel(chan);
978 dma_unmap_sg(port->dev, &atmel_port->sg_rx, 1,
Wolfram Sang48479142014-07-21 11:42:04 +0200979 DMA_FROM_DEVICE);
Elen Song34df42f2013-07-22 16:30:27 +0800980 }
981
982 atmel_port->desc_rx = NULL;
983 atmel_port->chan_rx = NULL;
984 atmel_port->cookie_rx = -EINVAL;
985}
986
987static void atmel_rx_from_dma(struct uart_port *port)
988{
989 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +0200990 struct tty_port *tport = &port->state->port;
Elen Song34df42f2013-07-22 16:30:27 +0800991 struct circ_buf *ring = &atmel_port->rx_ring;
992 struct dma_chan *chan = atmel_port->chan_rx;
993 struct dma_tx_state state;
994 enum dma_status dmastat;
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +0200995 size_t count;
Elen Song34df42f2013-07-22 16:30:27 +0800996
997
998 /* Reset the UART timeout early so that we don't miss one */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +0200999 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO);
Elen Song34df42f2013-07-22 16:30:27 +08001000 dmastat = dmaengine_tx_status(chan,
1001 atmel_port->cookie_rx,
1002 &state);
1003 /* Restart a new tasklet if DMA status is error */
1004 if (dmastat == DMA_ERROR) {
1005 dev_dbg(port->dev, "Get residue error, restart tasklet\n");
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001006 atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT);
Elen Song34df42f2013-07-22 16:30:27 +08001007 tasklet_schedule(&atmel_port->tasklet);
1008 return;
1009 }
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +02001010
1011 /* CPU claims ownership of RX DMA buffer */
1012 dma_sync_sg_for_cpu(port->dev,
1013 &atmel_port->sg_rx,
1014 1,
Cyrille Pitchen485819b2014-12-09 14:31:32 +01001015 DMA_FROM_DEVICE);
Elen Song34df42f2013-07-22 16:30:27 +08001016
1017 /*
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +02001018 * ring->head points to the end of data already written by the DMA.
1019 * ring->tail points to the beginning of data to be read by the
1020 * framework.
1021 * The current transfer size should not be larger than the dma buffer
1022 * length.
Elen Song34df42f2013-07-22 16:30:27 +08001023 */
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +02001024 ring->head = sg_dma_len(&atmel_port->sg_rx) - state.residue;
1025 BUG_ON(ring->head > sg_dma_len(&atmel_port->sg_rx));
1026 /*
1027 * At this point ring->head may point to the first byte right after the
1028 * last byte of the dma buffer:
1029 * 0 <= ring->head <= sg_dma_len(&atmel_port->sg_rx)
1030 *
1031 * However ring->tail must always points inside the dma buffer:
1032 * 0 <= ring->tail <= sg_dma_len(&atmel_port->sg_rx) - 1
1033 *
1034 * Since we use a ring buffer, we have to handle the case
1035 * where head is lower than tail. In such a case, we first read from
1036 * tail to the end of the buffer then reset tail.
1037 */
1038 if (ring->head < ring->tail) {
1039 count = sg_dma_len(&atmel_port->sg_rx) - ring->tail;
Elen Song34df42f2013-07-22 16:30:27 +08001040
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +02001041 tty_insert_flip_string(tport, ring->buf + ring->tail, count);
1042 ring->tail = 0;
Elen Song34df42f2013-07-22 16:30:27 +08001043 port->icount.rx += count;
1044 }
1045
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +02001046 /* Finally we read data from tail to head */
1047 if (ring->tail < ring->head) {
1048 count = ring->head - ring->tail;
1049
1050 tty_insert_flip_string(tport, ring->buf + ring->tail, count);
1051 /* Wrap ring->head if needed */
1052 if (ring->head >= sg_dma_len(&atmel_port->sg_rx))
1053 ring->head = 0;
1054 ring->tail = ring->head;
1055 port->icount.rx += count;
1056 }
1057
1058 /* USART retreives ownership of RX DMA buffer */
1059 dma_sync_sg_for_device(port->dev,
1060 &atmel_port->sg_rx,
1061 1,
Cyrille Pitchen485819b2014-12-09 14:31:32 +01001062 DMA_FROM_DEVICE);
Cyrille Pitchen66f37aa2014-10-20 19:12:20 +02001063
1064 /*
1065 * Drop the lock here since it might end up calling
1066 * uart_start(), which takes the lock.
1067 */
1068 spin_unlock(&port->lock);
1069 tty_flip_buffer_push(tport);
1070 spin_lock(&port->lock);
1071
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001072 atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT);
Elen Song34df42f2013-07-22 16:30:27 +08001073}
1074
1075static int atmel_prepare_rx_dma(struct uart_port *port)
1076{
1077 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1078 struct dma_async_tx_descriptor *desc;
1079 dma_cap_mask_t mask;
1080 struct dma_slave_config config;
1081 struct circ_buf *ring;
1082 int ret, nent;
1083
1084 ring = &atmel_port->rx_ring;
1085
1086 dma_cap_zero(mask);
1087 dma_cap_set(DMA_CYCLIC, mask);
1088
1089 atmel_port->chan_rx = dma_request_slave_channel(port->dev, "rx");
1090 if (atmel_port->chan_rx == NULL)
1091 goto chan_err;
1092 dev_info(port->dev, "using %s for rx DMA transfers\n",
1093 dma_chan_name(atmel_port->chan_rx));
1094
1095 spin_lock_init(&atmel_port->lock_rx);
1096 sg_init_table(&atmel_port->sg_rx, 1);
1097 /* UART circular rx buffer is an aligned page. */
Leilei Zhao2c277052015-02-27 16:07:14 +08001098 BUG_ON(!PAGE_ALIGNED(ring->buf));
Elen Song34df42f2013-07-22 16:30:27 +08001099 sg_set_page(&atmel_port->sg_rx,
Cyrille Pitchen1842dc2e2014-12-09 14:31:36 +01001100 virt_to_page(ring->buf),
Leilei Zhaoa5108802015-02-27 16:07:15 +08001101 sizeof(struct atmel_uart_char) * ATMEL_SERIAL_RINGSIZE,
Uwe Kleine-Königc8d1f022015-09-30 10:19:38 +02001102 (unsigned long)ring->buf & ~PAGE_MASK);
Cyrille Pitchen1842dc2e2014-12-09 14:31:36 +01001103 nent = dma_map_sg(port->dev,
1104 &atmel_port->sg_rx,
1105 1,
1106 DMA_FROM_DEVICE);
Elen Song34df42f2013-07-22 16:30:27 +08001107
1108 if (!nent) {
1109 dev_dbg(port->dev, "need to release resource of dma\n");
1110 goto chan_err;
1111 } else {
Uwe Kleine-Königc8d1f022015-09-30 10:19:38 +02001112 dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__,
Elen Song34df42f2013-07-22 16:30:27 +08001113 sg_dma_len(&atmel_port->sg_rx),
1114 ring->buf,
Uwe Kleine-Königc8d1f022015-09-30 10:19:38 +02001115 &sg_dma_address(&atmel_port->sg_rx));
Elen Song34df42f2013-07-22 16:30:27 +08001116 }
1117
1118 /* Configure the slave DMA */
1119 memset(&config, 0, sizeof(config));
1120 config.direction = DMA_DEV_TO_MEM;
1121 config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
1122 config.src_addr = port->mapbase + ATMEL_US_RHR;
Ludovic Desrochesa8d4e012015-04-16 16:58:12 +02001123 config.src_maxburst = 1;
Elen Song34df42f2013-07-22 16:30:27 +08001124
Maxime Ripard5483c102014-10-22 17:43:16 +02001125 ret = dmaengine_slave_config(atmel_port->chan_rx,
1126 &config);
Elen Song34df42f2013-07-22 16:30:27 +08001127 if (ret) {
1128 dev_err(port->dev, "DMA rx slave configuration failed\n");
1129 goto chan_err;
1130 }
1131 /*
1132 * Prepare a cyclic dma transfer, assign 2 descriptors,
1133 * each one is half ring buffer size
1134 */
1135 desc = dmaengine_prep_dma_cyclic(atmel_port->chan_rx,
Cyrille Pitchen1842dc2e2014-12-09 14:31:36 +01001136 sg_dma_address(&atmel_port->sg_rx),
1137 sg_dma_len(&atmel_port->sg_rx),
1138 sg_dma_len(&atmel_port->sg_rx)/2,
1139 DMA_DEV_TO_MEM,
1140 DMA_PREP_INTERRUPT);
Elen Song34df42f2013-07-22 16:30:27 +08001141 desc->callback = atmel_complete_rx_dma;
1142 desc->callback_param = port;
1143 atmel_port->desc_rx = desc;
1144 atmel_port->cookie_rx = dmaengine_submit(desc);
1145
1146 return 0;
1147
1148chan_err:
1149 dev_err(port->dev, "RX channel not available, switch to pio\n");
1150 atmel_port->use_dma_rx = 0;
1151 if (atmel_port->chan_rx)
1152 atmel_release_rx_dma(port);
1153 return -EINVAL;
1154}
1155
Elen Song2e68c222013-07-22 16:30:30 +08001156static void atmel_uart_timer_callback(unsigned long data)
1157{
1158 struct uart_port *port = (void *)data;
1159 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1160
1161 tasklet_schedule(&atmel_port->tasklet);
1162 mod_timer(&atmel_port->uart_timer, jiffies + uart_poll_timeout(port));
1163}
1164
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001165/*
Remy Bohmerb843aa22008-02-08 04:21:01 -08001166 * receive interrupt handler.
1167 */
1168static void
1169atmel_handle_receive(struct uart_port *port, unsigned int pending)
1170{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001171 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Remy Bohmerb843aa22008-02-08 04:21:01 -08001172
Elen Song64e22eb2013-07-22 16:30:24 +08001173 if (atmel_use_pdc_rx(port)) {
Chip Coldwella6670612008-02-08 04:21:06 -08001174 /*
1175 * PDC receive. Just schedule the tasklet and let it
1176 * figure out the details.
1177 *
1178 * TODO: We're not handling error flags correctly at
1179 * the moment.
1180 */
1181 if (pending & (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)) {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001182 atmel_uart_writel(port, ATMEL_US_IDR,
1183 (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT));
Chip Coldwella6670612008-02-08 04:21:06 -08001184 tasklet_schedule(&atmel_port->tasklet);
1185 }
1186
1187 if (pending & (ATMEL_US_RXBRK | ATMEL_US_OVRE |
1188 ATMEL_US_FRAME | ATMEL_US_PARE))
1189 atmel_pdc_rxerr(port, pending);
1190 }
1191
Elen Song34df42f2013-07-22 16:30:27 +08001192 if (atmel_use_dma_rx(port)) {
1193 if (pending & ATMEL_US_TIMEOUT) {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001194 atmel_uart_writel(port, ATMEL_US_IDR,
1195 ATMEL_US_TIMEOUT);
Elen Song34df42f2013-07-22 16:30:27 +08001196 tasklet_schedule(&atmel_port->tasklet);
1197 }
1198 }
1199
Remy Bohmerb843aa22008-02-08 04:21:01 -08001200 /* Interrupt receive */
1201 if (pending & ATMEL_US_RXRDY)
1202 atmel_rx_chars(port);
1203 else if (pending & ATMEL_US_RXBRK) {
1204 /*
1205 * End of break detected. If it came along with a
1206 * character, atmel_rx_chars will handle it.
1207 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001208 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);
1209 atmel_uart_writel(port, ATMEL_US_IDR, ATMEL_US_RXBRK);
Remy Bohmerb843aa22008-02-08 04:21:01 -08001210 atmel_port->break_active = 0;
1211 }
1212}
1213
1214/*
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001215 * transmit interrupt handler. (Transmit is IRQF_NODELAY safe)
Remy Bohmerb843aa22008-02-08 04:21:01 -08001216 */
1217static void
1218atmel_handle_transmit(struct uart_port *port, unsigned int pending)
1219{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001220 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001221
Claudio Scordinoe8faff72010-05-03 13:31:28 +01001222 if (pending & atmel_port->tx_done_mask) {
1223 /* Either PDC or interrupt transmission */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001224 atmel_uart_writel(port, ATMEL_US_IDR,
1225 atmel_port->tx_done_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +01001226 tasklet_schedule(&atmel_port->tasklet);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001227 }
Remy Bohmerb843aa22008-02-08 04:21:01 -08001228}
1229
1230/*
1231 * status flags interrupt handler.
1232 */
1233static void
1234atmel_handle_status(struct uart_port *port, unsigned int pending,
1235 unsigned int status)
1236{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001237 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Nicolas Ferre92052182016-06-17 12:05:46 +02001238 unsigned int status_change;
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001239
Remy Bohmerb843aa22008-02-08 04:21:01 -08001240 if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001241 | ATMEL_US_CTSIC)) {
Nicolas Ferre92052182016-06-17 12:05:46 +02001242 status_change = status ^ atmel_port->irq_status_prev;
Leilei Zhaod033e822015-04-09 10:48:15 +08001243 atmel_port->irq_status_prev = status;
Nicolas Ferre92052182016-06-17 12:05:46 +02001244
1245 if (status_change & (ATMEL_US_RI | ATMEL_US_DSR
1246 | ATMEL_US_DCD | ATMEL_US_CTS)) {
1247 /* TODO: All reads to CSR will clear these interrupts! */
1248 if (status_change & ATMEL_US_RI)
1249 port->icount.rng++;
1250 if (status_change & ATMEL_US_DSR)
1251 port->icount.dsr++;
1252 if (status_change & ATMEL_US_DCD)
1253 uart_handle_dcd_change(port, !(status & ATMEL_US_DCD));
1254 if (status_change & ATMEL_US_CTS)
1255 uart_handle_cts_change(port, !(status & ATMEL_US_CTS));
1256
1257 wake_up_interruptible(&port->state->port.delta_msr_wait);
1258 }
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001259 }
Remy Bohmerb843aa22008-02-08 04:21:01 -08001260}
1261
1262/*
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001263 * Interrupt handler
1264 */
David Howells7d12e782006-10-05 14:55:46 +01001265static irqreturn_t atmel_interrupt(int irq, void *dev_id)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001266{
1267 struct uart_port *port = dev_id;
Richard Genoudab5e4e42014-05-13 20:20:45 +02001268 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001269 unsigned int status, pending, mask, pass_counter = 0;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001270
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001271 spin_lock(&atmel_port->lock_suspended);
1272
Chip Coldwella6670612008-02-08 04:21:06 -08001273 do {
Richard Genoude0b0baa2014-05-13 20:20:44 +02001274 status = atmel_get_lines_status(port);
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001275 mask = atmel_uart_readl(port, ATMEL_US_IMR);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001276 pending = status & mask;
Chip Coldwella6670612008-02-08 04:21:06 -08001277 if (!pending)
1278 break;
1279
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001280 if (atmel_port->suspended) {
1281 atmel_port->pending |= pending;
1282 atmel_port->pending_status = status;
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001283 atmel_uart_writel(port, ATMEL_US_IDR, mask);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001284 pm_system_wakeup();
1285 break;
1286 }
1287
Remy Bohmerb843aa22008-02-08 04:21:01 -08001288 atmel_handle_receive(port, pending);
1289 atmel_handle_status(port, pending, status);
1290 atmel_handle_transmit(port, pending);
Chip Coldwella6670612008-02-08 04:21:06 -08001291 } while (pass_counter++ < ATMEL_ISR_PASS_LIMIT);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001292
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001293 spin_unlock(&atmel_port->lock_suspended);
1294
Haavard Skinnemoen0400b692008-02-23 15:23:36 -08001295 return pass_counter ? IRQ_HANDLED : IRQ_NONE;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001296}
1297
Elen Songa930e522013-07-22 16:30:25 +08001298static void atmel_release_tx_pdc(struct uart_port *port)
1299{
1300 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1301 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
1302
1303 dma_unmap_single(port->dev,
1304 pdc->dma_addr,
1305 pdc->dma_size,
1306 DMA_TO_DEVICE);
1307}
1308
Chip Coldwella6670612008-02-08 04:21:06 -08001309/*
1310 * Called from tasklet with ENDTX and TXBUFE interrupts disabled.
1311 */
Elen Song64e22eb2013-07-22 16:30:24 +08001312static void atmel_tx_pdc(struct uart_port *port)
Chip Coldwella6670612008-02-08 04:21:06 -08001313{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001314 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Alan Coxebd2c8f2009-09-19 13:13:28 -07001315 struct circ_buf *xmit = &port->state->xmit;
Chip Coldwella6670612008-02-08 04:21:06 -08001316 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
1317 int count;
1318
Michael Trimarchiba0657f2008-04-02 13:04:41 -07001319 /* nothing left to transmit? */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001320 if (atmel_uart_readl(port, ATMEL_PDC_TCR))
Michael Trimarchiba0657f2008-04-02 13:04:41 -07001321 return;
1322
Chip Coldwella6670612008-02-08 04:21:06 -08001323 xmit->tail += pdc->ofs;
1324 xmit->tail &= UART_XMIT_SIZE - 1;
1325
1326 port->icount.tx += pdc->ofs;
1327 pdc->ofs = 0;
1328
Michael Trimarchiba0657f2008-04-02 13:04:41 -07001329 /* more to transmit - setup next transfer */
Chip Coldwella6670612008-02-08 04:21:06 -08001330
Michael Trimarchiba0657f2008-04-02 13:04:41 -07001331 /* disable PDC transmit */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001332 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
Michael Trimarchiba0657f2008-04-02 13:04:41 -07001333
Itai Levi1f140812009-01-15 13:50:43 -08001334 if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {
Chip Coldwella6670612008-02-08 04:21:06 -08001335 dma_sync_single_for_device(port->dev,
1336 pdc->dma_addr,
1337 pdc->dma_size,
1338 DMA_TO_DEVICE);
1339
1340 count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
1341 pdc->ofs = count;
1342
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001343 atmel_uart_writel(port, ATMEL_PDC_TPR,
1344 pdc->dma_addr + xmit->tail);
1345 atmel_uart_writel(port, ATMEL_PDC_TCR, count);
Claudio Scordinoe8faff72010-05-03 13:31:28 +01001346 /* re-enable PDC transmit */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001347 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
Claudio Scordinoe8faff72010-05-03 13:31:28 +01001348 /* Enable interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001349 atmel_uart_writel(port, ATMEL_US_IER,
1350 atmel_port->tx_done_mask);
Claudio Scordinoe8faff72010-05-03 13:31:28 +01001351 } else {
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01001352 if ((port->rs485.flags & SER_RS485_ENABLED) &&
1353 !(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
Claudio Scordinoe8faff72010-05-03 13:31:28 +01001354 /* DMA done, stop TX, start RX for RS485 */
1355 atmel_start_rx(port);
1356 }
Chip Coldwella6670612008-02-08 04:21:06 -08001357 }
1358
1359 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
1360 uart_write_wakeup(port);
1361}
1362
Elen Songa930e522013-07-22 16:30:25 +08001363static int atmel_prepare_tx_pdc(struct uart_port *port)
1364{
1365 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1366 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
1367 struct circ_buf *xmit = &port->state->xmit;
1368
1369 pdc->buf = xmit->buf;
1370 pdc->dma_addr = dma_map_single(port->dev,
1371 pdc->buf,
1372 UART_XMIT_SIZE,
1373 DMA_TO_DEVICE);
1374 pdc->dma_size = UART_XMIT_SIZE;
1375 pdc->ofs = 0;
1376
1377 return 0;
1378}
1379
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001380static void atmel_rx_from_ring(struct uart_port *port)
1381{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001382 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001383 struct circ_buf *ring = &atmel_port->rx_ring;
1384 unsigned int flg;
1385 unsigned int status;
1386
1387 while (ring->head != ring->tail) {
1388 struct atmel_uart_char c;
1389
1390 /* Make sure c is loaded after head. */
1391 smp_rmb();
1392
1393 c = ((struct atmel_uart_char *)ring->buf)[ring->tail];
1394
1395 ring->tail = (ring->tail + 1) & (ATMEL_SERIAL_RINGSIZE - 1);
1396
1397 port->icount.rx++;
1398 status = c.status;
1399 flg = TTY_NORMAL;
1400
1401 /*
1402 * note that the error handling code is
1403 * out of the main execution path
1404 */
1405 if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME
1406 | ATMEL_US_OVRE | ATMEL_US_RXBRK))) {
1407 if (status & ATMEL_US_RXBRK) {
1408 /* ignore side-effect */
1409 status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME);
1410
1411 port->icount.brk++;
1412 if (uart_handle_break(port))
1413 continue;
1414 }
1415 if (status & ATMEL_US_PARE)
1416 port->icount.parity++;
1417 if (status & ATMEL_US_FRAME)
1418 port->icount.frame++;
1419 if (status & ATMEL_US_OVRE)
1420 port->icount.overrun++;
1421
1422 status &= port->read_status_mask;
1423
1424 if (status & ATMEL_US_RXBRK)
1425 flg = TTY_BREAK;
1426 else if (status & ATMEL_US_PARE)
1427 flg = TTY_PARITY;
1428 else if (status & ATMEL_US_FRAME)
1429 flg = TTY_FRAME;
1430 }
1431
1432
1433 if (uart_handle_sysrq_char(port, c.ch))
1434 continue;
1435
1436 uart_insert_char(port, status, ATMEL_US_OVRE, c.ch, flg);
1437 }
1438
1439 /*
1440 * Drop the lock here since it might end up calling
1441 * uart_start(), which takes the lock.
1442 */
1443 spin_unlock(&port->lock);
Jiri Slaby2e124b42013-01-03 15:53:06 +01001444 tty_flip_buffer_push(&port->state->port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001445 spin_lock(&port->lock);
1446}
1447
Elen Songa930e522013-07-22 16:30:25 +08001448static void atmel_release_rx_pdc(struct uart_port *port)
1449{
1450 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1451 int i;
1452
1453 for (i = 0; i < 2; i++) {
1454 struct atmel_dma_buffer *pdc = &atmel_port->pdc_rx[i];
1455
1456 dma_unmap_single(port->dev,
1457 pdc->dma_addr,
1458 pdc->dma_size,
1459 DMA_FROM_DEVICE);
1460 kfree(pdc->buf);
1461 }
1462}
1463
Elen Song64e22eb2013-07-22 16:30:24 +08001464static void atmel_rx_from_pdc(struct uart_port *port)
Chip Coldwella6670612008-02-08 04:21:06 -08001465{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001466 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Jiri Slaby05c7cd32013-01-03 15:53:04 +01001467 struct tty_port *tport = &port->state->port;
Chip Coldwella6670612008-02-08 04:21:06 -08001468 struct atmel_dma_buffer *pdc;
1469 int rx_idx = atmel_port->pdc_rx_idx;
1470 unsigned int head;
1471 unsigned int tail;
1472 unsigned int count;
1473
1474 do {
1475 /* Reset the UART timeout early so that we don't miss one */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001476 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO);
Chip Coldwella6670612008-02-08 04:21:06 -08001477
1478 pdc = &atmel_port->pdc_rx[rx_idx];
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001479 head = atmel_uart_readl(port, ATMEL_PDC_RPR) - pdc->dma_addr;
Chip Coldwella6670612008-02-08 04:21:06 -08001480 tail = pdc->ofs;
1481
1482 /* If the PDC has switched buffers, RPR won't contain
1483 * any address within the current buffer. Since head
1484 * is unsigned, we just need a one-way comparison to
1485 * find out.
1486 *
1487 * In this case, we just need to consume the entire
1488 * buffer and resubmit it for DMA. This will clear the
1489 * ENDRX bit as well, so that we can safely re-enable
1490 * all interrupts below.
1491 */
1492 head = min(head, pdc->dma_size);
1493
1494 if (likely(head != tail)) {
1495 dma_sync_single_for_cpu(port->dev, pdc->dma_addr,
1496 pdc->dma_size, DMA_FROM_DEVICE);
1497
1498 /*
1499 * head will only wrap around when we recycle
1500 * the DMA buffer, and when that happens, we
1501 * explicitly set tail to 0. So head will
1502 * always be greater than tail.
1503 */
1504 count = head - tail;
1505
Jiri Slaby05c7cd32013-01-03 15:53:04 +01001506 tty_insert_flip_string(tport, pdc->buf + pdc->ofs,
1507 count);
Chip Coldwella6670612008-02-08 04:21:06 -08001508
1509 dma_sync_single_for_device(port->dev, pdc->dma_addr,
1510 pdc->dma_size, DMA_FROM_DEVICE);
1511
1512 port->icount.rx += count;
1513 pdc->ofs = head;
1514 }
1515
1516 /*
1517 * If the current buffer is full, we need to check if
1518 * the next one contains any additional data.
1519 */
1520 if (head >= pdc->dma_size) {
1521 pdc->ofs = 0;
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001522 atmel_uart_writel(port, ATMEL_PDC_RNPR, pdc->dma_addr);
1523 atmel_uart_writel(port, ATMEL_PDC_RNCR, pdc->dma_size);
Chip Coldwella6670612008-02-08 04:21:06 -08001524
1525 rx_idx = !rx_idx;
1526 atmel_port->pdc_rx_idx = rx_idx;
1527 }
1528 } while (head >= pdc->dma_size);
1529
1530 /*
1531 * Drop the lock here since it might end up calling
1532 * uart_start(), which takes the lock.
1533 */
1534 spin_unlock(&port->lock);
Jiri Slaby2e124b42013-01-03 15:53:06 +01001535 tty_flip_buffer_push(tport);
Chip Coldwella6670612008-02-08 04:21:06 -08001536 spin_lock(&port->lock);
1537
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001538 atmel_uart_writel(port, ATMEL_US_IER,
1539 ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
Chip Coldwella6670612008-02-08 04:21:06 -08001540}
1541
Elen Songa930e522013-07-22 16:30:25 +08001542static int atmel_prepare_rx_pdc(struct uart_port *port)
1543{
1544 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1545 int i;
1546
1547 for (i = 0; i < 2; i++) {
1548 struct atmel_dma_buffer *pdc = &atmel_port->pdc_rx[i];
1549
1550 pdc->buf = kmalloc(PDC_BUFFER_SIZE, GFP_KERNEL);
1551 if (pdc->buf == NULL) {
1552 if (i != 0) {
1553 dma_unmap_single(port->dev,
1554 atmel_port->pdc_rx[0].dma_addr,
1555 PDC_BUFFER_SIZE,
1556 DMA_FROM_DEVICE);
1557 kfree(atmel_port->pdc_rx[0].buf);
1558 }
1559 atmel_port->use_pdc_rx = 0;
1560 return -ENOMEM;
1561 }
1562 pdc->dma_addr = dma_map_single(port->dev,
1563 pdc->buf,
1564 PDC_BUFFER_SIZE,
1565 DMA_FROM_DEVICE);
1566 pdc->dma_size = PDC_BUFFER_SIZE;
1567 pdc->ofs = 0;
1568 }
1569
1570 atmel_port->pdc_rx_idx = 0;
1571
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001572 atmel_uart_writel(port, ATMEL_PDC_RPR, atmel_port->pdc_rx[0].dma_addr);
1573 atmel_uart_writel(port, ATMEL_PDC_RCR, PDC_BUFFER_SIZE);
Elen Songa930e522013-07-22 16:30:25 +08001574
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001575 atmel_uart_writel(port, ATMEL_PDC_RNPR,
1576 atmel_port->pdc_rx[1].dma_addr);
1577 atmel_uart_writel(port, ATMEL_PDC_RNCR, PDC_BUFFER_SIZE);
Elen Songa930e522013-07-22 16:30:25 +08001578
1579 return 0;
1580}
1581
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001582/*
1583 * tasklet handling tty stuff outside the interrupt handler.
1584 */
1585static void atmel_tasklet_func(unsigned long data)
1586{
1587 struct uart_port *port = (struct uart_port *)data;
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001588 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001589
1590 /* The interrupt handler does not take the lock */
1591 spin_lock(&port->lock);
1592
Elen Songa930e522013-07-22 16:30:25 +08001593 atmel_port->schedule_tx(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001594
Elen Songa930e522013-07-22 16:30:25 +08001595 atmel_port->schedule_rx(port);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08001596
1597 spin_unlock(&port->lock);
1598}
1599
Leilei Zhao4a1e8882015-02-27 16:07:16 +08001600static void atmel_init_property(struct atmel_uart_port *atmel_port,
Elen Song33d64c42013-07-22 16:30:28 +08001601 struct platform_device *pdev)
1602{
1603 struct device_node *np = pdev->dev.of_node;
Jingoo Han574de552013-07-30 17:06:57 +09001604 struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
Elen Song33d64c42013-07-22 16:30:28 +08001605
1606 if (np) {
1607 /* DMA/PDC usage specification */
1608 if (of_get_property(np, "atmel,use-dma-rx", NULL)) {
1609 if (of_get_property(np, "dmas", NULL)) {
1610 atmel_port->use_dma_rx = true;
1611 atmel_port->use_pdc_rx = false;
1612 } else {
1613 atmel_port->use_dma_rx = false;
1614 atmel_port->use_pdc_rx = true;
1615 }
1616 } else {
1617 atmel_port->use_dma_rx = false;
1618 atmel_port->use_pdc_rx = false;
1619 }
1620
1621 if (of_get_property(np, "atmel,use-dma-tx", NULL)) {
1622 if (of_get_property(np, "dmas", NULL)) {
1623 atmel_port->use_dma_tx = true;
1624 atmel_port->use_pdc_tx = false;
1625 } else {
1626 atmel_port->use_dma_tx = false;
1627 atmel_port->use_pdc_tx = true;
1628 }
1629 } else {
1630 atmel_port->use_dma_tx = false;
1631 atmel_port->use_pdc_tx = false;
1632 }
1633
1634 } else {
1635 atmel_port->use_pdc_rx = pdata->use_dma_rx;
1636 atmel_port->use_pdc_tx = pdata->use_dma_tx;
1637 atmel_port->use_dma_rx = false;
1638 atmel_port->use_dma_tx = false;
1639 }
1640
Elen Song33d64c42013-07-22 16:30:28 +08001641}
1642
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01001643static void atmel_init_rs485(struct uart_port *port,
Elen Song33d64c42013-07-22 16:30:28 +08001644 struct platform_device *pdev)
1645{
1646 struct device_node *np = pdev->dev.of_node;
Jingoo Han574de552013-07-30 17:06:57 +09001647 struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
Elen Song33d64c42013-07-22 16:30:28 +08001648
1649 if (np) {
Jiri Slaby77bdec62015-10-11 15:22:44 +02001650 struct serial_rs485 *rs485conf = &port->rs485;
Elen Song33d64c42013-07-22 16:30:28 +08001651 u32 rs485_delay[2];
1652 /* rs485 properties */
1653 if (of_property_read_u32_array(np, "rs485-rts-delay",
1654 rs485_delay, 2) == 0) {
Elen Song33d64c42013-07-22 16:30:28 +08001655 rs485conf->delay_rts_before_send = rs485_delay[0];
1656 rs485conf->delay_rts_after_send = rs485_delay[1];
1657 rs485conf->flags = 0;
Jiri Slaby77bdec62015-10-11 15:22:44 +02001658 }
Elen Song33d64c42013-07-22 16:30:28 +08001659
1660 if (of_get_property(np, "rs485-rx-during-tx", NULL))
1661 rs485conf->flags |= SER_RS485_RX_DURING_TX;
1662
1663 if (of_get_property(np, "linux,rs485-enabled-at-boot-time",
1664 NULL))
1665 rs485conf->flags |= SER_RS485_ENABLED;
Elen Song33d64c42013-07-22 16:30:28 +08001666 } else {
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01001667 port->rs485 = pdata->rs485;
Elen Song33d64c42013-07-22 16:30:28 +08001668 }
1669
1670}
1671
Elen Songa930e522013-07-22 16:30:25 +08001672static void atmel_set_ops(struct uart_port *port)
1673{
1674 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1675
Elen Song34df42f2013-07-22 16:30:27 +08001676 if (atmel_use_dma_rx(port)) {
1677 atmel_port->prepare_rx = &atmel_prepare_rx_dma;
1678 atmel_port->schedule_rx = &atmel_rx_from_dma;
1679 atmel_port->release_rx = &atmel_release_rx_dma;
1680 } else if (atmel_use_pdc_rx(port)) {
Elen Songa930e522013-07-22 16:30:25 +08001681 atmel_port->prepare_rx = &atmel_prepare_rx_pdc;
1682 atmel_port->schedule_rx = &atmel_rx_from_pdc;
1683 atmel_port->release_rx = &atmel_release_rx_pdc;
1684 } else {
1685 atmel_port->prepare_rx = NULL;
1686 atmel_port->schedule_rx = &atmel_rx_from_ring;
1687 atmel_port->release_rx = NULL;
1688 }
1689
Elen Song08f738b2013-07-22 16:30:26 +08001690 if (atmel_use_dma_tx(port)) {
1691 atmel_port->prepare_tx = &atmel_prepare_tx_dma;
1692 atmel_port->schedule_tx = &atmel_tx_dma;
1693 atmel_port->release_tx = &atmel_release_tx_dma;
1694 } else if (atmel_use_pdc_tx(port)) {
Elen Songa930e522013-07-22 16:30:25 +08001695 atmel_port->prepare_tx = &atmel_prepare_tx_pdc;
1696 atmel_port->schedule_tx = &atmel_tx_pdc;
1697 atmel_port->release_tx = &atmel_release_tx_pdc;
1698 } else {
1699 atmel_port->prepare_tx = NULL;
1700 atmel_port->schedule_tx = &atmel_tx_chars;
1701 atmel_port->release_tx = NULL;
1702 }
1703}
1704
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001705/*
Elen Song055560b2013-07-22 16:30:29 +08001706 * Get ip name usart or uart
1707 */
Nicolas Ferre892db582013-10-17 17:37:11 +02001708static void atmel_get_ip_name(struct uart_port *port)
Elen Song055560b2013-07-22 16:30:29 +08001709{
1710 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001711 int name = atmel_uart_readl(port, ATMEL_US_NAME);
Nicolas Ferre731d9ca2013-10-17 17:37:12 +02001712 u32 version;
Nicolas Ferre1d673fb2016-01-26 11:26:15 +01001713 u32 usart, dbgu_uart, new_uart;
Nicolas Ferre4b769372016-01-26 11:26:14 +01001714 /* ASCII decoding for IP version */
1715 usart = 0x55534152; /* USAR(T) */
1716 dbgu_uart = 0x44424755; /* DBGU */
Nicolas Ferre1d673fb2016-01-26 11:26:15 +01001717 new_uart = 0x55415254; /* UART */
Elen Song055560b2013-07-22 16:30:29 +08001718
Nicolas Ferre4b769372016-01-26 11:26:14 +01001719 atmel_port->has_hw_timer = false;
Elen Song055560b2013-07-22 16:30:29 +08001720
Ludovic Desroches2958cce2016-02-22 15:18:55 +01001721 if (name == new_uart) {
1722 dev_dbg(port->dev, "Uart with hw timer");
Nicolas Ferre4b769372016-01-26 11:26:14 +01001723 atmel_port->has_hw_timer = true;
Ludovic Desroches2958cce2016-02-22 15:18:55 +01001724 atmel_port->rtor = ATMEL_UA_RTOR;
1725 } else if (name == usart) {
1726 dev_dbg(port->dev, "Usart\n");
1727 atmel_port->has_hw_timer = true;
1728 atmel_port->rtor = ATMEL_US_RTOR;
Nicolas Ferre4b769372016-01-26 11:26:14 +01001729 } else if (name == dbgu_uart) {
1730 dev_dbg(port->dev, "Dbgu or uart without hw timer\n");
Elen Song055560b2013-07-22 16:30:29 +08001731 } else {
Nicolas Ferre731d9ca2013-10-17 17:37:12 +02001732 /* fallback for older SoCs: use version field */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001733 version = atmel_uart_readl(port, ATMEL_US_VERSION);
Nicolas Ferre731d9ca2013-10-17 17:37:12 +02001734 switch (version) {
1735 case 0x302:
1736 case 0x10213:
1737 dev_dbg(port->dev, "This version is usart\n");
Nicolas Ferre4b769372016-01-26 11:26:14 +01001738 atmel_port->has_hw_timer = true;
Ludovic Desroches2958cce2016-02-22 15:18:55 +01001739 atmel_port->rtor = ATMEL_US_RTOR;
Nicolas Ferre731d9ca2013-10-17 17:37:12 +02001740 break;
1741 case 0x203:
1742 case 0x10202:
1743 dev_dbg(port->dev, "This version is uart\n");
Nicolas Ferre731d9ca2013-10-17 17:37:12 +02001744 break;
1745 default:
1746 dev_err(port->dev, "Not supported ip name nor version, set to uart\n");
1747 }
Elen Song055560b2013-07-22 16:30:29 +08001748 }
Elen Song055560b2013-07-22 16:30:29 +08001749}
1750
1751/*
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001752 * Perform initialization and enable port for reception
1753 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02001754static int atmel_startup(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001755{
Elen Song33d64c42013-07-22 16:30:28 +08001756 struct platform_device *pdev = to_platform_device(port->dev);
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001757 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Alan Coxebd2c8f2009-09-19 13:13:28 -07001758 struct tty_struct *tty = port->state->port.tty;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001759 int retval;
1760
1761 /*
1762 * Ensure that no interrupts are enabled otherwise when
1763 * request_irq() is called we could get stuck trying to
1764 * handle an unexpected interrupt
1765 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001766 atmel_uart_writel(port, ATMEL_US_IDR, -1);
Richard Genoudab5e4e42014-05-13 20:20:45 +02001767 atmel_port->ms_irq_enabled = false;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001768
1769 /*
1770 * Allocate the IRQ
1771 */
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01001772 retval = request_irq(port->irq, atmel_interrupt,
1773 IRQF_SHARED | IRQF_COND_SUSPEND,
Haavard Skinnemoenae161062008-02-08 04:21:08 -08001774 tty ? tty->name : "atmel_serial", port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001775 if (retval) {
Richard Genoudddaa6032014-02-26 17:19:45 +01001776 dev_err(port->dev, "atmel_startup - Can't get irq\n");
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001777 return retval;
1778 }
1779
Leilei Zhao1e125782015-02-27 16:07:18 +08001780 tasklet_enable(&atmel_port->tasklet);
1781
Richard Genoudab5e4e42014-05-13 20:20:45 +02001782 /*
Chip Coldwella6670612008-02-08 04:21:06 -08001783 * Initialize DMA (if necessary)
1784 */
Elen Song33d64c42013-07-22 16:30:28 +08001785 atmel_init_property(atmel_port, pdev);
Leilei Zhao4d9628a2015-02-27 16:07:17 +08001786 atmel_set_ops(port);
Elen Song33d64c42013-07-22 16:30:28 +08001787
Elen Songa930e522013-07-22 16:30:25 +08001788 if (atmel_port->prepare_rx) {
1789 retval = atmel_port->prepare_rx(port);
1790 if (retval < 0)
1791 atmel_set_ops(port);
Chip Coldwella6670612008-02-08 04:21:06 -08001792 }
1793
Elen Songa930e522013-07-22 16:30:25 +08001794 if (atmel_port->prepare_tx) {
1795 retval = atmel_port->prepare_tx(port);
1796 if (retval < 0)
1797 atmel_set_ops(port);
1798 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001799
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02001800 /*
1801 * Enable FIFO when available
1802 */
1803 if (atmel_port->fifo_size) {
1804 unsigned int txrdym = ATMEL_US_ONE_DATA;
1805 unsigned int rxrdym = ATMEL_US_ONE_DATA;
1806 unsigned int fmr;
1807
1808 atmel_uart_writel(port, ATMEL_US_CR,
1809 ATMEL_US_FIFOEN |
1810 ATMEL_US_RXFCLR |
1811 ATMEL_US_TXFLCLR);
1812
Cyrille Pitchen5f258b32015-07-02 15:18:13 +02001813 if (atmel_use_dma_tx(port))
1814 txrdym = ATMEL_US_FOUR_DATA;
1815
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02001816 fmr = ATMEL_US_TXRDYM(txrdym) | ATMEL_US_RXRDYM(rxrdym);
1817 if (atmel_port->rts_high &&
1818 atmel_port->rts_low)
1819 fmr |= ATMEL_US_FRTSC |
1820 ATMEL_US_RXFTHRES(atmel_port->rts_high) |
1821 ATMEL_US_RXFTHRES2(atmel_port->rts_low);
1822
1823 atmel_uart_writel(port, ATMEL_US_FMR, fmr);
1824 }
1825
Atsushi Nemoto27c0c8e2009-02-18 14:48:28 -08001826 /* Save current CSR for comparison in atmel_tasklet_func() */
Richard Genoude0b0baa2014-05-13 20:20:44 +02001827 atmel_port->irq_status_prev = atmel_get_lines_status(port);
Atsushi Nemoto27c0c8e2009-02-18 14:48:28 -08001828
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001829 /*
1830 * Finally, enable the serial port
1831 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001832 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
Remy Bohmerb843aa22008-02-08 04:21:01 -08001833 /* enable xmit & rcvr */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001834 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
Andrew Victorafefc412006-06-19 19:53:19 +01001835
Marek Roszko8bc661b2014-01-10 10:33:11 +01001836 setup_timer(&atmel_port->uart_timer,
1837 atmel_uart_timer_callback,
1838 (unsigned long)port);
1839
Elen Song64e22eb2013-07-22 16:30:24 +08001840 if (atmel_use_pdc_rx(port)) {
Chip Coldwella6670612008-02-08 04:21:06 -08001841 /* set UART timeout */
Nicolas Ferre4b769372016-01-26 11:26:14 +01001842 if (!atmel_port->has_hw_timer) {
Elen Song2e68c222013-07-22 16:30:30 +08001843 mod_timer(&atmel_port->uart_timer,
1844 jiffies + uart_poll_timeout(port));
1845 /* set USART timeout */
1846 } else {
Ludovic Desroches2958cce2016-02-22 15:18:55 +01001847 atmel_uart_writel(port, atmel_port->rtor,
1848 PDC_RX_TIMEOUT);
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001849 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO);
Chip Coldwella6670612008-02-08 04:21:06 -08001850
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001851 atmel_uart_writel(port, ATMEL_US_IER,
1852 ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
Elen Song2e68c222013-07-22 16:30:30 +08001853 }
Chip Coldwella6670612008-02-08 04:21:06 -08001854 /* enable PDC controller */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001855 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
Elen Song34df42f2013-07-22 16:30:27 +08001856 } else if (atmel_use_dma_rx(port)) {
Elen Song2e68c222013-07-22 16:30:30 +08001857 /* set UART timeout */
Nicolas Ferre4b769372016-01-26 11:26:14 +01001858 if (!atmel_port->has_hw_timer) {
Elen Song2e68c222013-07-22 16:30:30 +08001859 mod_timer(&atmel_port->uart_timer,
1860 jiffies + uart_poll_timeout(port));
1861 /* set USART timeout */
1862 } else {
Ludovic Desroches2958cce2016-02-22 15:18:55 +01001863 atmel_uart_writel(port, atmel_port->rtor,
1864 PDC_RX_TIMEOUT);
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001865 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO);
Elen Song34df42f2013-07-22 16:30:27 +08001866
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001867 atmel_uart_writel(port, ATMEL_US_IER,
1868 ATMEL_US_TIMEOUT);
Elen Song2e68c222013-07-22 16:30:30 +08001869 }
Chip Coldwella6670612008-02-08 04:21:06 -08001870 } else {
1871 /* enable receive only */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001872 atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_RXRDY);
Chip Coldwella6670612008-02-08 04:21:06 -08001873 }
Andrew Victorafefc412006-06-19 19:53:19 +01001874
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001875 return 0;
1876}
1877
1878/*
Peter Hurley479e9b92014-10-16 16:54:18 -04001879 * Flush any TX data submitted for DMA. Called when the TX circular
1880 * buffer is reset.
1881 */
1882static void atmel_flush_buffer(struct uart_port *port)
1883{
1884 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
1885
1886 if (atmel_use_pdc_tx(port)) {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001887 atmel_uart_writel(port, ATMEL_PDC_TCR, 0);
Peter Hurley479e9b92014-10-16 16:54:18 -04001888 atmel_port->pdc_tx.ofs = 0;
1889 }
1890}
1891
1892/*
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001893 * Disable the port
1894 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02001895static void atmel_shutdown(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001896{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001897 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Marek Roszko0cc7c6c2014-01-07 11:45:06 +01001898
Chip Coldwella6670612008-02-08 04:21:06 -08001899 /*
Marek Roszko8bc661b2014-01-10 10:33:11 +01001900 * Prevent any tasklets being scheduled during
1901 * cleanup
1902 */
1903 del_timer_sync(&atmel_port->uart_timer);
1904
1905 /*
Marek Roszko0cc7c6c2014-01-07 11:45:06 +01001906 * Clear out any scheduled tasklets before
1907 * we destroy the buffers
1908 */
Leilei Zhao1e125782015-02-27 16:07:18 +08001909 tasklet_disable(&atmel_port->tasklet);
Marek Roszko0cc7c6c2014-01-07 11:45:06 +01001910 tasklet_kill(&atmel_port->tasklet);
1911
1912 /*
1913 * Ensure everything is stopped and
1914 * disable all interrupts, port and break condition.
Chip Coldwella6670612008-02-08 04:21:06 -08001915 */
1916 atmel_stop_rx(port);
1917 atmel_stop_tx(port);
1918
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001919 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA);
1920 atmel_uart_writel(port, ATMEL_US_IDR, -1);
Marek Roszko0cc7c6c2014-01-07 11:45:06 +01001921
1922
Chip Coldwella6670612008-02-08 04:21:06 -08001923 /*
1924 * Shut-down the DMA.
1925 */
Elen Songa930e522013-07-22 16:30:25 +08001926 if (atmel_port->release_rx)
1927 atmel_port->release_rx(port);
1928 if (atmel_port->release_tx)
1929 atmel_port->release_tx(port);
Chip Coldwella6670612008-02-08 04:21:06 -08001930
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001931 /*
Mark Deneenbb7e73c2014-01-07 11:45:09 +01001932 * Reset ring buffer pointers
1933 */
1934 atmel_port->rx_ring.head = 0;
1935 atmel_port->rx_ring.tail = 0;
1936
1937 /*
Richard Genoudab5e4e42014-05-13 20:20:45 +02001938 * Free the interrupts
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001939 */
1940 free_irq(port->irq, port);
Richard Genoudab5e4e42014-05-13 20:20:45 +02001941
1942 atmel_port->ms_irq_enabled = false;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001943
Peter Hurley479e9b92014-10-16 16:54:18 -04001944 atmel_flush_buffer(port);
Haavard Skinnemoen9afd5612008-07-16 21:52:46 +01001945}
1946
1947/*
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001948 * Power / Clock management.
1949 */
Remy Bohmerb843aa22008-02-08 04:21:01 -08001950static void atmel_serial_pm(struct uart_port *port, unsigned int state,
1951 unsigned int oldstate)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001952{
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08001953 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Andrew Victorafefc412006-06-19 19:53:19 +01001954
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001955 switch (state) {
Remy Bohmerb843aa22008-02-08 04:21:01 -08001956 case 0:
1957 /*
1958 * Enable the peripheral clock for this serial port.
1959 * This is called on uart_open() or a resume event.
1960 */
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02001961 clk_prepare_enable(atmel_port->clk);
Anti Sullinf05596d2008-09-22 13:57:54 -07001962
1963 /* re-enable interrupts if we disabled some on suspend */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001964 atmel_uart_writel(port, ATMEL_US_IER, atmel_port->backup_imr);
Remy Bohmerb843aa22008-02-08 04:21:01 -08001965 break;
1966 case 3:
Anti Sullinf05596d2008-09-22 13:57:54 -07001967 /* Back up the interrupt mask and disable all interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001968 atmel_port->backup_imr = atmel_uart_readl(port, ATMEL_US_IMR);
1969 atmel_uart_writel(port, ATMEL_US_IDR, -1);
Anti Sullinf05596d2008-09-22 13:57:54 -07001970
Remy Bohmerb843aa22008-02-08 04:21:01 -08001971 /*
1972 * Disable the peripheral clock for this serial port.
1973 * This is called on uart_close() or a suspend event.
1974 */
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02001975 clk_disable_unprepare(atmel_port->clk);
Remy Bohmerb843aa22008-02-08 04:21:01 -08001976 break;
1977 default:
Richard Genoudddaa6032014-02-26 17:19:45 +01001978 dev_err(port->dev, "atmel_serial: unknown pm %d\n", state);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001979 }
1980}
1981
1982/*
1983 * Change the port parameters
1984 */
Remy Bohmerb843aa22008-02-08 04:21:01 -08001985static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
1986 struct ktermios *old)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001987{
1988 unsigned long flags;
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01001989 unsigned int old_mode, mode, imr, quot, baud;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001990
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01001991 /* save the current mode register */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02001992 mode = old_mode = atmel_uart_readl(port, ATMEL_US_MR);
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01001993
1994 /* reset the mode, clock divisor, parity, stop bits and data size */
1995 mode &= ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP |
1996 ATMEL_US_PAR | ATMEL_US_USMODE);
Andrew Victor03abeac2007-05-03 12:26:24 +01001997
Remy Bohmerb843aa22008-02-08 04:21:01 -08001998 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00001999 quot = uart_get_divisor(port, baud);
2000
Remy Bohmerb843aa22008-02-08 04:21:01 -08002001 if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */
Andrew Victor03abeac2007-05-03 12:26:24 +01002002 quot /= 8;
2003 mode |= ATMEL_US_USCLKS_MCK_DIV8;
2004 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002005
2006 /* byte size */
2007 switch (termios->c_cflag & CSIZE) {
2008 case CS5:
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002009 mode |= ATMEL_US_CHRL_5;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002010 break;
2011 case CS6:
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002012 mode |= ATMEL_US_CHRL_6;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002013 break;
2014 case CS7:
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002015 mode |= ATMEL_US_CHRL_7;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002016 break;
2017 default:
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002018 mode |= ATMEL_US_CHRL_8;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002019 break;
2020 }
2021
2022 /* stop bits */
2023 if (termios->c_cflag & CSTOPB)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002024 mode |= ATMEL_US_NBSTOP_2;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002025
2026 /* parity */
2027 if (termios->c_cflag & PARENB) {
Remy Bohmerb843aa22008-02-08 04:21:01 -08002028 /* Mark or Space parity */
2029 if (termios->c_cflag & CMSPAR) {
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002030 if (termios->c_cflag & PARODD)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002031 mode |= ATMEL_US_PAR_MARK;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002032 else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002033 mode |= ATMEL_US_PAR_SPACE;
Remy Bohmerb843aa22008-02-08 04:21:01 -08002034 } else if (termios->c_cflag & PARODD)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002035 mode |= ATMEL_US_PAR_ODD;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002036 else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002037 mode |= ATMEL_US_PAR_EVEN;
Remy Bohmerb843aa22008-02-08 04:21:01 -08002038 } else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002039 mode |= ATMEL_US_PAR_NONE;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002040
2041 spin_lock_irqsave(&port->lock, flags);
2042
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002043 port->read_status_mask = ATMEL_US_OVRE;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002044 if (termios->c_iflag & INPCK)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002045 port->read_status_mask |= (ATMEL_US_FRAME | ATMEL_US_PARE);
Peter Hurleyef8b9dd2014-06-16 08:10:41 -04002046 if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002047 port->read_status_mask |= ATMEL_US_RXBRK;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002048
Elen Song64e22eb2013-07-22 16:30:24 +08002049 if (atmel_use_pdc_rx(port))
Chip Coldwella6670612008-02-08 04:21:06 -08002050 /* need to enable error interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002051 atmel_uart_writel(port, ATMEL_US_IER, port->read_status_mask);
Chip Coldwella6670612008-02-08 04:21:06 -08002052
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002053 /*
2054 * Characters to ignore
2055 */
2056 port->ignore_status_mask = 0;
2057 if (termios->c_iflag & IGNPAR)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002058 port->ignore_status_mask |= (ATMEL_US_FRAME | ATMEL_US_PARE);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002059 if (termios->c_iflag & IGNBRK) {
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002060 port->ignore_status_mask |= ATMEL_US_RXBRK;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002061 /*
2062 * If we're ignoring parity and break indicators,
2063 * ignore overruns too (for real raw support).
2064 */
2065 if (termios->c_iflag & IGNPAR)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002066 port->ignore_status_mask |= ATMEL_US_OVRE;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002067 }
Remy Bohmerb843aa22008-02-08 04:21:01 -08002068 /* TODO: Ignore all characters if CREAD is set.*/
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002069
2070 /* update the per-port timeout */
2071 uart_update_timeout(port, termios->c_cflag, baud);
2072
Haavard Skinnemoen0ccad872009-06-16 17:02:03 +01002073 /*
2074 * save/disable interrupts. The tty layer will ensure that the
2075 * transmitter is empty if requested by the caller, so there's
2076 * no need to wait for it here.
2077 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002078 imr = atmel_uart_readl(port, ATMEL_US_IMR);
2079 atmel_uart_writel(port, ATMEL_US_IDR, -1);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002080
2081 /* disable receiver and transmitter */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002082 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002083
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01002084 /* mode */
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01002085 if (port->rs485.flags & SER_RS485_ENABLED) {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002086 atmel_uart_writel(port, ATMEL_US_TTGR,
2087 port->rs485.delay_rts_after_send);
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002088 mode |= ATMEL_US_USMODE_RS485;
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01002089 } else if (termios->c_cflag & CRTSCTS) {
2090 /* RS232 with hardware handshake (RTS/CTS) */
Alexandre Belloni5be605a2016-04-12 14:51:40 +02002091 if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
2092 dev_info(port->dev, "not enabling hardware flow control because DMA is used");
2093 termios->c_cflag &= ~CRTSCTS;
2094 } else {
2095 mode |= ATMEL_US_USMODE_HWHS;
2096 }
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01002097 } else {
2098 /* RS232 without hadware handshake */
2099 mode |= ATMEL_US_USMODE_NORMAL;
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002100 }
2101
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01002102 /* set the mode, clock divisor, parity, stop bits and data size */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002103 atmel_uart_writel(port, ATMEL_US_MR, mode);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002104
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01002105 /*
2106 * when switching the mode, set the RTS line state according to the
2107 * new mode, otherwise keep the former state
2108 */
2109 if ((old_mode & ATMEL_US_USMODE) != (mode & ATMEL_US_USMODE)) {
2110 unsigned int rts_state;
2111
2112 if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) {
2113 /* let the hardware control the RTS line */
2114 rts_state = ATMEL_US_RTSDIS;
2115 } else {
2116 /* force RTS line to low level */
2117 rts_state = ATMEL_US_RTSEN;
2118 }
2119
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002120 atmel_uart_writel(port, ATMEL_US_CR, rts_state);
Cyrille Pitchen1cf6e8f2014-12-09 14:31:35 +01002121 }
2122
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002123 /* set the baud rate */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002124 atmel_uart_writel(port, ATMEL_US_BRGR, quot);
2125 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
2126 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002127
2128 /* restore interrupts */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002129 atmel_uart_writel(port, ATMEL_US_IER, imr);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002130
2131 /* CTS flow-control and modem-status interrupts */
2132 if (UART_ENABLE_MS(port, termios->c_cflag))
Richard Genoud35b675b2014-09-03 18:09:26 +02002133 atmel_enable_ms(port);
2134 else
2135 atmel_disable_ms(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002136
2137 spin_unlock_irqrestore(&port->lock, flags);
2138}
2139
Peter Hurley732a84a2014-11-05 13:11:43 -05002140static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios)
Viktar Palstsiuk42bd7a42011-02-09 15:26:13 +01002141{
Peter Hurley732a84a2014-11-05 13:11:43 -05002142 if (termios->c_line == N_PPS) {
Viktar Palstsiuk42bd7a42011-02-09 15:26:13 +01002143 port->flags |= UPF_HARDPPS_CD;
Peter Hurleyd41510c2014-11-05 13:11:44 -05002144 spin_lock_irq(&port->lock);
Viktar Palstsiuk42bd7a42011-02-09 15:26:13 +01002145 atmel_enable_ms(port);
Peter Hurleyd41510c2014-11-05 13:11:44 -05002146 spin_unlock_irq(&port->lock);
Viktar Palstsiuk42bd7a42011-02-09 15:26:13 +01002147 } else {
2148 port->flags &= ~UPF_HARDPPS_CD;
Peter Hurleycab68f82014-11-05 13:11:45 -05002149 if (!UART_ENABLE_MS(port, termios->c_cflag)) {
2150 spin_lock_irq(&port->lock);
2151 atmel_disable_ms(port);
2152 spin_unlock_irq(&port->lock);
2153 }
Viktar Palstsiuk42bd7a42011-02-09 15:26:13 +01002154 }
2155}
2156
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002157/*
2158 * Return string describing the specified port
2159 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002160static const char *atmel_type(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002161{
Haavard Skinnemoen9ab4f882006-10-04 16:02:06 +02002162 return (port->type == PORT_ATMEL) ? "ATMEL_SERIAL" : NULL;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002163}
2164
2165/*
2166 * Release the memory region(s) being used by 'port'.
2167 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002168static void atmel_release_port(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002169{
Andrew Victorafefc412006-06-19 19:53:19 +01002170 struct platform_device *pdev = to_platform_device(port->dev);
2171 int size = pdev->resource[0].end - pdev->resource[0].start + 1;
2172
2173 release_mem_region(port->mapbase, size);
2174
2175 if (port->flags & UPF_IOREMAP) {
2176 iounmap(port->membase);
2177 port->membase = NULL;
2178 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002179}
2180
2181/*
2182 * Request the memory region(s) being used by 'port'.
2183 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002184static int atmel_request_port(struct uart_port *port)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002185{
Andrew Victorafefc412006-06-19 19:53:19 +01002186 struct platform_device *pdev = to_platform_device(port->dev);
2187 int size = pdev->resource[0].end - pdev->resource[0].start + 1;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002188
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002189 if (!request_mem_region(port->mapbase, size, "atmel_serial"))
Andrew Victorafefc412006-06-19 19:53:19 +01002190 return -EBUSY;
2191
2192 if (port->flags & UPF_IOREMAP) {
2193 port->membase = ioremap(port->mapbase, size);
2194 if (port->membase == NULL) {
2195 release_mem_region(port->mapbase, size);
2196 return -ENOMEM;
2197 }
2198 }
2199
2200 return 0;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002201}
2202
2203/*
2204 * Configure/autoconfigure the port.
2205 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002206static void atmel_config_port(struct uart_port *port, int flags)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002207{
2208 if (flags & UART_CONFIG_TYPE) {
Haavard Skinnemoen9ab4f882006-10-04 16:02:06 +02002209 port->type = PORT_ATMEL;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002210 atmel_request_port(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002211 }
2212}
2213
2214/*
2215 * Verify the new serial_struct (for TIOCSSERIAL).
2216 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002217static int atmel_verify_port(struct uart_port *port, struct serial_struct *ser)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002218{
2219 int ret = 0;
Haavard Skinnemoen9ab4f882006-10-04 16:02:06 +02002220 if (ser->type != PORT_UNKNOWN && ser->type != PORT_ATMEL)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002221 ret = -EINVAL;
2222 if (port->irq != ser->irq)
2223 ret = -EINVAL;
2224 if (ser->io_type != SERIAL_IO_MEM)
2225 ret = -EINVAL;
2226 if (port->uartclk / 16 != ser->baud_base)
2227 ret = -EINVAL;
Andre Przywara270c2ad2015-10-05 18:00:52 +01002228 if (port->mapbase != (unsigned long)ser->iomem_base)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002229 ret = -EINVAL;
2230 if (port->iobase != ser->port)
2231 ret = -EINVAL;
2232 if (ser->hub6 != 0)
2233 ret = -EINVAL;
2234 return ret;
2235}
2236
Albin Tonnerre8fe2d542009-12-09 12:31:32 -08002237#ifdef CONFIG_CONSOLE_POLL
2238static int atmel_poll_get_char(struct uart_port *port)
2239{
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002240 while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_RXRDY))
Albin Tonnerre8fe2d542009-12-09 12:31:32 -08002241 cpu_relax();
2242
Cyrille Pitchena6499432015-07-30 16:33:38 +02002243 return atmel_uart_read_char(port);
Albin Tonnerre8fe2d542009-12-09 12:31:32 -08002244}
2245
2246static void atmel_poll_put_char(struct uart_port *port, unsigned char ch)
2247{
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002248 while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY))
Albin Tonnerre8fe2d542009-12-09 12:31:32 -08002249 cpu_relax();
2250
Cyrille Pitchena6499432015-07-30 16:33:38 +02002251 atmel_uart_write_char(port, ch);
Albin Tonnerre8fe2d542009-12-09 12:31:32 -08002252}
2253#endif
2254
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002255static struct uart_ops atmel_pops = {
2256 .tx_empty = atmel_tx_empty,
2257 .set_mctrl = atmel_set_mctrl,
2258 .get_mctrl = atmel_get_mctrl,
2259 .stop_tx = atmel_stop_tx,
2260 .start_tx = atmel_start_tx,
2261 .stop_rx = atmel_stop_rx,
2262 .enable_ms = atmel_enable_ms,
2263 .break_ctl = atmel_break_ctl,
2264 .startup = atmel_startup,
2265 .shutdown = atmel_shutdown,
Haavard Skinnemoen9afd5612008-07-16 21:52:46 +01002266 .flush_buffer = atmel_flush_buffer,
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002267 .set_termios = atmel_set_termios,
Viktar Palstsiuk42bd7a42011-02-09 15:26:13 +01002268 .set_ldisc = atmel_set_ldisc,
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002269 .type = atmel_type,
2270 .release_port = atmel_release_port,
2271 .request_port = atmel_request_port,
2272 .config_port = atmel_config_port,
2273 .verify_port = atmel_verify_port,
2274 .pm = atmel_serial_pm,
Albin Tonnerre8fe2d542009-12-09 12:31:32 -08002275#ifdef CONFIG_CONSOLE_POLL
2276 .poll_get_char = atmel_poll_get_char,
2277 .poll_put_char = atmel_poll_put_char,
2278#endif
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002279};
2280
Andrew Victorafefc412006-06-19 19:53:19 +01002281/*
2282 * Configure the port from the platform device resource info.
2283 */
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002284static int atmel_init_port(struct atmel_uart_port *atmel_port,
Remy Bohmerb843aa22008-02-08 04:21:01 -08002285 struct platform_device *pdev)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002286{
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002287 int ret;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002288 struct uart_port *port = &atmel_port->uart;
Jingoo Han574de552013-07-30 17:06:57 +09002289 struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002290
Leilei Zhao4a1e8882015-02-27 16:07:16 +08002291 atmel_init_property(atmel_port, pdev);
2292 atmel_set_ops(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002293
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01002294 atmel_init_rs485(port, pdev);
Elen Songa930e522013-07-22 16:30:25 +08002295
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002296 port->iotype = UPIO_MEM;
2297 port->flags = UPF_BOOT_AUTOCONF;
2298 port->ops = &atmel_pops;
2299 port->fifosize = 1;
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002300 port->dev = &pdev->dev;
Andrew Victorafefc412006-06-19 19:53:19 +01002301 port->mapbase = pdev->resource[0].start;
2302 port->irq = pdev->resource[1].start;
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01002303 port->rs485_config = atmel_config_rs485;
Andrew Victorafefc412006-06-19 19:53:19 +01002304
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08002305 tasklet_init(&atmel_port->tasklet, atmel_tasklet_func,
2306 (unsigned long)port);
Leilei Zhao1e125782015-02-27 16:07:18 +08002307 tasklet_disable(&atmel_port->tasklet);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08002308
2309 memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
2310
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +02002311 if (pdata && pdata->regs) {
Haavard Skinnemoen75d35212006-10-04 16:02:08 +02002312 /* Already mapped by setup code */
Nicolas Ferre1acfc7e2011-10-12 18:06:57 +02002313 port->membase = pdata->regs;
Nicolas Ferre588edbf2011-10-12 18:06:58 +02002314 } else {
Andrew Victorafefc412006-06-19 19:53:19 +01002315 port->flags |= UPF_IOREMAP;
2316 port->membase = NULL;
2317 }
2318
Remy Bohmerb843aa22008-02-08 04:21:01 -08002319 /* for console, the clock could already be configured */
2320 if (!atmel_port->clk) {
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002321 atmel_port->clk = clk_get(&pdev->dev, "usart");
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002322 if (IS_ERR(atmel_port->clk)) {
2323 ret = PTR_ERR(atmel_port->clk);
2324 atmel_port->clk = NULL;
2325 return ret;
2326 }
2327 ret = clk_prepare_enable(atmel_port->clk);
2328 if (ret) {
2329 clk_put(atmel_port->clk);
2330 atmel_port->clk = NULL;
2331 return ret;
2332 }
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002333 port->uartclk = clk_get_rate(atmel_port->clk);
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002334 clk_disable_unprepare(atmel_port->clk);
David Brownell06a7f052008-11-06 12:53:40 -08002335 /* only enable clock when USART is in use */
Andrew Victorafefc412006-06-19 19:53:19 +01002336 }
Chip Coldwella6670612008-02-08 04:21:06 -08002337
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002338 /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
Ricardo Ribalda Delgado13bd3e62014-11-06 09:22:56 +01002339 if (port->rs485.flags & SER_RS485_ENABLED)
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002340 atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
Elen Song64e22eb2013-07-22 16:30:24 +08002341 else if (atmel_use_pdc_tx(port)) {
Chip Coldwella6670612008-02-08 04:21:06 -08002342 port->fifosize = PDC_BUFFER_SIZE;
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002343 atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE;
2344 } else {
2345 atmel_port->tx_done_mask = ATMEL_US_TXRDY;
2346 }
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002347
2348 return 0;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002349}
2350
Jean-Christophe PLAGNIOL-VILLARD69f6a272012-02-16 00:24:07 +08002351struct platform_device *atmel_default_console_device; /* the serial console device */
2352
Haavard Skinnemoen749c4e62006-10-04 16:02:02 +02002353#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002354static void atmel_console_putchar(struct uart_port *port, int ch)
Russell Kingd3587882006-03-20 20:00:09 +00002355{
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002356 while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY))
Haavard Skinnemoen829dd812008-02-08 04:21:02 -08002357 cpu_relax();
Cyrille Pitchena6499432015-07-30 16:33:38 +02002358 atmel_uart_write_char(port, ch);
Russell Kingd3587882006-03-20 20:00:09 +00002359}
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002360
2361/*
2362 * Interrupts are disabled on entering
2363 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002364static void atmel_console_write(struct console *co, const char *s, u_int count)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002365{
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002366 struct uart_port *port = &atmel_ports[co->index].uart;
Claudio Scordinoe8faff72010-05-03 13:31:28 +01002367 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Russell Kingd3587882006-03-20 20:00:09 +00002368 unsigned int status, imr;
Marc Pignat39d4c922008-04-02 13:04:42 -07002369 unsigned int pdc_tx;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002370
2371 /*
Remy Bohmerb843aa22008-02-08 04:21:01 -08002372 * First, save IMR and then disable interrupts
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002373 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002374 imr = atmel_uart_readl(port, ATMEL_US_IMR);
2375 atmel_uart_writel(port, ATMEL_US_IDR,
2376 ATMEL_US_RXRDY | atmel_port->tx_done_mask);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002377
Marc Pignat39d4c922008-04-02 13:04:42 -07002378 /* Store PDC transmit status and disable it */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002379 pdc_tx = atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN;
2380 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
Marc Pignat39d4c922008-04-02 13:04:42 -07002381
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002382 uart_console_write(port, s, count, atmel_console_putchar);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002383
2384 /*
Remy Bohmerb843aa22008-02-08 04:21:01 -08002385 * Finally, wait for transmitter to become empty
2386 * and restore IMR
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002387 */
2388 do {
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002389 status = atmel_uart_readl(port, ATMEL_US_CSR);
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002390 } while (!(status & ATMEL_US_TXRDY));
Marc Pignat39d4c922008-04-02 13:04:42 -07002391
2392 /* Restore PDC transmit status */
2393 if (pdc_tx)
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002394 atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
Marc Pignat39d4c922008-04-02 13:04:42 -07002395
Remy Bohmerb843aa22008-02-08 04:21:01 -08002396 /* set interrupts back the way they were */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002397 atmel_uart_writel(port, ATMEL_US_IER, imr);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002398}
2399
2400/*
Remy Bohmerb843aa22008-02-08 04:21:01 -08002401 * If the port was already initialised (eg, by a boot loader),
2402 * try to determine the current setup.
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002403 */
Remy Bohmerb843aa22008-02-08 04:21:01 -08002404static void __init atmel_console_get_options(struct uart_port *port, int *baud,
2405 int *parity, int *bits)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002406{
2407 unsigned int mr, quot;
2408
Haavard Skinnemoen1c0fd822008-02-08 04:21:03 -08002409 /*
2410 * If the baud rate generator isn't running, the port wasn't
2411 * initialized by the boot loader.
2412 */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002413 quot = atmel_uart_readl(port, ATMEL_US_BRGR) & ATMEL_US_CD;
Haavard Skinnemoen1c0fd822008-02-08 04:21:03 -08002414 if (!quot)
2415 return;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002416
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002417 mr = atmel_uart_readl(port, ATMEL_US_MR) & ATMEL_US_CHRL;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002418 if (mr == ATMEL_US_CHRL_8)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002419 *bits = 8;
2420 else
2421 *bits = 7;
2422
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002423 mr = atmel_uart_readl(port, ATMEL_US_MR) & ATMEL_US_PAR;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002424 if (mr == ATMEL_US_PAR_EVEN)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002425 *parity = 'e';
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002426 else if (mr == ATMEL_US_PAR_ODD)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002427 *parity = 'o';
2428
Haavard Skinnemoen4d5e3922006-10-04 16:02:11 +02002429 /*
2430 * The serial core only rounds down when matching this to a
2431 * supported baud rate. Make sure we don't end up slightly
2432 * lower than one of those, as it would make us fall through
2433 * to a much lower baud rate than we really want.
2434 */
Haavard Skinnemoen4d5e3922006-10-04 16:02:11 +02002435 *baud = port->uartclk / (16 * (quot - 1));
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002436}
2437
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002438static int __init atmel_console_setup(struct console *co, char *options)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002439{
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002440 int ret;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002441 struct uart_port *port = &atmel_ports[co->index].uart;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002442 int baud = 115200;
2443 int bits = 8;
2444 int parity = 'n';
2445 int flow = 'n';
2446
Remy Bohmerb843aa22008-02-08 04:21:01 -08002447 if (port->membase == NULL) {
2448 /* Port not initialized yet - delay setup */
Andrew Victorafefc412006-06-19 19:53:19 +01002449 return -ENODEV;
Remy Bohmerb843aa22008-02-08 04:21:01 -08002450 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002451
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002452 ret = clk_prepare_enable(atmel_ports[co->index].clk);
2453 if (ret)
2454 return ret;
David Brownell06a7f052008-11-06 12:53:40 -08002455
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002456 atmel_uart_writel(port, ATMEL_US_IDR, -1);
2457 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
2458 atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002459
2460 if (options)
2461 uart_parse_options(options, &baud, &parity, &bits, &flow);
2462 else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002463 atmel_console_get_options(port, &baud, &parity, &bits);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002464
2465 return uart_set_options(port, co, baud, parity, bits, flow);
2466}
2467
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002468static struct uart_driver atmel_uart;
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002469
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002470static struct console atmel_console = {
2471 .name = ATMEL_DEVICENAME,
2472 .write = atmel_console_write,
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002473 .device = uart_console_device,
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002474 .setup = atmel_console_setup,
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002475 .flags = CON_PRINTBUFFER,
2476 .index = -1,
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002477 .data = &atmel_uart,
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002478};
2479
David Brownell06a7f052008-11-06 12:53:40 -08002480#define ATMEL_CONSOLE_DEVICE (&atmel_console)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002481
Andrew Victorafefc412006-06-19 19:53:19 +01002482/*
2483 * Early console initialization (before VM subsystem initialized).
2484 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002485static int __init atmel_console_init(void)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002486{
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002487 int ret;
Haavard Skinnemoen73e27982006-10-04 16:02:04 +02002488 if (atmel_default_console_device) {
Voss, Nikolaus0d0a3cc2011-08-10 14:02:29 +02002489 struct atmel_uart_data *pdata =
Jingoo Han574de552013-07-30 17:06:57 +09002490 dev_get_platdata(&atmel_default_console_device->dev);
Linus Torvaldsefb8d212011-10-26 15:11:09 +02002491 int id = pdata->num;
Jaeden Amerob78cd162016-01-26 12:34:49 +01002492 struct atmel_uart_port *atmel_port = &atmel_ports[id];
Voss, Nikolaus0d0a3cc2011-08-10 14:02:29 +02002493
Jaeden Amerob78cd162016-01-26 12:34:49 +01002494 atmel_port->backup_imr = 0;
2495 atmel_port->uart.line = id;
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002496
2497 add_preferred_console(ATMEL_DEVICENAME, id, NULL);
Jaeden Amerob78cd162016-01-26 12:34:49 +01002498 ret = atmel_init_port(atmel_port, atmel_default_console_device);
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002499 if (ret)
2500 return ret;
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002501 register_console(&atmel_console);
Andrew Victorafefc412006-06-19 19:53:19 +01002502 }
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002503
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002504 return 0;
2505}
Remy Bohmerb843aa22008-02-08 04:21:01 -08002506
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002507console_initcall(atmel_console_init);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002508
Andrew Victorafefc412006-06-19 19:53:19 +01002509/*
2510 * Late console initialization.
2511 */
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002512static int __init atmel_late_console_init(void)
Andrew Victorafefc412006-06-19 19:53:19 +01002513{
Remy Bohmerb843aa22008-02-08 04:21:01 -08002514 if (atmel_default_console_device
2515 && !(atmel_console.flags & CON_ENABLED))
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002516 register_console(&atmel_console);
Andrew Victorafefc412006-06-19 19:53:19 +01002517
2518 return 0;
2519}
Remy Bohmerb843aa22008-02-08 04:21:01 -08002520
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002521core_initcall(atmel_late_console_init);
Andrew Victorafefc412006-06-19 19:53:19 +01002522
Haavard Skinnemoendfa7f342008-02-08 04:21:04 -08002523static inline bool atmel_is_console_port(struct uart_port *port)
2524{
2525 return port->cons && port->cons->index == port->line;
2526}
2527
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002528#else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002529#define ATMEL_CONSOLE_DEVICE NULL
Haavard Skinnemoendfa7f342008-02-08 04:21:04 -08002530
2531static inline bool atmel_is_console_port(struct uart_port *port)
2532{
2533 return false;
2534}
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002535#endif
2536
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002537static struct uart_driver atmel_uart = {
Remy Bohmerb843aa22008-02-08 04:21:01 -08002538 .owner = THIS_MODULE,
2539 .driver_name = "atmel_serial",
2540 .dev_name = ATMEL_DEVICENAME,
2541 .major = SERIAL_ATMEL_MAJOR,
2542 .minor = MINOR_START,
2543 .nr = ATMEL_MAX_UART,
2544 .cons = ATMEL_CONSOLE_DEVICE,
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002545};
2546
Andrew Victorafefc412006-06-19 19:53:19 +01002547#ifdef CONFIG_PM
Haavard Skinnemoenf826caa2008-02-24 14:34:45 +01002548static bool atmel_serial_clk_will_stop(void)
2549{
2550#ifdef CONFIG_ARCH_AT91
2551 return at91_suspend_entering_slow_clock();
2552#else
2553 return false;
2554#endif
2555}
2556
Remy Bohmerb843aa22008-02-08 04:21:01 -08002557static int atmel_serial_suspend(struct platform_device *pdev,
2558 pm_message_t state)
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002559{
Andrew Victorafefc412006-06-19 19:53:19 +01002560 struct uart_port *port = platform_get_drvdata(pdev);
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08002561 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002562
Haavard Skinnemoene1c609e2008-03-14 14:54:13 +01002563 if (atmel_is_console_port(port) && console_suspend_enabled) {
2564 /* Drain the TX shifter */
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002565 while (!(atmel_uart_readl(port, ATMEL_US_CSR) &
2566 ATMEL_US_TXEMPTY))
Haavard Skinnemoene1c609e2008-03-14 14:54:13 +01002567 cpu_relax();
2568 }
2569
Anti Sullinf05596d2008-09-22 13:57:54 -07002570 /* we can not wake up if we're running on slow clock */
2571 atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01002572 if (atmel_serial_clk_will_stop()) {
2573 unsigned long flags;
2574
2575 spin_lock_irqsave(&atmel_port->lock_suspended, flags);
2576 atmel_port->suspended = true;
2577 spin_unlock_irqrestore(&atmel_port->lock_suspended, flags);
Anti Sullinf05596d2008-09-22 13:57:54 -07002578 device_set_wakeup_enable(&pdev->dev, 0);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01002579 }
Anti Sullinf05596d2008-09-22 13:57:54 -07002580
2581 uart_suspend_port(&atmel_uart, port);
Andrew Victor1e6c9c22006-01-10 16:59:27 +00002582
2583 return 0;
2584}
2585
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002586static int atmel_serial_resume(struct platform_device *pdev)
Andrew Victorafefc412006-06-19 19:53:19 +01002587{
2588 struct uart_port *port = platform_get_drvdata(pdev);
Haavard Skinnemoenc811ab82008-02-08 04:21:08 -08002589 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01002590 unsigned long flags;
2591
2592 spin_lock_irqsave(&atmel_port->lock_suspended, flags);
2593 if (atmel_port->pending) {
2594 atmel_handle_receive(port, atmel_port->pending);
2595 atmel_handle_status(port, atmel_port->pending,
2596 atmel_port->pending_status);
2597 atmel_handle_transmit(port, atmel_port->pending);
2598 atmel_port->pending = 0;
2599 }
2600 atmel_port->suspended = false;
2601 spin_unlock_irqrestore(&atmel_port->lock_suspended, flags);
Andrew Victorafefc412006-06-19 19:53:19 +01002602
Anti Sullinf05596d2008-09-22 13:57:54 -07002603 uart_resume_port(&atmel_uart, port);
2604 device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup);
Andrew Victorafefc412006-06-19 19:53:19 +01002605
2606 return 0;
2607}
2608#else
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002609#define atmel_serial_suspend NULL
2610#define atmel_serial_resume NULL
Andrew Victorafefc412006-06-19 19:53:19 +01002611#endif
2612
Jaeden Amerob78cd162016-01-26 12:34:49 +01002613static void atmel_serial_probe_fifos(struct atmel_uart_port *atmel_port,
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002614 struct platform_device *pdev)
2615{
Jaeden Amerob78cd162016-01-26 12:34:49 +01002616 atmel_port->fifo_size = 0;
2617 atmel_port->rts_low = 0;
2618 atmel_port->rts_high = 0;
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002619
2620 if (of_property_read_u32(pdev->dev.of_node,
2621 "atmel,fifo-size",
Jaeden Amerob78cd162016-01-26 12:34:49 +01002622 &atmel_port->fifo_size))
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002623 return;
2624
Jaeden Amerob78cd162016-01-26 12:34:49 +01002625 if (!atmel_port->fifo_size)
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002626 return;
2627
Jaeden Amerob78cd162016-01-26 12:34:49 +01002628 if (atmel_port->fifo_size < ATMEL_MIN_FIFO_SIZE) {
2629 atmel_port->fifo_size = 0;
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002630 dev_err(&pdev->dev, "Invalid FIFO size\n");
2631 return;
2632 }
2633
2634 /*
2635 * 0 <= rts_low <= rts_high <= fifo_size
2636 * Once their CTS line asserted by the remote peer, some x86 UARTs tend
2637 * to flush their internal TX FIFO, commonly up to 16 data, before
2638 * actually stopping to send new data. So we try to set the RTS High
2639 * Threshold to a reasonably high value respecting this 16 data
2640 * empirical rule when possible.
2641 */
Jaeden Amerob78cd162016-01-26 12:34:49 +01002642 atmel_port->rts_high = max_t(int, atmel_port->fifo_size >> 1,
2643 atmel_port->fifo_size - ATMEL_RTS_HIGH_OFFSET);
2644 atmel_port->rts_low = max_t(int, atmel_port->fifo_size >> 2,
2645 atmel_port->fifo_size - ATMEL_RTS_LOW_OFFSET);
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002646
2647 dev_info(&pdev->dev, "Using FIFO (%u data)\n",
Jaeden Amerob78cd162016-01-26 12:34:49 +01002648 atmel_port->fifo_size);
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002649 dev_dbg(&pdev->dev, "RTS High Threshold : %2u data\n",
Jaeden Amerob78cd162016-01-26 12:34:49 +01002650 atmel_port->rts_high);
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002651 dev_dbg(&pdev->dev, "RTS Low Threshold : %2u data\n",
Jaeden Amerob78cd162016-01-26 12:34:49 +01002652 atmel_port->rts_low);
Cyrille Pitchenb5199d42015-07-02 15:18:12 +02002653}
2654
Bill Pemberton9671f092012-11-19 13:21:50 -05002655static int atmel_serial_probe(struct platform_device *pdev)
Andrew Victorafefc412006-06-19 19:53:19 +01002656{
Jaeden Amerob78cd162016-01-26 12:34:49 +01002657 struct atmel_uart_port *atmel_port;
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +02002658 struct device_node *np = pdev->dev.of_node;
Jingoo Han574de552013-07-30 17:06:57 +09002659 struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08002660 void *data;
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002661 int ret = -ENODEV;
Ricardo Ribalda Delgadobd737f82014-11-06 09:23:00 +01002662 bool rs485_enabled;
Andrew Victorafefc412006-06-19 19:53:19 +01002663
Haavard Skinnemoen9d09daf2009-10-26 16:50:02 -07002664 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08002665
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +02002666 if (np)
2667 ret = of_alias_get_id(np, "serial");
2668 else
2669 if (pdata)
2670 ret = pdata->num;
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002671
2672 if (ret < 0)
Nicolas Ferre5fbe46b2011-10-12 18:07:00 +02002673 /* port id not found in platform data nor device-tree aliases:
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002674 * auto-enumerate it */
Pawel Wieczorkiewicz503bded2013-02-20 17:26:20 +01002675 ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART);
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002676
Pawel Wieczorkiewicz503bded2013-02-20 17:26:20 +01002677 if (ret >= ATMEL_MAX_UART) {
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002678 ret = -ENODEV;
2679 goto err;
2680 }
2681
Pawel Wieczorkiewicz503bded2013-02-20 17:26:20 +01002682 if (test_and_set_bit(ret, atmel_ports_in_use)) {
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002683 /* port already in use */
2684 ret = -EBUSY;
2685 goto err;
2686 }
2687
Jaeden Amerob78cd162016-01-26 12:34:49 +01002688 atmel_port = &atmel_ports[ret];
2689 atmel_port->backup_imr = 0;
2690 atmel_port->uart.line = ret;
2691 atmel_serial_probe_fifos(atmel_port, pdev);
Linus Walleij354e57f2013-11-07 10:25:55 +01002692
Jaeden Amerob78cd162016-01-26 12:34:49 +01002693 spin_lock_init(&atmel_port->lock_suspended);
Boris BREZILLON2c7af5b2015-03-02 10:18:18 +01002694
Jaeden Amerob78cd162016-01-26 12:34:49 +01002695 ret = atmel_init_port(atmel_port, pdev);
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002696 if (ret)
Cyrille Pitchen6fbb9bd2014-12-09 14:31:34 +01002697 goto err_clear_bit;
Andrew Victorafefc412006-06-19 19:53:19 +01002698
Jaeden Amerob78cd162016-01-26 12:34:49 +01002699 atmel_port->gpios = mctrl_gpio_init(&atmel_port->uart, 0);
2700 if (IS_ERR(atmel_port->gpios)) {
2701 ret = PTR_ERR(atmel_port->gpios);
Uwe Kleine-König18dfef92015-10-18 21:34:45 +02002702 goto err_clear_bit;
2703 }
2704
Jaeden Amerob78cd162016-01-26 12:34:49 +01002705 if (!atmel_use_pdc_rx(&atmel_port->uart)) {
Chip Coldwella6670612008-02-08 04:21:06 -08002706 ret = -ENOMEM;
Haavard Skinnemoen64334712008-02-08 04:21:07 -08002707 data = kmalloc(sizeof(struct atmel_uart_char)
2708 * ATMEL_SERIAL_RINGSIZE, GFP_KERNEL);
Chip Coldwella6670612008-02-08 04:21:06 -08002709 if (!data)
2710 goto err_alloc_ring;
Jaeden Amerob78cd162016-01-26 12:34:49 +01002711 atmel_port->rx_ring.buf = data;
Chip Coldwella6670612008-02-08 04:21:06 -08002712 }
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08002713
Jaeden Amerob78cd162016-01-26 12:34:49 +01002714 rs485_enabled = atmel_port->uart.rs485.flags & SER_RS485_ENABLED;
Ricardo Ribalda Delgadobd737f82014-11-06 09:23:00 +01002715
Jaeden Amerob78cd162016-01-26 12:34:49 +01002716 ret = uart_add_one_port(&atmel_uart, &atmel_port->uart);
Haavard Skinnemoendfa7f342008-02-08 04:21:04 -08002717 if (ret)
2718 goto err_add_port;
2719
Albin Tonnerre8da14b52009-07-29 15:04:18 -07002720#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
Jaeden Amerob78cd162016-01-26 12:34:49 +01002721 if (atmel_is_console_port(&atmel_port->uart)
David Brownell06a7f052008-11-06 12:53:40 -08002722 && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) {
2723 /*
2724 * The serial core enabled the clock for us, so undo
Boris BREZILLON91f8c2d2013-06-19 13:17:30 +02002725 * the clk_prepare_enable() in atmel_console_setup()
David Brownell06a7f052008-11-06 12:53:40 -08002726 */
Jaeden Amerob78cd162016-01-26 12:34:49 +01002727 clk_disable_unprepare(atmel_port->clk);
David Brownell06a7f052008-11-06 12:53:40 -08002728 }
Albin Tonnerre8da14b52009-07-29 15:04:18 -07002729#endif
David Brownell06a7f052008-11-06 12:53:40 -08002730
Haavard Skinnemoendfa7f342008-02-08 04:21:04 -08002731 device_init_wakeup(&pdev->dev, 1);
Jaeden Amerob78cd162016-01-26 12:34:49 +01002732 platform_set_drvdata(pdev, atmel_port);
Haavard Skinnemoendfa7f342008-02-08 04:21:04 -08002733
Cyrille Pitchend4f64182014-12-09 14:31:33 +01002734 /*
2735 * The peripheral clock has been disabled by atmel_init_port():
2736 * enable it before accessing I/O registers
2737 */
Jaeden Amerob78cd162016-01-26 12:34:49 +01002738 clk_prepare_enable(atmel_port->clk);
Cyrille Pitchend4f64182014-12-09 14:31:33 +01002739
Ricardo Ribalda Delgadobd737f82014-11-06 09:23:00 +01002740 if (rs485_enabled) {
Jaeden Amerob78cd162016-01-26 12:34:49 +01002741 atmel_uart_writel(&atmel_port->uart, ATMEL_US_MR,
Cyrille Pitchen4e7decd2015-07-02 15:18:11 +02002742 ATMEL_US_USMODE_NORMAL);
Jaeden Amerob78cd162016-01-26 12:34:49 +01002743 atmel_uart_writel(&atmel_port->uart, ATMEL_US_CR,
2744 ATMEL_US_RTSEN);
Claudio Scordino5dfbd1d72011-01-13 15:45:39 -08002745 }
2746
Elen Song055560b2013-07-22 16:30:29 +08002747 /*
2748 * Get port name of usart or uart
2749 */
Jaeden Amerob78cd162016-01-26 12:34:49 +01002750 atmel_get_ip_name(&atmel_port->uart);
Elen Song055560b2013-07-22 16:30:29 +08002751
Cyrille Pitchend4f64182014-12-09 14:31:33 +01002752 /*
2753 * The peripheral clock can now safely be disabled till the port
2754 * is used
2755 */
Jaeden Amerob78cd162016-01-26 12:34:49 +01002756 clk_disable_unprepare(atmel_port->clk);
Cyrille Pitchend4f64182014-12-09 14:31:33 +01002757
Haavard Skinnemoendfa7f342008-02-08 04:21:04 -08002758 return 0;
2759
2760err_add_port:
Jaeden Amerob78cd162016-01-26 12:34:49 +01002761 kfree(atmel_port->rx_ring.buf);
2762 atmel_port->rx_ring.buf = NULL;
Remy Bohmer1ecc26b2008-02-08 04:21:05 -08002763err_alloc_ring:
Jaeden Amerob78cd162016-01-26 12:34:49 +01002764 if (!atmel_is_console_port(&atmel_port->uart)) {
2765 clk_put(atmel_port->clk);
2766 atmel_port->clk = NULL;
Andrew Victorafefc412006-06-19 19:53:19 +01002767 }
Cyrille Pitchen6fbb9bd2014-12-09 14:31:34 +01002768err_clear_bit:
Jaeden Amerob78cd162016-01-26 12:34:49 +01002769 clear_bit(atmel_port->uart.line, atmel_ports_in_use);
Nicolas Ferre4cbf9f42011-10-12 18:06:59 +02002770err:
Andrew Victorafefc412006-06-19 19:53:19 +01002771 return ret;
2772}
2773
Romain Izardf4a8ab042016-02-26 11:15:04 +01002774/*
2775 * Even if the driver is not modular, it makes sense to be able to
2776 * unbind a device: there can be many bound devices, and there are
2777 * situations where dynamic binding and unbinding can be useful.
2778 *
2779 * For example, a connected device can require a specific firmware update
2780 * protocol that needs bitbanging on IO lines, but use the regular serial
2781 * port in the normal case.
2782 */
2783static int atmel_serial_remove(struct platform_device *pdev)
2784{
2785 struct uart_port *port = platform_get_drvdata(pdev);
2786 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
2787 int ret = 0;
2788
2789 tasklet_kill(&atmel_port->tasklet);
2790
2791 device_init_wakeup(&pdev->dev, 0);
2792
2793 ret = uart_remove_one_port(&atmel_uart, port);
2794
2795 kfree(atmel_port->rx_ring.buf);
2796
2797 /* "port" is allocated statically, so we shouldn't free it */
2798
2799 clear_bit(port->line, atmel_ports_in_use);
2800
2801 clk_put(atmel_port->clk);
2802 atmel_port->clk = NULL;
2803
2804 return ret;
2805}
2806
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002807static struct platform_driver atmel_serial_driver = {
2808 .probe = atmel_serial_probe,
Romain Izardf4a8ab042016-02-26 11:15:04 +01002809 .remove = atmel_serial_remove,
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002810 .suspend = atmel_serial_suspend,
2811 .resume = atmel_serial_resume,
Andrew Victorafefc412006-06-19 19:53:19 +01002812 .driver = {
Paul Gortmakerc39dfeb2015-10-18 18:21:16 -04002813 .name = "atmel_usart",
2814 .of_match_table = of_match_ptr(atmel_serial_dt_ids),
Andrew Victorafefc412006-06-19 19:53:19 +01002815 },
2816};
2817
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002818static int __init atmel_serial_init(void)
Andrew Victorafefc412006-06-19 19:53:19 +01002819{
2820 int ret;
2821
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002822 ret = uart_register_driver(&atmel_uart);
Andrew Victorafefc412006-06-19 19:53:19 +01002823 if (ret)
2824 return ret;
2825
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002826 ret = platform_driver_register(&atmel_serial_driver);
Andrew Victorafefc412006-06-19 19:53:19 +01002827 if (ret)
Haavard Skinnemoen7192f922006-10-04 16:02:05 +02002828 uart_unregister_driver(&atmel_uart);
Andrew Victorafefc412006-06-19 19:53:19 +01002829
2830 return ret;
2831}
Paul Gortmakerc39dfeb2015-10-18 18:21:16 -04002832device_initcall(atmel_serial_init);