diff options
author | Claudio Scordino <claudio@evidence.eu.com> | 2010-05-03 08:31:28 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-05-04 11:59:11 -0400 |
commit | e8faff7330a3501eafc9bfe5f4f15af444be29f5 (patch) | |
tree | f0348e3831698baed6cc122972b8239bd155ecdf /drivers/serial/atmel_serial.c | |
parent | aec9562f3db8ece218125042e0b2b7ac5b7091e7 (diff) |
ARM: 6092/1: atmel_serial: support for RS485 communications
Final version of the patch that adds support for RS485 communications to the atmel_serial driver.
The patch has been already sent and discussed on both linux-kernel and linux-arm-kernel mailing lists several times.
Many people collaborated to improve and test the code:
Tested-by: Sebastian Heutling <Sebastian.Heutling@who-ing.de>
Tested-by: Bernhard Roth <br@pwrnet.de>
Reviewed-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Claudio Scordino <claudio@evidence.eu.com>
Signed-off-by: Michael Trimarchi <michael@evidence.eu.com>
Signed-off-by: Rick Bronson <rick@efn.org>
Signed-off-by: Sebastian Heutling <Sebastian.Heutling@who-ing.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/serial/atmel_serial.c')
-rw-r--r-- | drivers/serial/atmel_serial.c | 207 |
1 files changed, 173 insertions, 34 deletions
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 2c9bf9b68327..eed3c2d8dd1c 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/dma-mapping.h> | 38 | #include <linux/dma-mapping.h> |
39 | #include <linux/atmel_pdc.h> | 39 | #include <linux/atmel_pdc.h> |
40 | #include <linux/atmel_serial.h> | 40 | #include <linux/atmel_serial.h> |
41 | #include <linux/uaccess.h> | ||
41 | 42 | ||
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
43 | 44 | ||
@@ -59,6 +60,9 @@ | |||
59 | 60 | ||
60 | #include <linux/serial_core.h> | 61 | #include <linux/serial_core.h> |
61 | 62 | ||
63 | static void atmel_start_rx(struct uart_port *port); | ||
64 | static void atmel_stop_rx(struct uart_port *port); | ||
65 | |||
62 | #ifdef CONFIG_SERIAL_ATMEL_TTYAT | 66 | #ifdef CONFIG_SERIAL_ATMEL_TTYAT |
63 | 67 | ||
64 | /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we | 68 | /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we |
@@ -93,6 +97,7 @@ | |||
93 | #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) | 97 | #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) |
94 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) | 98 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) |
95 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) | 99 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) |
100 | #define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR) | ||
96 | 101 | ||
97 | /* PDC registers */ | 102 | /* PDC registers */ |
98 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) | 103 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) |
@@ -147,6 +152,9 @@ struct atmel_uart_port { | |||
147 | unsigned int irq_status_prev; | 152 | unsigned int irq_status_prev; |
148 | 153 | ||
149 | struct circ_buf rx_ring; | 154 | struct circ_buf rx_ring; |
155 | |||
156 | struct serial_rs485 rs485; /* rs485 settings */ | ||
157 | unsigned int tx_done_mask; | ||
150 | }; | 158 | }; |
151 | 159 | ||
152 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; | 160 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; |
@@ -187,6 +195,46 @@ static bool atmel_use_dma_tx(struct uart_port *port) | |||
187 | } | 195 | } |
188 | #endif | 196 | #endif |
189 | 197 | ||
198 | /* Enable or disable the rs485 support */ | ||
199 | void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | ||
200 | { | ||
201 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
202 | unsigned int mode; | ||
203 | |||
204 | spin_lock(&port->lock); | ||
205 | |||
206 | /* Disable interrupts */ | ||
207 | UART_PUT_IDR(port, atmel_port->tx_done_mask); | ||
208 | |||
209 | mode = UART_GET_MR(port); | ||
210 | |||
211 | /* Resetting serial mode to RS232 (0x0) */ | ||
212 | mode &= ~ATMEL_US_USMODE; | ||
213 | |||
214 | atmel_port->rs485 = *rs485conf; | ||
215 | |||
216 | if (rs485conf->flags & SER_RS485_ENABLED) { | ||
217 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
218 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | ||
219 | UART_PUT_TTGR(port, rs485conf->delay_rts_before_send); | ||
220 | mode |= ATMEL_US_USMODE_RS485; | ||
221 | } else { | ||
222 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
223 | if (atmel_use_dma_tx(port)) | ||
224 | atmel_port->tx_done_mask = ATMEL_US_ENDTX | | ||
225 | ATMEL_US_TXBUFE; | ||
226 | else | ||
227 | atmel_port->tx_done_mask = ATMEL_US_TXRDY; | ||
228 | } | ||
229 | UART_PUT_MR(port, mode); | ||
230 | |||
231 | /* Enable interrupts */ | ||
232 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
233 | |||
234 | spin_unlock(&port->lock); | ||
235 | |||
236 | } | ||
237 | |||
190 | /* | 238 | /* |
191 | * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. | 239 | * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. |
192 | */ | 240 | */ |
@@ -202,6 +250,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
202 | { | 250 | { |
203 | unsigned int control = 0; | 251 | unsigned int control = 0; |
204 | unsigned int mode; | 252 | unsigned int mode; |
253 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
205 | 254 | ||
206 | #ifdef CONFIG_ARCH_AT91RM9200 | 255 | #ifdef CONFIG_ARCH_AT91RM9200 |
207 | if (cpu_is_at91rm9200()) { | 256 | if (cpu_is_at91rm9200()) { |
@@ -236,6 +285,17 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
236 | mode |= ATMEL_US_CHMODE_LOC_LOOP; | 285 | mode |= ATMEL_US_CHMODE_LOC_LOOP; |
237 | else | 286 | else |
238 | mode |= ATMEL_US_CHMODE_NORMAL; | 287 | mode |= ATMEL_US_CHMODE_NORMAL; |
288 | |||
289 | /* Resetting serial mode to RS232 (0x0) */ | ||
290 | mode &= ~ATMEL_US_USMODE; | ||
291 | |||
292 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
293 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
294 | UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); | ||
295 | mode |= ATMEL_US_USMODE_RS485; | ||
296 | } else { | ||
297 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
298 | } | ||
239 | UART_PUT_MR(port, mode); | 299 | UART_PUT_MR(port, mode); |
240 | } | 300 | } |
241 | 301 | ||
@@ -268,12 +328,17 @@ static u_int atmel_get_mctrl(struct uart_port *port) | |||
268 | */ | 328 | */ |
269 | static void atmel_stop_tx(struct uart_port *port) | 329 | static void atmel_stop_tx(struct uart_port *port) |
270 | { | 330 | { |
331 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
332 | |||
271 | if (atmel_use_dma_tx(port)) { | 333 | if (atmel_use_dma_tx(port)) { |
272 | /* disable PDC transmit */ | 334 | /* disable PDC transmit */ |
273 | UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); | 335 | UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); |
274 | UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 336 | } |
275 | } else | 337 | /* Disable interrupts */ |
276 | UART_PUT_IDR(port, ATMEL_US_TXRDY); | 338 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
339 | |||
340 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | ||
341 | atmel_start_rx(port); | ||
277 | } | 342 | } |
278 | 343 | ||
279 | /* | 344 | /* |
@@ -281,17 +346,39 @@ static void atmel_stop_tx(struct uart_port *port) | |||
281 | */ | 346 | */ |
282 | static void atmel_start_tx(struct uart_port *port) | 347 | static void atmel_start_tx(struct uart_port *port) |
283 | { | 348 | { |
349 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
350 | |||
284 | if (atmel_use_dma_tx(port)) { | 351 | if (atmel_use_dma_tx(port)) { |
285 | if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) | 352 | if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) |
286 | /* The transmitter is already running. Yes, we | 353 | /* The transmitter is already running. Yes, we |
287 | really need this.*/ | 354 | really need this.*/ |
288 | return; | 355 | return; |
289 | 356 | ||
290 | UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 357 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) |
358 | atmel_stop_rx(port); | ||
359 | |||
291 | /* re-enable PDC transmit */ | 360 | /* re-enable PDC transmit */ |
292 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); | 361 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); |
293 | } else | 362 | } |
294 | UART_PUT_IER(port, ATMEL_US_TXRDY); | 363 | /* Enable interrupts */ |
364 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * start receiving - port is in process of being opened. | ||
369 | */ | ||
370 | static void atmel_start_rx(struct uart_port *port) | ||
371 | { | ||
372 | UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ | ||
373 | |||
374 | if (atmel_use_dma_rx(port)) { | ||
375 | /* enable PDC controller */ | ||
376 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | | ||
377 | port->read_status_mask); | ||
378 | UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); | ||
379 | } else { | ||
380 | UART_PUT_IER(port, ATMEL_US_RXRDY); | ||
381 | } | ||
295 | } | 382 | } |
296 | 383 | ||
297 | /* | 384 | /* |
@@ -302,9 +389,11 @@ static void atmel_stop_rx(struct uart_port *port) | |||
302 | if (atmel_use_dma_rx(port)) { | 389 | if (atmel_use_dma_rx(port)) { |
303 | /* disable PDC receive */ | 390 | /* disable PDC receive */ |
304 | UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); | 391 | UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); |
305 | UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); | 392 | UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | |
306 | } else | 393 | port->read_status_mask); |
394 | } else { | ||
307 | UART_PUT_IDR(port, ATMEL_US_RXRDY); | 395 | UART_PUT_IDR(port, ATMEL_US_RXRDY); |
396 | } | ||
308 | } | 397 | } |
309 | 398 | ||
310 | /* | 399 | /* |
@@ -428,8 +517,9 @@ static void atmel_rx_chars(struct uart_port *port) | |||
428 | static void atmel_tx_chars(struct uart_port *port) | 517 | static void atmel_tx_chars(struct uart_port *port) |
429 | { | 518 | { |
430 | struct circ_buf *xmit = &port->state->xmit; | 519 | struct circ_buf *xmit = &port->state->xmit; |
520 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
431 | 521 | ||
432 | if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) { | 522 | if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) { |
433 | UART_PUT_CHAR(port, port->x_char); | 523 | UART_PUT_CHAR(port, port->x_char); |
434 | port->icount.tx++; | 524 | port->icount.tx++; |
435 | port->x_char = 0; | 525 | port->x_char = 0; |
@@ -437,7 +527,7 @@ static void atmel_tx_chars(struct uart_port *port) | |||
437 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 527 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
438 | return; | 528 | return; |
439 | 529 | ||
440 | while (UART_GET_CSR(port) & ATMEL_US_TXRDY) { | 530 | while (UART_GET_CSR(port) & atmel_port->tx_done_mask) { |
441 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); | 531 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); |
442 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 532 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
443 | port->icount.tx++; | 533 | port->icount.tx++; |
@@ -449,7 +539,8 @@ static void atmel_tx_chars(struct uart_port *port) | |||
449 | uart_write_wakeup(port); | 539 | uart_write_wakeup(port); |
450 | 540 | ||
451 | if (!uart_circ_empty(xmit)) | 541 | if (!uart_circ_empty(xmit)) |
452 | UART_PUT_IER(port, ATMEL_US_TXRDY); | 542 | /* Enable interrupts */ |
543 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
453 | } | 544 | } |
454 | 545 | ||
455 | /* | 546 | /* |
@@ -501,18 +592,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) | |||
501 | { | 592 | { |
502 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 593 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
503 | 594 | ||
504 | if (atmel_use_dma_tx(port)) { | 595 | if (pending & atmel_port->tx_done_mask) { |
505 | /* PDC transmit */ | 596 | /* Either PDC or interrupt transmission */ |
506 | if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) { | 597 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
507 | UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 598 | tasklet_schedule(&atmel_port->tasklet); |
508 | tasklet_schedule(&atmel_port->tasklet); | ||
509 | } | ||
510 | } else { | ||
511 | /* Interrupt transmit */ | ||
512 | if (pending & ATMEL_US_TXRDY) { | ||
513 | UART_PUT_IDR(port, ATMEL_US_TXRDY); | ||
514 | tasklet_schedule(&atmel_port->tasklet); | ||
515 | } | ||
516 | } | 599 | } |
517 | } | 600 | } |
518 | 601 | ||
@@ -590,9 +673,15 @@ static void atmel_tx_dma(struct uart_port *port) | |||
590 | 673 | ||
591 | UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); | 674 | UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); |
592 | UART_PUT_TCR(port, count); | 675 | UART_PUT_TCR(port, count); |
593 | /* re-enable PDC transmit and interrupts */ | 676 | /* re-enable PDC transmit */ |
594 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); | 677 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); |
595 | UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 678 | /* Enable interrupts */ |
679 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
680 | } else { | ||
681 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
682 | /* DMA done, stop TX, start RX for RS485 */ | ||
683 | atmel_start_rx(port); | ||
684 | } | ||
596 | } | 685 | } |
597 | 686 | ||
598 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 687 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -1017,6 +1106,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1017 | { | 1106 | { |
1018 | unsigned long flags; | 1107 | unsigned long flags; |
1019 | unsigned int mode, imr, quot, baud; | 1108 | unsigned int mode, imr, quot, baud; |
1109 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1020 | 1110 | ||
1021 | /* Get current mode register */ | 1111 | /* Get current mode register */ |
1022 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | 1112 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL |
@@ -1115,6 +1205,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1115 | /* disable receiver and transmitter */ | 1205 | /* disable receiver and transmitter */ |
1116 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); | 1206 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); |
1117 | 1207 | ||
1208 | /* Resetting serial mode to RS232 (0x0) */ | ||
1209 | mode &= ~ATMEL_US_USMODE; | ||
1210 | |||
1211 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
1212 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
1213 | UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); | ||
1214 | mode |= ATMEL_US_USMODE_RS485; | ||
1215 | } else { | ||
1216 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
1217 | } | ||
1218 | |||
1118 | /* set the parity, stop bits and data size */ | 1219 | /* set the parity, stop bits and data size */ |
1119 | UART_PUT_MR(port, mode); | 1220 | UART_PUT_MR(port, mode); |
1120 | 1221 | ||
@@ -1231,6 +1332,35 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) | |||
1231 | } | 1332 | } |
1232 | #endif | 1333 | #endif |
1233 | 1334 | ||
1335 | static int | ||
1336 | atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) | ||
1337 | { | ||
1338 | struct serial_rs485 rs485conf; | ||
1339 | |||
1340 | switch (cmd) { | ||
1341 | case TIOCSRS485: | ||
1342 | if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, | ||
1343 | sizeof(rs485conf))) | ||
1344 | return -EFAULT; | ||
1345 | |||
1346 | atmel_config_rs485(port, &rs485conf); | ||
1347 | break; | ||
1348 | |||
1349 | case TIOCGRS485: | ||
1350 | if (copy_to_user((struct serial_rs485 *) arg, | ||
1351 | &(to_atmel_uart_port(port)->rs485), | ||
1352 | sizeof(rs485conf))) | ||
1353 | return -EFAULT; | ||
1354 | break; | ||
1355 | |||
1356 | default: | ||
1357 | return -ENOIOCTLCMD; | ||
1358 | } | ||
1359 | return 0; | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | |||
1234 | static struct uart_ops atmel_pops = { | 1364 | static struct uart_ops atmel_pops = { |
1235 | .tx_empty = atmel_tx_empty, | 1365 | .tx_empty = atmel_tx_empty, |
1236 | .set_mctrl = atmel_set_mctrl, | 1366 | .set_mctrl = atmel_set_mctrl, |
@@ -1250,6 +1380,7 @@ static struct uart_ops atmel_pops = { | |||
1250 | .config_port = atmel_config_port, | 1380 | .config_port = atmel_config_port, |
1251 | .verify_port = atmel_verify_port, | 1381 | .verify_port = atmel_verify_port, |
1252 | .pm = atmel_serial_pm, | 1382 | .pm = atmel_serial_pm, |
1383 | .ioctl = atmel_ioctl, | ||
1253 | #ifdef CONFIG_CONSOLE_POLL | 1384 | #ifdef CONFIG_CONSOLE_POLL |
1254 | .poll_get_char = atmel_poll_get_char, | 1385 | .poll_get_char = atmel_poll_get_char, |
1255 | .poll_put_char = atmel_poll_put_char, | 1386 | .poll_put_char = atmel_poll_put_char, |
@@ -1265,13 +1396,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1265 | struct uart_port *port = &atmel_port->uart; | 1396 | struct uart_port *port = &atmel_port->uart; |
1266 | struct atmel_uart_data *data = pdev->dev.platform_data; | 1397 | struct atmel_uart_data *data = pdev->dev.platform_data; |
1267 | 1398 | ||
1268 | port->iotype = UPIO_MEM; | 1399 | port->iotype = UPIO_MEM; |
1269 | port->flags = UPF_BOOT_AUTOCONF; | 1400 | port->flags = UPF_BOOT_AUTOCONF; |
1270 | port->ops = &atmel_pops; | 1401 | port->ops = &atmel_pops; |
1271 | port->fifosize = 1; | 1402 | port->fifosize = 1; |
1272 | port->line = pdev->id; | 1403 | port->line = pdev->id; |
1273 | port->dev = &pdev->dev; | 1404 | port->dev = &pdev->dev; |
1274 | |||
1275 | port->mapbase = pdev->resource[0].start; | 1405 | port->mapbase = pdev->resource[0].start; |
1276 | port->irq = pdev->resource[1].start; | 1406 | port->irq = pdev->resource[1].start; |
1277 | 1407 | ||
@@ -1299,8 +1429,16 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1299 | 1429 | ||
1300 | atmel_port->use_dma_rx = data->use_dma_rx; | 1430 | atmel_port->use_dma_rx = data->use_dma_rx; |
1301 | atmel_port->use_dma_tx = data->use_dma_tx; | 1431 | atmel_port->use_dma_tx = data->use_dma_tx; |
1302 | if (atmel_use_dma_tx(port)) | 1432 | atmel_port->rs485 = data->rs485; |
1433 | /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ | ||
1434 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | ||
1435 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | ||
1436 | else if (atmel_use_dma_tx(port)) { | ||
1303 | port->fifosize = PDC_BUFFER_SIZE; | 1437 | port->fifosize = PDC_BUFFER_SIZE; |
1438 | atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE; | ||
1439 | } else { | ||
1440 | atmel_port->tx_done_mask = ATMEL_US_TXRDY; | ||
1441 | } | ||
1304 | } | 1442 | } |
1305 | 1443 | ||
1306 | /* | 1444 | /* |
@@ -1334,6 +1472,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch) | |||
1334 | static void atmel_console_write(struct console *co, const char *s, u_int count) | 1472 | static void atmel_console_write(struct console *co, const char *s, u_int count) |
1335 | { | 1473 | { |
1336 | struct uart_port *port = &atmel_ports[co->index].uart; | 1474 | struct uart_port *port = &atmel_ports[co->index].uart; |
1475 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1337 | unsigned int status, imr; | 1476 | unsigned int status, imr; |
1338 | unsigned int pdc_tx; | 1477 | unsigned int pdc_tx; |
1339 | 1478 | ||
@@ -1341,7 +1480,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) | |||
1341 | * First, save IMR and then disable interrupts | 1480 | * First, save IMR and then disable interrupts |
1342 | */ | 1481 | */ |
1343 | imr = UART_GET_IMR(port); | 1482 | imr = UART_GET_IMR(port); |
1344 | UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); | 1483 | UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask); |
1345 | 1484 | ||
1346 | /* Store PDC transmit status and disable it */ | 1485 | /* Store PDC transmit status and disable it */ |
1347 | pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; | 1486 | pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; |