aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2011-10-12 12:07:00 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-18 19:42:08 -0400
commit5fbe46b67680c27aeb56228dab8cfe25f8f8f83d (patch)
tree0758fc1a8d70fb46705bdd35f92c83acf8b653aa /drivers/tty
parent4cbf9f4864bd4fb2e64d555aacb93c24478e4e8d (diff)
tty/serial: atmel_serial: add device tree support
Will use aliases to enumerate ports, if available. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/atmel_serial.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 10743297a001..fc4081ead727 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>
@@ -163,6 +165,16 @@ static unsigned long atmel_ports_in_use;
163static struct console atmel_console; 165static struct console atmel_console;
164#endif 166#endif
165 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
166static inline struct atmel_uart_port * 178static inline struct atmel_uart_port *
167to_atmel_uart_port(struct uart_port *uart) 179to_atmel_uart_port(struct uart_port *uart)
168{ 180{
@@ -1411,6 +1423,48 @@ static struct uart_ops atmel_pops = {
1411#endif 1423#endif
1412}; 1424};
1413 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
1414/* 1468/*
1415 * Configure the port from the platform device resource info. 1469 * Configure the port from the platform device resource info.
1416 */ 1470 */
@@ -1420,6 +1474,14 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1420 struct uart_port *port = &atmel_port->uart; 1474 struct uart_port *port = &atmel_port->uart;
1421 struct atmel_uart_data *pdata = pdev->dev.platform_data; 1475 struct atmel_uart_data *pdata = pdev->dev.platform_data;
1422 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 }
1484
1423 port->iotype = UPIO_MEM; 1485 port->iotype = UPIO_MEM;
1424 port->flags = UPF_BOOT_AUTOCONF; 1486 port->flags = UPF_BOOT_AUTOCONF;
1425 port->ops = &atmel_pops; 1487 port->ops = &atmel_pops;
@@ -1433,7 +1495,7 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1433 1495
1434 memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); 1496 memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
1435 1497
1436 if (pdata->regs) { 1498 if (pdata && pdata->regs) {
1437 /* Already mapped by setup code */ 1499 /* Already mapped by setup code */
1438 port->membase = pdata->regs; 1500 port->membase = pdata->regs;
1439 } else { 1501 } else {
@@ -1450,10 +1512,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1450 /* only enable clock when USART is in use */ 1512 /* only enable clock when USART is in use */
1451 } 1513 }
1452 1514
1453 atmel_port->use_dma_rx = pdata->use_dma_rx;
1454 atmel_port->use_dma_tx = pdata->use_dma_tx;
1455 atmel_port->rs485 = pdata->rs485;
1456
1457 /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ 1515 /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
1458 if (atmel_port->rs485.flags & SER_RS485_ENABLED) 1516 if (atmel_port->rs485.flags & SER_RS485_ENABLED)
1459 atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; 1517 atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
@@ -1718,17 +1776,21 @@ static int atmel_serial_resume(struct platform_device *pdev)
1718static int __devinit atmel_serial_probe(struct platform_device *pdev) 1776static int __devinit atmel_serial_probe(struct platform_device *pdev)
1719{ 1777{
1720 struct atmel_uart_port *port; 1778 struct atmel_uart_port *port;
1779 struct device_node *np = pdev->dev.of_node;
1721 struct atmel_uart_data *pdata = pdev->dev.platform_data; 1780 struct atmel_uart_data *pdata = pdev->dev.platform_data;
1722 void *data; 1781 void *data;
1723 int ret = -ENODEV; 1782 int ret = -ENODEV;
1724 1783
1725 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); 1784 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
1726 1785
1727 if (pdata) 1786 if (np)
1728 ret = pdata->num; 1787 ret = of_alias_get_id(np, "serial");
1788 else
1789 if (pdata)
1790 ret = pdata->num;
1729 1791
1730 if (ret < 0) 1792 if (ret < 0)
1731 /* port id not found in platform data: 1793 /* port id not found in platform data nor device-tree aliases:
1732 * auto-enumerate it */ 1794 * auto-enumerate it */
1733 ret = find_first_zero_bit(&atmel_ports_in_use, 1795 ret = find_first_zero_bit(&atmel_ports_in_use,
1734 sizeof(atmel_ports_in_use)); 1796 sizeof(atmel_ports_in_use));
@@ -1827,6 +1889,7 @@ static struct platform_driver atmel_serial_driver = {
1827 .driver = { 1889 .driver = {
1828 .name = "atmel_usart", 1890 .name = "atmel_usart",
1829 .owner = THIS_MODULE, 1891 .owner = THIS_MODULE,
1892 .of_match_table = of_match_ptr(atmel_serial_dt_ids),
1830 }, 1893 },
1831}; 1894};
1832 1895