Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cbf9f48 authored by Nicolas Ferre's avatar Nicolas Ferre Committed by Greg Kroah-Hartman
Browse files

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: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 588edbf3
Loading
Loading
Loading
Loading
+36 −8
Original line number Original line Diff line number Diff line
@@ -157,6 +157,7 @@ struct atmel_uart_port {
};
};


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


#ifdef SUPPORT_SYSRQ
#ifdef SUPPORT_SYSRQ
static struct console atmel_console;
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->flags		= UPF_BOOT_AUTOCONF;
	port->ops		= &atmel_pops;
	port->ops		= &atmel_pops;
	port->fifosize		= 1;
	port->fifosize		= 1;
	port->line		= pdata->num;
	port->dev		= &pdev->dev;
	port->dev		= &pdev->dev;
	port->mapbase	= pdev->resource[0].start;
	port->mapbase	= pdev->resource[0].start;
	port->irq	= pdev->resource[1].start;
	port->irq	= pdev->resource[1].start;
@@ -1613,10 +1613,15 @@ static struct console atmel_console = {
static int __init atmel_console_init(void)
static int __init atmel_console_init(void)
{
{
	if (atmel_default_console_device) {
	if (atmel_default_console_device) {
		add_preferred_console(ATMEL_DEVICENAME,
		int id = atmel_default_console_device->id;
				      atmel_default_console_device->id, NULL);
		struct atmel_uart_port *port = &atmel_ports[id];
		atmel_init_port(&atmel_ports[atmel_default_console_device->id],

				atmel_default_console_device);
		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);
		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_port *port;
	struct atmel_uart_data *pdata = pdev->dev.platform_data;
	struct atmel_uart_data *pdata = pdev->dev.platform_data;
	void *data;
	void *data;
	int ret;
	int ret = -ENODEV;


	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
	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->backup_imr = 0;
	port->uart.line = ret;


	atmel_init_port(port, pdev);
	atmel_init_port(port, pdev);


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

err:
	return ret;
	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 */
	/* "port" is allocated statically, so we shouldn't free it */


	clear_bit(port->line, &atmel_ports_in_use);

	clk_put(atmel_port->clk);
	clk_put(atmel_port->clk);


	return ret;
	return ret;