aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2011-10-12 12:06:59 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-18 19:42:07 -0400
commit4cbf9f4864bd4fb2e64d555aacb93c24478e4e8d (patch)
tree80d85d123ee482dfa2b3881f5a0f3cf755c29416
parent588edbf3b8948d94a52da5d6b45c9bb7307d1f01 (diff)
tty/serial: atmel_serial: auto-enumerate ports
If no platform data provided to enumerate ports, use a bit field to choose port number and check if port is already initialized. Use this mechanism for both console and plain serial ports. 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>
-rw-r--r--drivers/tty/serial/atmel_serial.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index bb723542ad24..10743297a001 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -157,6 +157,7 @@ struct atmel_uart_port {
157}; 157};
158 158
159static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; 159static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
160static unsigned long atmel_ports_in_use;
160 161
161#ifdef SUPPORT_SYSRQ 162#ifdef SUPPORT_SYSRQ
162static struct console atmel_console; 163static struct console atmel_console;
@@ -1423,7 +1424,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
1423 port->flags = UPF_BOOT_AUTOCONF; 1424 port->flags = UPF_BOOT_AUTOCONF;
1424 port->ops = &atmel_pops; 1425 port->ops = &atmel_pops;
1425 port->fifosize = 1; 1426 port->fifosize = 1;
1426 port->line = pdata->num;
1427 port->dev = &pdev->dev; 1427 port->dev = &pdev->dev;
1428 port->mapbase = pdev->resource[0].start; 1428 port->mapbase = pdev->resource[0].start;
1429 port->irq = pdev->resource[1].start; 1429 port->irq = pdev->resource[1].start;
@@ -1613,10 +1613,15 @@ static struct console atmel_console = {
1613static int __init atmel_console_init(void) 1613static int __init atmel_console_init(void)
1614{ 1614{
1615 if (atmel_default_console_device) { 1615 if (atmel_default_console_device) {
1616 add_preferred_console(ATMEL_DEVICENAME, 1616 int id = atmel_default_console_device->id;
1617 atmel_default_console_device->id, NULL); 1617 struct atmel_uart_port *port = &atmel_ports[id];
1618 atmel_init_port(&atmel_ports[atmel_default_console_device->id], 1618
1619 atmel_default_console_device); 1619 set_bit(id, &atmel_ports_in_use);
1620 port->backup_imr = 0;
1621 port->uart.line = id;
1622
1623 add_preferred_console(ATMEL_DEVICENAME, id, NULL);
1624 atmel_init_port(port, atmel_default_console_device);
1620 register_console(&atmel_console); 1625 register_console(&atmel_console);
1621 } 1626 }
1622 1627
@@ -1715,12 +1720,33 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
1715 struct atmel_uart_port *port; 1720 struct atmel_uart_port *port;
1716 struct atmel_uart_data *pdata = pdev->dev.platform_data; 1721 struct atmel_uart_data *pdata = pdev->dev.platform_data;
1717 void *data; 1722 void *data;
1718 int ret; 1723 int ret = -ENODEV;
1719 1724
1720 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); 1725 BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
1721 1726
1722 port = &atmel_ports[pdata->num]; 1727 if (pdata)
1728 ret = pdata->num;
1729
1730 if (ret < 0)
1731 /* port id not found in platform data:
1732 * auto-enumerate it */
1733 ret = find_first_zero_bit(&atmel_ports_in_use,
1734 sizeof(atmel_ports_in_use));
1735
1736 if (ret > ATMEL_MAX_UART) {
1737 ret = -ENODEV;
1738 goto err;
1739 }
1740
1741 if (test_and_set_bit(ret, &atmel_ports_in_use)) {
1742 /* port already in use */
1743 ret = -EBUSY;
1744 goto err;
1745 }
1746
1747 port = &atmel_ports[ret];
1723 port->backup_imr = 0; 1748 port->backup_imr = 0;
1749 port->uart.line = ret;
1724 1750
1725 atmel_init_port(port, pdev); 1751 atmel_init_port(port, pdev);
1726 1752
@@ -1766,7 +1792,7 @@ err_alloc_ring:
1766 clk_put(port->clk); 1792 clk_put(port->clk);
1767 port->clk = NULL; 1793 port->clk = NULL;
1768 } 1794 }
1769 1795err:
1770 return ret; 1796 return ret;
1771} 1797}
1772 1798
@@ -1786,6 +1812,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
1786 1812
1787 /* "port" is allocated statically, so we shouldn't free it */ 1813 /* "port" is allocated statically, so we shouldn't free it */
1788 1814
1815 clear_bit(port->line, &atmel_ports_in_use);
1816
1789 clk_put(atmel_port->clk); 1817 clk_put(atmel_port->clk);
1790 1818
1791 return ret; 1819 return ret;