8250_pnp: do pnp probe before legacy probe
authorSean Young <sean@mess.org>
Fri, 7 Sep 2012 18:06:23 +0000 (19:06 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Sep 2012 20:25:41 +0000 (13:25 -0700)
We first probe the legacy serial ports and then check pnp. If there
is a non-standard configuration then this might not work, also this
change is needed so we can blacklist Winbond CIR based on PNP ID.

For this to work the 8250_pnp driver must be merged into the 8250
module.

Signed-off-by: Sean Young <sean@mess.org>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_pnp.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/8250/Makefile

index 932a216aa5bceb0fc74e32a9f33a3092c27cf56f..a2042c6673afcf0fe5e80215bf74ec2d91111f23 100644 (file)
@@ -2675,6 +2675,9 @@ static void __init serial8250_isa_init_ports(void)
                return;
        first = 0;
 
+       if (nr_uarts > UART_NR)
+               nr_uarts = UART_NR;
+
        for (i = 0; i < nr_uarts; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
                struct uart_port *port = &up->port;
@@ -2684,6 +2687,7 @@ static void __init serial8250_isa_init_ports(void)
 
                init_timer(&up->timer);
                up->timer.function = serial8250_timeout;
+               up->cur_iotype = 0xFF;
 
                /*
                 * ALPHA_KLUDGE_MCR needs to be killed.
@@ -2735,13 +2739,9 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 
        for (i = 0; i < nr_uarts; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
-               up->cur_iotype = 0xFF;
-       }
 
-       serial8250_isa_init_ports();
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
+               if (up->port.dev)
+                       continue;
 
                up->port.dev = dev;
 
@@ -2866,9 +2866,6 @@ static struct console serial8250_console = {
 
 static int __init serial8250_console_init(void)
 {
-       if (nr_uarts > UART_NR)
-               nr_uarts = UART_NR;
-
        serial8250_isa_init_ports();
        register_console(&serial8250_console);
        return 0;
@@ -3151,7 +3148,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
 
        uart = serial8250_find_match_or_unused(&up->port);
        if (uart) {
-               uart_remove_one_port(&serial8250_reg, &uart->port);
+               if (uart->port.dev)
+                       uart_remove_one_port(&serial8250_reg, &uart->port);
 
                uart->port.iobase       = up->port.iobase;
                uart->port.membase      = up->port.membase;
@@ -3235,8 +3233,7 @@ static int __init serial8250_init(void)
 {
        int ret;
 
-       if (nr_uarts > UART_NR)
-               nr_uarts = UART_NR;
+       serial8250_isa_init_ports();
 
        printk(KERN_INFO "Serial: 8250/16550 driver, "
                "%d ports, IRQ sharing %sabled\n", nr_uarts,
@@ -3251,11 +3248,15 @@ static int __init serial8250_init(void)
        if (ret)
                goto out;
 
+       ret = serial8250_pnp_init();
+       if (ret)
+               goto unreg_uart_drv;
+
        serial8250_isa_devs = platform_device_alloc("serial8250",
                                                    PLAT8250_DEV_LEGACY);
        if (!serial8250_isa_devs) {
                ret = -ENOMEM;
-               goto unreg_uart_drv;
+               goto unreg_pnp;
        }
 
        ret = platform_device_add(serial8250_isa_devs);
@@ -3271,6 +3272,8 @@ static int __init serial8250_init(void)
        platform_device_del(serial8250_isa_devs);
 put_dev:
        platform_device_put(serial8250_isa_devs);
+unreg_pnp:
+       serial8250_pnp_exit();
 unreg_uart_drv:
 #ifdef CONFIG_SPARC
        sunserial_unregister_minors(&serial8250_reg, UART_NR);
@@ -3295,6 +3298,8 @@ static void __exit serial8250_exit(void)
        platform_driver_unregister(&serial8250_isa_driver);
        platform_device_unregister(isa_dev);
 
+       serial8250_pnp_exit();
+
 #ifdef CONFIG_SPARC
        sunserial_unregister_minors(&serial8250_reg, UART_NR);
 #else
index 0c5e908df0b55cbc8fa535b5efc77bf496b12ad7..5a76f9c8d36b98d943ef574de25c4400579c0551 100644 (file)
@@ -97,3 +97,12 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value)
 #else
 #define ALPHA_KLUDGE_MCR 0
 #endif
+
+#ifdef CONFIG_SERIAL_8250_PNP
+int serial8250_pnp_init(void);
+void serial8250_pnp_exit(void);
+#else
+static inline int serial8250_pnp_init(void) { return 0; }
+static inline void serial8250_pnp_exit(void) { }
+#endif
+
index fde5aa60d51e92391dfdb996a7065d25d4f12c00..28bf830603aa7e21edb0aef5ed099cca340cebfd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Probe module for 8250/16550-type ISAPNP serial ports.
+ *  Probe for 8250/16550-type ISAPNP serial ports.
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
  *
@@ -507,18 +507,13 @@ static struct pnp_driver serial_pnp_driver = {
        .id_table       = pnp_dev_table,
 };
 
-static int __init serial8250_pnp_init(void)
+int serial8250_pnp_init(void)
 {
        return pnp_register_driver(&serial_pnp_driver);
 }
 
-static void __exit serial8250_pnp_exit(void)
+void serial8250_pnp_exit(void)
 {
        pnp_unregister_driver(&serial_pnp_driver);
 }
 
-module_init(serial8250_pnp_init);
-module_exit(serial8250_pnp_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
index a27dd0569bd7341b93a176be9c58755669d3829d..f3d283f2e3aa280598867500de23f142cb050670 100644 (file)
@@ -33,6 +33,14 @@ config SERIAL_8250
          Most people will say Y or M here, so that they can use serial mice,
          modems and similar devices connecting to the standard serial ports.
 
+config SERIAL_8250_PNP
+       bool "8250/16550 PNP device support" if EXPERT
+       depends on SERIAL_8250 && PNP
+       default y
+       ---help---
+         This builds standard PNP serial support. You may be able to
+         disable this feature if you only need legacy serial support.
+
 config SERIAL_8250_CONSOLE
        bool "Console on 8250/16550 and compatible serial port"
        depends on SERIAL_8250=y
@@ -85,14 +93,6 @@ config SERIAL_8250_PCI
          disable this feature if you only need legacy serial support.
          Saves about 9K.
 
-config SERIAL_8250_PNP
-       tristate "8250/16550 PNP device support" if EXPERT
-       depends on SERIAL_8250 && PNP
-       default SERIAL_8250
-       help
-         This builds standard PNP serial support. You may be able to
-         disable this feature if you only need legacy serial support.
-
 config SERIAL_8250_HP300
        tristate
        depends on SERIAL_8250 && HP300
index d7533c7d2c1ac227727e075444e30ba2643dfd8b..108fe7fe13e290f0abdf3edd35210f02347afc99 100644 (file)
@@ -2,8 +2,9 @@
 # Makefile for the 8250 serial device drivers.
 #
 
-obj-$(CONFIG_SERIAL_8250)              += 8250.o
-obj-$(CONFIG_SERIAL_8250_PNP)          += 8250_pnp.o
+obj-$(CONFIG_SERIAL_8250)              += 8250_core.o
+8250_core-y                            := 8250.o
+8250_core-$(CONFIG_SERIAL_8250_PNP)    += 8250_pnp.o
 obj-$(CONFIG_SERIAL_8250_GSC)          += 8250_gsc.o
 obj-$(CONFIG_SERIAL_8250_PCI)          += 8250_pci.o
 obj-$(CONFIG_SERIAL_8250_HP300)                += 8250_hp300.o