From a61c2d78ce61e67baf27c43f6721db87a27ac762 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sat, 7 Jan 2006 23:18:19 +0000 Subject: [SERIAL] Make the number of UARTs registered configurable. Also add a nr_uarts module option to the 8250 code to override this, up to a maximum of CONFIG_SERIAL_8250_NR_UARTS This should appease people who complain about a proliferation of /dev/ttyS & /sysfs nodes whilst at the same time allowing a single kernel image to support the rarer occasions of lots of devices. Signed-off-by: Dave Jones --- Documentation/kernel-parameters.txt | 2 ++ drivers/serial/8250.c | 28 ++++++++++++++++++---------- drivers/serial/Kconfig | 10 ++++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index acb010bb087b57..0dc848bf0b56bb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -998,6 +998,8 @@ running once the system is up. nowb [ARM] + nr_uarts= [SERIAL] maximum number of UARTs to be registered. + opl3= [HW,OSS] Format: diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 1891cf5bdeef24..e8454611cb652b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -54,6 +54,8 @@ */ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; +static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; + /* * Debugging. */ @@ -2118,7 +2120,7 @@ static void __init serial8250_isa_init_ports(void) return; first = 0; - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; up->port.line = i; @@ -2137,7 +2139,7 @@ static void __init serial8250_isa_init_ports(void) } for (i = 0, up = serial8250_ports; - i < ARRAY_SIZE(old_serial_port) && i < UART_NR; + i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; i++, up++) { up->port.iobase = old_serial_port[i].port; up->port.irq = irq_canonicalize(old_serial_port[i].irq); @@ -2159,7 +2161,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) serial8250_isa_init_ports(); - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; up->port.dev = dev; @@ -2262,7 +2264,7 @@ static int serial8250_console_setup(struct console *co, char *options) * if so, search for the first available port that does have * console support. */ - if (co->index >= UART_NR) + if (co->index >= nr_uarts) co->index = 0; port = &serial8250_ports[co->index].port; if (!port->iobase && !port->membase) @@ -2298,7 +2300,7 @@ static int __init find_port(struct uart_port *p) int line; struct uart_port *port; - for (line = 0; line < UART_NR; line++) { + for (line = 0; line < nr_uarts; line++) { port = &serial8250_ports[line].port; if (uart_match_port(p, port)) return line; @@ -2420,7 +2422,7 @@ static int __devexit serial8250_remove(struct platform_device *dev) { int i; - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; if (up->port.dev == &dev->dev) @@ -2487,7 +2489,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /* * First, find a port entry which matches. */ - for (i = 0; i < UART_NR; i++) + for (i = 0; i < nr_uarts; i++) if (uart_match_port(&serial8250_ports[i].port, port)) return &serial8250_ports[i]; @@ -2496,7 +2498,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * * free entry. We look for one which hasn't been previously * used (indicated by zero iobase). */ - for (i = 0; i < UART_NR; i++) + for (i = 0; i < nr_uarts; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN && serial8250_ports[i].port.iobase == 0) return &serial8250_ports[i]; @@ -2505,7 +2507,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * * That also failed. Last resort is to find any entry which * doesn't have a real port associated with it. */ - for (i = 0; i < UART_NR; i++) + for (i = 0; i < nr_uarts; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN) return &serial8250_ports[i]; @@ -2590,8 +2592,11 @@ static int __init serial8250_init(void) { int ret, i; + if (nr_uarts > UART_NR) + nr_uarts = UART_NR; + printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ " - "%d ports, IRQ sharing %sabled\n", (int) UART_NR, + "%d ports, IRQ sharing %sabled\n", nr_uarts, share_irqs ? "en" : "dis"); for (i = 0; i < NR_IRQS; i++) @@ -2651,6 +2656,9 @@ module_param(share_irqs, uint, 0644); MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" " (unsafe)"); +module_param(nr_uarts, uint, 0644); +MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); + #ifdef CONFIG_SERIAL_8250_RSA module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 812bae62c8ecff..3fd5b999fdac30 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -95,6 +95,16 @@ config SERIAL_8250_NR_UARTS PCI enumeration and any ports that may be added at run-time via hot-plug, or any ISA multi-port serial cards. +config SERIAL_8250_RUNTIME_UARTS + int "Number of 8250/16550 serial ports to register at runtime" + depends on SERIAL_8250 + default "4" + help + Set this to the maximum number of serial ports you want + the kernel to register at boot time. This can be overriden + with the module parameter "nr_uarts", or boot-time parameter + 8250.nr_uarts + config SERIAL_8250_EXTENDED bool "Extended 8250/16550 serial driver options" depends on SERIAL_8250 -- cgit 1.2.3-korg