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>
This commit is contained in:
parent
588edbf3b8
commit
4cbf9f4864
1 changed files with 36 additions and 8 deletions
|
@ -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 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue