diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | drivers/serial/8250.c | 28 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 10 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 1 |
4 files changed, 31 insertions, 10 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index acb010bb087b..0dc848bf0b56 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -998,6 +998,8 @@ running once the system is up. | |||
998 | 998 | ||
999 | nowb [ARM] | 999 | nowb [ARM] |
1000 | 1000 | ||
1001 | nr_uarts= [SERIAL] maximum number of UARTs to be registered. | ||
1002 | |||
1001 | opl3= [HW,OSS] | 1003 | opl3= [HW,OSS] |
1002 | Format: <io> | 1004 | Format: <io> |
1003 | 1005 | ||
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 1891cf5bdeef..e8454611cb65 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -54,6 +54,8 @@ | |||
54 | */ | 54 | */ |
55 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | 55 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; |
56 | 56 | ||
57 | static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; | ||
58 | |||
57 | /* | 59 | /* |
58 | * Debugging. | 60 | * Debugging. |
59 | */ | 61 | */ |
@@ -2118,7 +2120,7 @@ static void __init serial8250_isa_init_ports(void) | |||
2118 | return; | 2120 | return; |
2119 | first = 0; | 2121 | first = 0; |
2120 | 2122 | ||
2121 | for (i = 0; i < UART_NR; i++) { | 2123 | for (i = 0; i < nr_uarts; i++) { |
2122 | struct uart_8250_port *up = &serial8250_ports[i]; | 2124 | struct uart_8250_port *up = &serial8250_ports[i]; |
2123 | 2125 | ||
2124 | up->port.line = i; | 2126 | up->port.line = i; |
@@ -2137,7 +2139,7 @@ static void __init serial8250_isa_init_ports(void) | |||
2137 | } | 2139 | } |
2138 | 2140 | ||
2139 | for (i = 0, up = serial8250_ports; | 2141 | for (i = 0, up = serial8250_ports; |
2140 | i < ARRAY_SIZE(old_serial_port) && i < UART_NR; | 2142 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; |
2141 | i++, up++) { | 2143 | i++, up++) { |
2142 | up->port.iobase = old_serial_port[i].port; | 2144 | up->port.iobase = old_serial_port[i].port; |
2143 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 2145 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |
@@ -2159,7 +2161,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) | |||
2159 | 2161 | ||
2160 | serial8250_isa_init_ports(); | 2162 | serial8250_isa_init_ports(); |
2161 | 2163 | ||
2162 | for (i = 0; i < UART_NR; i++) { | 2164 | for (i = 0; i < nr_uarts; i++) { |
2163 | struct uart_8250_port *up = &serial8250_ports[i]; | 2165 | struct uart_8250_port *up = &serial8250_ports[i]; |
2164 | 2166 | ||
2165 | up->port.dev = dev; | 2167 | up->port.dev = dev; |
@@ -2262,7 +2264,7 @@ static int serial8250_console_setup(struct console *co, char *options) | |||
2262 | * if so, search for the first available port that does have | 2264 | * if so, search for the first available port that does have |
2263 | * console support. | 2265 | * console support. |
2264 | */ | 2266 | */ |
2265 | if (co->index >= UART_NR) | 2267 | if (co->index >= nr_uarts) |
2266 | co->index = 0; | 2268 | co->index = 0; |
2267 | port = &serial8250_ports[co->index].port; | 2269 | port = &serial8250_ports[co->index].port; |
2268 | if (!port->iobase && !port->membase) | 2270 | if (!port->iobase && !port->membase) |
@@ -2298,7 +2300,7 @@ static int __init find_port(struct uart_port *p) | |||
2298 | int line; | 2300 | int line; |
2299 | struct uart_port *port; | 2301 | struct uart_port *port; |
2300 | 2302 | ||
2301 | for (line = 0; line < UART_NR; line++) { | 2303 | for (line = 0; line < nr_uarts; line++) { |
2302 | port = &serial8250_ports[line].port; | 2304 | port = &serial8250_ports[line].port; |
2303 | if (uart_match_port(p, port)) | 2305 | if (uart_match_port(p, port)) |
2304 | return line; | 2306 | return line; |
@@ -2420,7 +2422,7 @@ static int __devexit serial8250_remove(struct platform_device *dev) | |||
2420 | { | 2422 | { |
2421 | int i; | 2423 | int i; |
2422 | 2424 | ||
2423 | for (i = 0; i < UART_NR; i++) { | 2425 | for (i = 0; i < nr_uarts; i++) { |
2424 | struct uart_8250_port *up = &serial8250_ports[i]; | 2426 | struct uart_8250_port *up = &serial8250_ports[i]; |
2425 | 2427 | ||
2426 | if (up->port.dev == &dev->dev) | 2428 | if (up->port.dev == &dev->dev) |
@@ -2487,7 +2489,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
2487 | /* | 2489 | /* |
2488 | * First, find a port entry which matches. | 2490 | * First, find a port entry which matches. |
2489 | */ | 2491 | */ |
2490 | for (i = 0; i < UART_NR; i++) | 2492 | for (i = 0; i < nr_uarts; i++) |
2491 | if (uart_match_port(&serial8250_ports[i].port, port)) | 2493 | if (uart_match_port(&serial8250_ports[i].port, port)) |
2492 | return &serial8250_ports[i]; | 2494 | return &serial8250_ports[i]; |
2493 | 2495 | ||
@@ -2496,7 +2498,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
2496 | * free entry. We look for one which hasn't been previously | 2498 | * free entry. We look for one which hasn't been previously |
2497 | * used (indicated by zero iobase). | 2499 | * used (indicated by zero iobase). |
2498 | */ | 2500 | */ |
2499 | for (i = 0; i < UART_NR; i++) | 2501 | for (i = 0; i < nr_uarts; i++) |
2500 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && | 2502 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && |
2501 | serial8250_ports[i].port.iobase == 0) | 2503 | serial8250_ports[i].port.iobase == 0) |
2502 | return &serial8250_ports[i]; | 2504 | return &serial8250_ports[i]; |
@@ -2505,7 +2507,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
2505 | * That also failed. Last resort is to find any entry which | 2507 | * That also failed. Last resort is to find any entry which |
2506 | * doesn't have a real port associated with it. | 2508 | * doesn't have a real port associated with it. |
2507 | */ | 2509 | */ |
2508 | for (i = 0; i < UART_NR; i++) | 2510 | for (i = 0; i < nr_uarts; i++) |
2509 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) | 2511 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) |
2510 | return &serial8250_ports[i]; | 2512 | return &serial8250_ports[i]; |
2511 | 2513 | ||
@@ -2590,8 +2592,11 @@ static int __init serial8250_init(void) | |||
2590 | { | 2592 | { |
2591 | int ret, i; | 2593 | int ret, i; |
2592 | 2594 | ||
2595 | if (nr_uarts > UART_NR) | ||
2596 | nr_uarts = UART_NR; | ||
2597 | |||
2593 | printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ " | 2598 | printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ " |
2594 | "%d ports, IRQ sharing %sabled\n", (int) UART_NR, | 2599 | "%d ports, IRQ sharing %sabled\n", nr_uarts, |
2595 | share_irqs ? "en" : "dis"); | 2600 | share_irqs ? "en" : "dis"); |
2596 | 2601 | ||
2597 | for (i = 0; i < NR_IRQS; i++) | 2602 | for (i = 0; i < NR_IRQS; i++) |
@@ -2651,6 +2656,9 @@ module_param(share_irqs, uint, 0644); | |||
2651 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" | 2656 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" |
2652 | " (unsafe)"); | 2657 | " (unsafe)"); |
2653 | 2658 | ||
2659 | module_param(nr_uarts, uint, 0644); | ||
2660 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | ||
2661 | |||
2654 | #ifdef CONFIG_SERIAL_8250_RSA | 2662 | #ifdef CONFIG_SERIAL_8250_RSA |
2655 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); | 2663 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); |
2656 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); | 2664 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 812bae62c8ec..3fd5b999fdac 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -95,6 +95,16 @@ config SERIAL_8250_NR_UARTS | |||
95 | PCI enumeration and any ports that may be added at run-time | 95 | PCI enumeration and any ports that may be added at run-time |
96 | via hot-plug, or any ISA multi-port serial cards. | 96 | via hot-plug, or any ISA multi-port serial cards. |
97 | 97 | ||
98 | config SERIAL_8250_RUNTIME_UARTS | ||
99 | int "Number of 8250/16550 serial ports to register at runtime" | ||
100 | depends on SERIAL_8250 | ||
101 | default "4" | ||
102 | help | ||
103 | Set this to the maximum number of serial ports you want | ||
104 | the kernel to register at boot time. This can be overriden | ||
105 | with the module parameter "nr_uarts", or boot-time parameter | ||
106 | 8250.nr_uarts | ||
107 | |||
98 | config SERIAL_8250_EXTENDED | 108 | config SERIAL_8250_EXTENDED |
99 | bool "Extended 8250/16550 serial driver options" | 109 | bool "Extended 8250/16550 serial driver options" |
100 | depends on SERIAL_8250 | 110 | depends on SERIAL_8250 |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 34c576dfad8d..9589509fc5bd 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1440,6 +1440,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) | |||
1440 | * modem is ready for us. | 1440 | * modem is ready for us. |
1441 | */ | 1441 | */ |
1442 | spin_lock_irq(&port->lock); | 1442 | spin_lock_irq(&port->lock); |
1443 | port->ops->enable_ms(port); | ||
1443 | mctrl = port->ops->get_mctrl(port); | 1444 | mctrl = port->ops->get_mctrl(port); |
1444 | spin_unlock_irq(&port->lock); | 1445 | spin_unlock_irq(&port->lock); |
1445 | if (mctrl & TIOCM_CAR) | 1446 | if (mctrl & TIOCM_CAR) |