diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2011-10-12 12:07:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-10-18 19:42:08 -0400 |
commit | 5fbe46b67680c27aeb56228dab8cfe25f8f8f83d (patch) | |
tree | 0758fc1a8d70fb46705bdd35f92c83acf8b653aa /drivers/tty | |
parent | 4cbf9f4864bd4fb2e64d555aacb93c24478e4e8d (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.c | 79 |
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; | |||
163 | static struct console atmel_console; | 165 | static struct console atmel_console; |
164 | #endif | 166 | #endif |
165 | 167 | ||
168 | #if defined(CONFIG_OF) | ||
169 | static const struct of_device_id atmel_serial_dt_ids[] = { | ||
170 | { .compatible = "atmel,at91rm9200-usart" }, | ||
171 | { .compatible = "atmel,at91sam9260-usart" }, | ||
172 | { /* sentinel */ } | ||
173 | }; | ||
174 | |||
175 | MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids); | ||
176 | #endif | ||
177 | |||
166 | static inline struct atmel_uart_port * | 178 | static inline struct atmel_uart_port * |
167 | to_atmel_uart_port(struct uart_port *uart) | 179 | to_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 | ||
1426 | static 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) | |||
1718 | static int __devinit atmel_serial_probe(struct platform_device *pdev) | 1776 | static 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 | ||