Commit a664ec9675d77aa2196e797afa5516d3e476da77
Committed by
Greg Kroah-Hartman
1 parent
0259894c73
Exists in
master
and in
39 other branches
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 | } |