Commit a664ec9675d77aa2196e797afa5516d3e476da77

Authored by Tobias Klauser
Committed by Greg Kroah-Hartman
1 parent 0259894c73

serial: altera_uart: Scan for a free port if platform device id is -1

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>

Showing 1 changed file with 15 additions and 11 deletions Side-by-side Diff

drivers/tty/serial/altera_uart.c
... ... @@ -540,11 +540,14 @@
540 540 int i = pdev->id;
541 541 int ret;
542 542  
543   - /* -1 emphasizes that the platform must have one port, no .N suffix */
544   - if (i == -1)
545   - i = 0;
  543 + /* if id is -1 scan for a free id and use that one */
  544 + if (i == -1) {
  545 + for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++)
  546 + if (altera_uart_ports[i].port.mapbase == 0)
  547 + break;
  548 + }
546 549  
547   - if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
  550 + if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
548 551 return -EINVAL;
549 552  
550 553 port = &altera_uart_ports[i].port;
... ... @@ -587,6 +590,8 @@
587 590 port->ops = &altera_uart_ops;
588 591 port->flags = UPF_BOOT_AUTOCONF;
589 592  
  593 + dev_set_drvdata(&pdev->dev, port);
  594 +
590 595 uart_add_one_port(&altera_uart_driver, port);
591 596  
592 597 return 0;
593 598  
... ... @@ -594,14 +599,13 @@
594 599  
595 600 static int __devexit altera_uart_remove(struct platform_device *pdev)
596 601 {
597   - struct uart_port *port;
598   - int i = pdev->id;
  602 + struct uart_port *port = dev_get_drvdata(&pdev->dev);
599 603  
600   - if (i == -1)
601   - i = 0;
602   -
603   - port = &altera_uart_ports[i].port;
604   - uart_remove_one_port(&altera_uart_driver, port);
  604 + if (port) {
  605 + uart_remove_one_port(&altera_uart_driver, port);
  606 + dev_set_drvdata(&pdev->dev, NULL);
  607 + port->mapbase = 0;
  608 + }
605 609  
606 610 return 0;
607 611 }