lkml.org 
[lkml]   [2011]   [Oct]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v2 4/5] tty/serial: atmel_serial: auto-enumerate ports
Date
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>
---
drivers/tty/serial/atmel_serial.c | 44 ++++++++++++++++++++++++++++++------
1 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index bb72354..1074329 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -157,6 +157,7 @@ struct atmel_uart_port {
};

static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
+static unsigned long atmel_ports_in_use;

#ifdef SUPPORT_SYSRQ
static struct console atmel_console;
@@ -1423,7 +1424,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
port->flags = UPF_BOOT_AUTOCONF;
port->ops = &atmel_pops;
port->fifosize = 1;
- port->line = pdata->num;
port->dev = &pdev->dev;
port->mapbase = pdev->resource[0].start;
port->irq = pdev->resource[1].start;
@@ -1613,10 +1613,15 @@ static struct console atmel_console = {
static int __init atmel_console_init(void)
{
if (atmel_default_console_device) {
- add_preferred_console(ATMEL_DEVICENAME,
- atmel_default_console_device->id, NULL);
- atmel_init_port(&atmel_ports[atmel_default_console_device->id],
- atmel_default_console_device);
+ int id = atmel_default_console_device->id;
+ struct atmel_uart_port *port = &atmel_ports[id];
+
+ set_bit(id, &atmel_ports_in_use);
+ port->backup_imr = 0;
+ port->uart.line = id;
+
+ add_preferred_console(ATMEL_DEVICENAME, id, NULL);
+ atmel_init_port(port, atmel_default_console_device);
register_console(&atmel_console);
}

@@ -1715,12 +1720,33 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
struct atmel_uart_port *port;
struct atmel_uart_data *pdata = pdev->dev.platform_data;
void *data;
- int ret;
+ int ret = -ENODEV;

BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));

- port = &atmel_ports[pdata->num];
+ if (pdata)
+ ret = pdata->num;
+
+ if (ret < 0)
+ /* port id not found in platform data:
+ * auto-enumerate it */
+ ret = find_first_zero_bit(&atmel_ports_in_use,
+ sizeof(atmel_ports_in_use));
+
+ if (ret > ATMEL_MAX_UART) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ if (test_and_set_bit(ret, &atmel_ports_in_use)) {
+ /* port already in use */
+ ret = -EBUSY;
+ goto err;
+ }
+
+ port = &atmel_ports[ret];
port->backup_imr = 0;
+ port->uart.line = ret;

atmel_init_port(port, pdev);

@@ -1766,7 +1792,7 @@ err_alloc_ring:
clk_put(port->clk);
port->clk = NULL;
}
-
+err:
return ret;
}

@@ -1786,6 +1812,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)

/* "port" is allocated statically, so we shouldn't free it */

+ clear_bit(port->line, &atmel_ports_in_use);
+
clk_put(atmel_port->clk);

return ret;
--
1.7.5.4


\
 
 \ /
  Last update: 2011-10-12 18:11    [W:0.067 / U:2.180 seconds]
©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site