]> git.neil.brown.name Git - history.git/commitdiff
[SERIAL] 8250_hcdp needs irq sharing
authorAlex Williamson <alex.williamson@com.rmk.(none)>
Tue, 4 May 2004 17:18:13 +0000 (18:18 +0100)
committerRussell King <rmk@flint.arm.linux.org.uk>
Tue, 4 May 2004 17:18:13 +0000 (18:18 +0100)
Patch from Alex Williamson

Here's a trivial patch that makes 8250_hcdp setup the correct flags
when IRQ sharing is enabled for serial ports.

The HCDP table tells us if the device is a PCI UART.  We can use this
to set the shared interrupt flag as well as program the interrupt with
the correct polarity/trigger (should get rid of "changing vector <x>
from IO-SAPIC-edge to IO-SAPIC-level" messages at bootup).  This also
allows non-PCI UARTs to be left un-shareable, which is likely much
more safe (edge triggered).

The bit that I'm keying on is still part of the older 1.0a HCDP spec,
so should be implemented (it was on all the boxes I tested).  If
there's firmware out there that doesn't set this bit or the interrupt
supported flag, the HCDP UART may run in polling mode, but should
still be functional.

drivers/serial/8250_hcdp.c
drivers/serial/8250_hcdp.h

index 8179a61448922943bab336c6ebec247572841874..d353d917ea3b1cffc3fbf6f35ae1bf48812d5e03 100644 (file)
@@ -147,7 +147,7 @@ setup_serial_hcdp(void *tablep)
                printk("  gsi = %d, baud rate = %lu, bits = %d, clock = %d\n",
                       gsi, (unsigned long) hcdp_dev->baud, hcdp_dev->bits,
                       hcdp_dev->clock_rate);
-               if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE)
+               if (HCDP_PCI_UART(hcdp_dev))
                        printk(" PCI id: %02x:%02x:%02x, vendor ID=0x%x, "
                                "dev ID=0x%x\n", hcdp_dev->pci_seg,
                                hcdp_dev->pci_bus, hcdp_dev->pci_dev,
@@ -179,16 +179,26 @@ setup_serial_hcdp(void *tablep)
                        printk(KERN_WARNING"warning: No support for PCI serial console\n");
                        return;
                }
+
+               if (HCDP_IRQ_SUPPORTED(hcdp_dev)) {
 #ifdef CONFIG_IA64
-               port.irq = acpi_register_irq(gsi, ACPI_ACTIVE_HIGH,
-                               ACPI_EDGE_SENSITIVE);
+                       if (HCDP_PCI_UART(hcdp_dev))
+                               port.irq = acpi_register_irq(gsi,
+                                       ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
+                       else
+                               port.irq = acpi_register_irq(gsi,
+                                       ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE);
 #else
-               port.irq = gsi;
+                       port.irq = gsi;
 #endif
-               port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_RESOURCES;
-               if (gsi)
                        port.flags |= UPF_AUTO_IRQ;
 
+                       if (HCDP_PCI_UART(hcdp_dev))
+                               port.flags |= UPF_SHARE_IRQ;
+               }
+
+               port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_RESOURCES;
+
                /*
                 * Note: the above memset() initializes port.line to 0,
                 * so we register this port as ttyS0.
@@ -197,6 +207,7 @@ setup_serial_hcdp(void *tablep)
                        printk("setup_serial_hcdp(): early_serial_setup() "
                                "for HCDP serial console port failed. "
                                "Will try any additional consoles in HCDP.\n");
+                       memset(&port, 0, sizeof(port));
                        continue;
                }
                break;
index 8ee1b60bc430d1cfd8ac6db797f32e3b7e14cd9d..fa956a1c8f068b792189f2b617e7f42df4baa4bd 100644 (file)
@@ -77,3 +77,6 @@ typedef struct {
        u32     num_entries;
        hcdp_dev_t      hcdp_dev[MAX_HCDP_DEVICES];
 } hcdp_t;
+
+#define HCDP_PCI_UART(x) (x->pci_func & 1UL<<7)
+#define HCDP_IRQ_SUPPORTED(x) (x->pci_func & 1UL<<6)