aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/atmel_serial.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 09:11:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 09:11:09 -0400
commitefb8d21b2c6db3497655cc6a033ae8a9883e4063 (patch)
treea14a0dbb9fec3a6db5e542ba7ed4a49681706420 /drivers/tty/serial/atmel_serial.c
parent3cb603284b3d256ae9ae9e65887cee8416bfef15 (diff)
parentd208a3bf77f902283894f546b6b5383202cf7882 (diff)
Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (79 commits) TTY: serial_core: Fix crash if DCD drop during suspend tty/serial: atmel_serial: bootconsole removed from auto-enumerates Revert "TTY: call tty_driver_lookup_tty unconditionally" tty/serial: atmel_serial: add device tree support tty/serial: atmel_serial: auto-enumerate ports tty/serial: atmel_serial: whitespace and braces modifications tty/serial: atmel_serial: change platform_data variable name tty/serial: RS485 bindings for device tree TTY: call tty_driver_lookup_tty unconditionally TTY: pty, release tty in all ptmx_open fail paths TTY: make tty_add_file non-failing TTY: drop driver reference in tty_open fail path 8250_pci: Fix kernel panic when pch_uart is disabled h8300: drivers/serial/Kconfig was moved parport_pc: release IO region properly if unsupported ITE887x card is found tty: Support compat_ioctl get/set termios_locked hvc_console: display printk messages on console. TTY: snyclinkmp: forever loop in tx_load_dma_buffer() tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output tty/n_gsm: fix a bug in gsm_dlci_data_output (adaption = 2 case) ... Fix up Conflicts in: - drivers/tty/serial/8250_pci.c Trivial conflict with removed duplicate device ID - drivers/tty/serial/atmel_serial.c Annoying silly conflict between "specify the port num via platform_data" and other changes to atmel_console_init
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r--drivers/tty/serial/atmel_serial.c128
1 files changed, 111 insertions, 17 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index b922f5d2e61e..9988c0c305c2 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -33,6 +33,8 @@
33#include <linux/sysrq.h> 33#include <linux/sysrq.h>
34#include <linux/tty_flip.h> 34#include <linux/tty_flip.h>
35#include <linux/platform_device.h> 35#include <linux/platform_device.h>
36#include <linux/of.h>
37#include <linux/of_device.h>
36#include <linux/dma-mapping.h> 38#include <linux/dma-mapping.h>
37#include <linux/atmel_pdc.h> 39#include <linux/atmel_pdc.h>
38#include <linux/atmel_serial.h> 40#include <linux/atmel_serial.h>
@@ -157,11 +159,22 @@ struct atmel_uart_port {
157}; 159};
158 160
159static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; 161static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
162static unsigned long atmel_ports_in_use;
160 163
161#ifdef SUPPORT_SYSRQ 164#ifdef SUPPORT_SYSRQ
162static struct console atmel_console; 165static struct console atmel_console;
163#endif 166#endif
164 167
168#if defined(CONFIG_OF)
169static const struct of_device_id atmel_serial_dt_ids[] = {
170 { .compatible = "atmel,at91rm9200-usart" },
171 { .compatible = "atmel,at91sam9260-usart" },
172 { /* sentinel */ }
173};
174
175MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids);
176#endif
177
165static inline struct atmel_uart_port * 178static inline struct atmel_uart_port *
166to_atmel_uart_port(struct uart_port *uart) 179to_atmel_uart_port(struct uart_port *uart)
167{ 180{
@@ -339,7 +352,8 @@ static void atmel_stop_tx(struct uart_port *port)
339 /* Disable interrupts */ 352 /* Disable interrupts */
340 UART_PUT_IDR(port, atmel_port->tx_done_mask); 353 UART_PUT_IDR(port, atmel_port->tx_done_mask);
341 354
342 if (atmel_port->rs485.flags & SER_RS485_ENABLED) 355 if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
356 !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX))
343 atmel_start_rx(port); 357 atmel_start_rx(port);
344} 358}
345 359
@@ -356,7 +370,8 @@ static void atmel_start_tx(struct uart_port *port)
356 really need this.*/ 370 really need this.*/
357 return; 371 return;
358 372
359 if (atmel_port->rs485.flags & SER_RS485_ENABLED) 373 if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
374 !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX))
360 atmel_stop_rx(port); 375 atmel_stop_rx(port);
361 376
362 /* re-enable PDC transmit */ 377 /* re-enable PDC transmit */
@@ -680,7 +695,8 @@ static void atmel_tx_dma(struct uart_port *port)
680 /* Enable interrupts */ 695 /* Enable interrupts */
681 UART_PUT_IER(port, atmel_port->tx_done_mask); 696 UART_PUT_IER(port, atmel_port->tx_done_mask);
682 } else { 697 } else {
683 if (atmel_port->rs485.flags & SER_RS485_ENABLED) { 698 if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
699 !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) {
684 /* DMA done, stop TX, start RX for RS485 */ 700 /* DMA done, stop TX, start RX for RS485 */
685 atmel_start_rx(port); 701 atmel_start_rx(port);
686 } 702 }
@@ -1407,6 +1423,48 @@ static struct uart_ops atmel_pops = {
1407#endif 1423#endif
1408}; 1424};
1409 1425
1426static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
1427 struct device_node *np)
1428{
1429 u32 rs485_delay[2];
1430
1431 /* DMA/PDC usage specification */
1432 if (of_get_property(np, "atmel,use-dma-rx", NULL))
1433 atmel_port->use_dma_rx = 1;
1434 else
1435 atmel_port->use_dma_rx = 0;
1436 if (of_get_property(np, "atmel,use-dma-tx", NULL))
1437 atmel_port->use_dma_tx = 1;
1438 else
1439 atmel_port->use_dma_tx = 0;
1440
1441 /* rs485 properties */
1442 if (of_property_read_u32_array(np, "rs485-rts-delay",
1443 rs485_delay, 2) == 0) {
1444 struct serial_rs485 *rs485conf = &atmel_port->rs485;
1445
1446 rs485conf->delay_rts_before_send = rs485_delay[0];
1447 rs485conf->delay_rts_after_send = rs485_delay[1];
1448 rs485conf->flags = 0;
1449
1450 if (rs485conf->delay_rts_before_send == 0 &&
1451 rs485conf->delay_rts_after_send == 0) {
1452 rs485conf->flags |= SER_RS485_RTS_ON_SEND;
1453 } else {
1454 if (rs485conf->delay_rts_before_send)
1455 rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND;
1456 if (rs485conf->delay_rts_after_send)
1457 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
1458 }
1459
1460 if (of_get_property(np, "rs485-rx-during-tx", NULL))
1461 rs485conf->flags |= SER_RS485_RX_DURING_TX;
1462
1463 if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL))
1464 rs485conf->flags |= SER_RS485_ENABLED;
1465 }
1466}
1467
1410/* 1468/*
1411 * Configure the port from the platform device resource info. 1469 * Configure the port from the platform device resource info.
1412 */ 1470 */
@@ -1414,13 +1472,20 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1414 struct platform_device *pdev) 1472 struct platform_device *pdev)
1415{ 1473{
1416 struct uart_port *port = &atmel_port->uart; 1474 struct uart_port *port = &atmel_port->uart;
1417 struct atmel_uart_data *data = pdev->dev.platform_data; 1475 struct atmel_uart_data *pdata = pdev->dev.platform_data;
1476
1477 if (pdev->dev.of_node) {
1478 atmel_of_init_port(atmel_port, pdev->dev.of_node);
1479 } else {
1480 atmel_port->use_dma_rx = pdata->use_dma_rx;
1481 atmel_port->use_dma_tx = pdata->use_dma_tx;
1482 atmel_port->rs485 = pdata->rs485;
1483 }
1418 1484
1419 port->iotype = UPIO_MEM; 1485 port->iotype = UPIO_MEM;
1420 port->flags = UPF_BOOT_AUTOCONF; 1486 port->flags = UPF_BOOT_AUTOCONF;
1421 port->ops = &atmel_pops; 1487 port->ops = &atmel_pops;
1422 port->fifosize = 1; 1488 port->fifosize = 1;
1423 port->line = data->num;
1424 port->dev = &pdev->dev; 1489 port->dev = &pdev->dev;
1425 port->mapbase = pdev->resource[0].start; 1490 port->mapbase = pdev->resource[0].start;
1426 port->irq = pdev->resource[1].start; 1491 port->irq = pdev->resource[1].start;
@@ -1430,10 +1495,10 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1430 1495
1431 memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); 1496 memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
1432 1497
1433 if (data->regs) 1498 if (pdata && pdata->regs) {
1434 /* Already mapped by setup code */ 1499 /* Already mapped by setup code */
1435 port->membase = data->regs; 1500 port->membase = pdata->regs;
1436 else { 1501 } else {
1437 port->flags |= UPF_IOREMAP; 1502 port->flags |= UPF_IOREMAP;
1438 port->membase = NULL; 1503 port->membase = NULL;
1439 } 1504 }
@@ -1447,9 +1512,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1447 /* only enable clock when USART is in use */ 1512 /* only enable clock when USART is in use */
1448 } 1513 }
1449 1514
1450 atmel_port->use_dma_rx = data->use_dma_rx;
1451 atmel_port->use_dma_tx = data->use_dma_tx;
1452 atmel_port->rs485 = data->rs485;
1453 /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ 1515 /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
1454 if (atmel_port->rs485.flags & SER_RS485_ENABLED) 1516 if (atmel_port->rs485.flags & SER_RS485_ENABLED)
1455 atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; 1517 atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
@@ -1611,10 +1673,14 @@ static int __init atmel_console_init(void)
1611 if (atmel_default_console_device) { 1673 if (atmel_default_console_device) {
1612 struct atmel_uart_data *pdata = 1674 struct atmel_uart_data *pdata =
1613 atmel_default_console_device->dev.platform_data; 1675 atmel_default_console_device->dev.platform_data;
1676 int id = pdata->num;
1677 struct atmel_uart_port *port = &atmel_ports[id];
1678
1679 port->backup_imr = 0;
1680 port->uart.line = id;
1614 1681
1615 add_preferred_console(ATMEL_DEVICENAME, pdata->num, NULL); 1682 add_preferred_console(ATMEL_DEVICENAME, id, NULL);
1616 atmel_init_port(&atmel_ports[pdata->num], 1683 atmel_init_port(port, atmel_default_console_device);
1617 atmel_default_console_device);
1618 register_console(&atmel_console); 1684 register_console(&atmel_console);
1619 } 1685 }
1620 1686
@@ -1711,14 +1777,39 @@ static int atmel_serial_resume(struct platform_device *pdev)
1711static int __devinit atmel_serial_probe(struct platform_device *pdev) 1777static int __devinit atmel_serial_probe(struct platform_device *pdev)
1712{ 1778{
1713 struct atmel_uart_port *port; 1779 struct atmel_uart_port *port;
1780 struct device_node *np = pdev->dev.of_node;
1714 struct atmel_uart_data *pdata = pdev->dev.platform_data; 1781 struct atmel_uart_data *pdata = pdev->dev.platform_data;
1715 void *data; 1782 void *data;
1716 int ret; 1783 int ret = -ENODEV;
1717 1784
1718 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); 1785 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
1719 1786
1720 port = &atmel_ports[pdata->num]; 1787 if (np)
1788 ret = of_alias_get_id(np, "serial");
1789 else
1790 if (pdata)
1791 ret = pdata->num;
1792
1793 if (ret < 0)
1794 /* port id not found in platform data nor device-tree aliases:
1795 * auto-enumerate it */
1796 ret = find_first_zero_bit(&atmel_ports_in_use,
1797 sizeof(atmel_ports_in_use));
1798
1799 if (ret > ATMEL_MAX_UART) {
1800 ret = -ENODEV;
1801 goto err;
1802 }
1803
1804 if (test_and_set_bit(ret, &atmel_ports_in_use)) {
1805 /* port already in use */
1806 ret = -EBUSY;
1807 goto err;
1808 }
1809
1810 port = &atmel_ports[ret];
1721 port->backup_imr = 0; 1811 port->backup_imr = 0;
1812 port->uart.line = ret;
1722 1813
1723 atmel_init_port(port, pdev); 1814 atmel_init_port(port, pdev);
1724 1815
@@ -1764,7 +1855,7 @@ err_alloc_ring:
1764 clk_put(port->clk); 1855 clk_put(port->clk);
1765 port->clk = NULL; 1856 port->clk = NULL;
1766 } 1857 }
1767 1858err:
1768 return ret; 1859 return ret;
1769} 1860}
1770 1861
@@ -1784,6 +1875,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
1784 1875
1785 /* "port" is allocated statically, so we shouldn't free it */ 1876 /* "port" is allocated statically, so we shouldn't free it */
1786 1877
1878 clear_bit(port->line, &atmel_ports_in_use);
1879
1787 clk_put(atmel_port->clk); 1880 clk_put(atmel_port->clk);
1788 1881
1789 return ret; 1882 return ret;
@@ -1797,6 +1890,7 @@ static struct platform_driver atmel_serial_driver = {
1797 .driver = { 1890 .driver = {
1798 .name = "atmel_usart", 1891 .name = "atmel_usart",
1799 .owner = THIS_MODULE, 1892 .owner = THIS_MODULE,
1893 .of_match_table = of_match_ptr(atmel_serial_dt_ids),
1800 }, 1894 },
1801}; 1895};
1802 1896