serial: altera_uart: Scan for a free port if platform device id is -1
authorTobias Klauser <tklauser@distanz.ch>
Mon, 28 Mar 2011 11:57:11 +0000 (13:57 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 19 Apr 2011 23:31:19 +0000 (16:31 -0700)
Devices extracted from device tree all seem to have pdev->id set to -1.
Up until now we mapped all devices with id -1 to the first device.  This
behaviour could lead to problems when using more than one Altera UART in
a system.

This patch changes the behaviour of the driver to scan for the next free
id in case the id is -1.

Because we cannot refer back to the assigned id in altera_uart_remove,
the port instance needs to be stored in device drvdata.

Reported-by: David Smoot <davidsmoot@gmail.com>
Cc: Anton Vorontsov <cbouatmailru@gmail.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/tty/serial/altera_uart.c

index 6d5b036ac7834883e8273dd32a378f27d340aeff..50bc5a5ac6533af4d9efceb1e21882eb489914ac 100644 (file)
@@ -540,11 +540,14 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
        int i = pdev->id;
        int ret;
 
-       /* -1 emphasizes that the platform must have one port, no .N suffix */
-       if (i == -1)
-               i = 0;
+       /* if id is -1 scan for a free id and use that one */
+       if (i == -1) {
+               for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++)
+                       if (altera_uart_ports[i].port.mapbase == 0)
+                               break;
+       }
 
-       if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
+       if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
                return -EINVAL;
 
        port = &altera_uart_ports[i].port;
@@ -587,6 +590,8 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
        port->ops = &altera_uart_ops;
        port->flags = UPF_BOOT_AUTOCONF;
 
+       dev_set_drvdata(&pdev->dev, port);
+
        uart_add_one_port(&altera_uart_driver, port);
 
        return 0;
@@ -594,14 +599,13 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
 
 static int __devexit altera_uart_remove(struct platform_device *pdev)
 {
-       struct uart_port *port;
-       int i = pdev->id;
+       struct uart_port *port = dev_get_drvdata(&pdev->dev);
 
-       if (i == -1)
-               i = 0;
-
-       port = &altera_uart_ports[i].port;
-       uart_remove_one_port(&altera_uart_driver, port);
+       if (port) {
+               uart_remove_one_port(&altera_uart_driver, port);
+               dev_set_drvdata(&pdev->dev, NULL);
+               port->mapbase = 0;
+       }
 
        return 0;
 }