* RE: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework @ 2004-05-17 9:58 Li, Shaohua 2004-05-17 15:41 ` Bjorn Helgaas 0 siblings, 1 reply; 5+ messages in thread From: Li, Shaohua @ 2004-05-17 9:58 UTC (permalink / raw) To: Bjorn Helgaas Cc: acpi-devel, Brown, Len, David Mosberger, Andi Kleen, Nakajima, Jun, linux-ia64 For the IOSAPIC, your patch mask interrupts in initialization, but should we mask platform interrupt? Thanks, Shaohua >-----Original Message----- >From: acpi-devel-admin@lists.sourceforge.net [mailto:acpi-devel- >admin@lists.sourceforge.net] On Behalf Of Bjorn Helgaas >Sent: Sunday, May 16, 2004 4:24 AM >To: acpi-devel@lists.sourceforge.net >Cc: Brown, Len; David Mosberger; Andi Kleen; Nakajima, Jun; linux- >ia64@vger.kernel.org >Subject: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework > >Andi's x86-64 update that showed up in linux-2.5 today touches >mp_parse_prt(), one of the functions I changed. > >Here's an updated patch: > >=== arch/i386/kernel/mpparse.c 1.71 vs edited ==>--- 1.71/arch/i386/kernel/mpparse.c Fri Apr 30 23:27:25 2004 >+++ edited/arch/i386/kernel/mpparse.c Sat May 15 14:16:59 2004 >@@ -1027,94 +1027,58 @@ > > extern FADT_DESCRIPTOR acpi_fadt; > >-#ifdef CONFIG_ACPI_PCI >+#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ >+ >+#ifdef CONFIG_X86_IO_APIC > >-void __init mp_parse_prt (void) >+void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) > { >- struct list_head *node = NULL; >- struct acpi_prt_entry *entry = NULL; > int ioapic = -1; > int ioapic_pin = 0; >- int gsi = 0; > int idx, bit = 0; >- int edge_level = 0; >- int active_high_low = 0; > >- /* >- * Parsing through the PCI Interrupt Routing Table (PRT) and program >- * routing for all entries. >- */ >- list_for_each(node, &acpi_prt.entries) { >- entry = list_entry(node, struct acpi_prt_entry, node); >+ /* Don't set up the ACPI SCI because it's already set up */ >+ if (acpi_fadt.sci_int = gsi) >+ return; >+ >+ ioapic = mp_find_ioapic(gsi); >+ if (ioapic < 0) { >+ printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi); >+ return; >+ } >+ >+ ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; > >- /* Need to get gsi for dynamic entry */ >- if (entry->link.handle) { >- gsi = acpi_pci_link_get_irq(entry->link.handle, entry- >>link.index, &edge_level, &active_high_low); >- if (!gsi) >- continue; >- } >- else { >- /* Hardwired GSI. Assume PCI standard settings */ >- gsi = entry->link.index; >- edge_level = 1; >- active_high_low = 1; >- } >- >- /* Don't set up the ACPI SCI because it's already set up */ >- if (acpi_fadt.sci_int = gsi) { >- /* we still need to set entry's irq */ >- acpi_gsi_to_irq(gsi, &entry->irq); >- continue; >- } >- >- ioapic = mp_find_ioapic(gsi); >- if (ioapic < 0) >- continue; >- ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; >- >- if (es7000_plat) { >- if (!ioapic && (gsi < 16)) >- gsi += 16; >- } >- >- /* >- * Avoid pin reprogramming. PRTs typically include entries >- * with redundant pin->gsi mappings (but unique PCI devices); >- * we only only program the IOAPIC on the first. >- */ >- bit = ioapic_pin % 32; >- idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); >- if (idx > 3) { >- printk(KERN_ERR "Invalid reference to IOAPIC pin " >- "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, >- ioapic_pin); >- continue; >- } >- if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { >- Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", >- mp_ioapic_routing[ioapic].apic_id, ioapic_pin); >- acpi_gsi_to_irq(gsi, &entry->irq); >- continue; >- } >- >- mp_ioapic_routing[ioapic].pin_programmed[idx] |(1<<bit); >- >- if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, >edge_level, active_high_low)) { >- acpi_gsi_to_irq(gsi, &entry->irq); >- } >- printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s >%s\n", >- entry->id.segment, entry->id.bus, >- entry->id.device, ('A' + entry->pin), >- mp_ioapic_routing[ioapic].apic_id, ioapic_pin, >- entry->irq, edge_level ? "level" : "edge", >- active_high_low ? "low" : "high"); >+ if (es7000_plat) { >+ if (!ioapic && (gsi < 16)) >+ gsi += 16; > } > >- print_IO_APIC(); >+ /* >+ * Avoid pin reprogramming. PRTs typically include entries >+ * with redundant pin->gsi mappings (but unique PCI devices); >+ * we only program the IOAPIC on the first. >+ */ >+ bit = ioapic_pin % 32; >+ idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); >+ if (idx > 3) { >+ printk(KERN_ERR "Invalid reference to IOAPIC pin " >+ "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, >+ ioapic_pin); >+ return; >+ } >+ if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { >+ Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", >+ mp_ioapic_routing[ioapic].apic_id, ioapic_pin); >+ return; >+ } > >- return; >+ mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); >+ >+ io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, >+ edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1, >+ active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1); > } > >-#endif /*CONFIG_ACPI_PCI*/ >-#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ >+#endif /*CONFIG_X86_IO_APIC*/ > #endif /*CONFIG_ACPI_BOOT*/ >=== arch/i386/kernel/acpi/boot.c 1.61 vs edited ==>--- 1.61/arch/i386/kernel/acpi/boot.c Sat May 15 00:11:59 2004 >+++ edited/arch/i386/kernel/acpi/boot.c Sat May 15 14:12:30 2004 >@@ -428,6 +428,28 @@ > return 0; > } > >+unsigned int acpi_register_gsi(u32 gsi, int edge_level, int >active_high_low) >+{ >+ static u16 irq_mask; >+ unsigned int irq; >+ extern void eisa_set_level_irq(unsigned int irq); >+ >+ /* >+ * Make sure all (legacy) PCI IRQs are set as level-triggered. >+ */ >+ if ((gsi < 16) && !((1 << gsi) & irq_mask)) { >+ printk(KERN_DEBUG PREFIX "Setting GSI 0x%x as level- >triggered\n", gsi); >+ irq_mask |= (1 << gsi); >+ eisa_set_level_irq(gsi); >+ } >+ >+#ifdef CONFIG_X86_IO_APIC >+ mp_register_gsi(gsi, edge_level, active_high_low); >+#endif >+ acpi_gsi_to_irq(gsi, &irq); >+ return irq; >+} >+ > static unsigned long __init > acpi_scan_rsdp ( > unsigned long start, >=== arch/i386/pci/acpi.c 1.13 vs edited ==>--- 1.13/arch/i386/pci/acpi.c Fri Apr 30 23:27:25 2004 >+++ edited/arch/i386/pci/acpi.c Sat May 15 14:12:31 2004 >@@ -1,6 +1,8 @@ > #include <linux/pci.h> > #include <linux/acpi.h> > #include <linux/init.h> >+#include <linux/irq.h> >+#include <asm/hw_irq.h> > #include "pci.h" > > struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, >int domain, int busnum) >@@ -15,18 +17,28 @@ > > static int __init pci_acpi_init(void) > { >+ struct pci_dev *dev = NULL; >+ > if (pcibios_scanned) > return 0; > >- if (!acpi_noirq) { >- if (!acpi_pci_irq_init()) { >- printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); >- pcibios_scanned++; >- pcibios_enable_irq = acpi_pci_irq_enable; >- } else >- printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing >table\n"); >+ if (acpi_noirq) >+ return 0; > >- } >+ printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); >+ acpi_irq_penalty_init(); >+ pcibios_scanned++; >+ pcibios_enable_irq = acpi_pci_irq_enable; >+ >+ /* >+ * PCI IRQ routing is set up by pci_enable_device(), but we >+ * also do it here in case there are still broken drivers that >+ * don't use pci_enable_device(). >+ */ >+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) !NULL) >+ acpi_pci_irq_enable(dev); >+ >+ print_IO_APIC(); > > return 0; > } >=== arch/ia64/kernel/acpi.c 1.69 vs edited ==>--- 1.69/arch/ia64/kernel/acpi.c Sat May 15 00:11:59 2004 >+++ edited/arch/ia64/kernel/acpi.c Sat May 15 14:12:32 2004 >@@ -508,9 +508,14 @@ > #endif /* CONFIG_ACPI_NUMA */ > > unsigned int >-acpi_register_gsi (u32 gsi, int polarity, int trigger) >+acpi_register_gsi (u32 gsi, int edge_level, int active_high_low) > { >- return acpi_register_irq(gsi, polarity, trigger); >+ if (has_8259 && gsi < 16) >+ return isa_irq_to_vector(gsi); >+ >+ return iosapic_register_intr(gsi, >+ (active_high_low = ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : >IOSAPIC_POL_LOW, >+ (edge_level = ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : >IOSAPIC_LEVEL); > } > EXPORT_SYMBOL(acpi_register_gsi); > >@@ -535,7 +540,7 @@ > if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) > acpi_legacy_devices = 1; > >- acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, >ACPI_LEVEL_SENSITIVE); >+ acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, >ACPI_ACTIVE_LOW); > return 0; > } > >@@ -648,17 +653,5 @@ > } > return 0; > } >- >-int >-acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) >-{ >- if (has_8259 && gsi < 16) >- return isa_irq_to_vector(gsi); >- >- return iosapic_register_intr(gsi, >- (polarity = ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : >IOSAPIC_POL_LOW, >- (trigger = ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : >IOSAPIC_LEVEL); >-} >-EXPORT_SYMBOL(acpi_register_irq); > > #endif /* CONFIG_ACPI_BOOT */ >=== arch/ia64/kernel/iosapic.c 1.42 vs edited ==>--- 1.42/arch/ia64/kernel/iosapic.c Fri May 14 20:00:12 2004 >+++ edited/arch/ia64/kernel/iosapic.c Sat May 15 14:12:32 2004 >@@ -173,7 +173,7 @@ > } > > static void >-set_rte (unsigned int vector, unsigned int dest, int mask) >+set_rte (unsigned int vector, unsigned int dest) > { > unsigned long pol, trigger, dmode, flags; > u32 low32, high32; >@@ -207,10 +207,11 @@ > } > #endif > >+ /* the RTE always starts masked; the IRQ startup unmasks it */ > low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | > (trigger << IOSAPIC_TRIGGER_SHIFT) | > (dmode << IOSAPIC_DELIVERY_SHIFT) | >- ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) | >+ (1 << IOSAPIC_MASK_SHIFT) | > vector); > > /* dest contains both id and eid */ >@@ -512,6 +513,42 @@ > } > } > >+static unsigned int >+dest_cpu_lid (void) >+{ >+#ifdef CONFIG_SMP >+ static int cpu = -1; >+ >+ /* >+ * If the platform supports redirection via XTP, let it >+ * distribute interrupts. >+ */ >+ if (smp_int_redirect & SMP_IRQ_REDIRECTION) >+ return hard_smp_processor_id(); >+ >+ /* >+ * Some interrupts (ACPI SCI, for instance) are registered >+ * before the BSP is marked as online. >+ */ >+ if (!cpu_online(smp_processor_id())) >+ return hard_smp_processor_id(); >+ >+ /* >+ * Otherwise, round-robin interrupt vectors across all the >+ * processors. (It'd be nice if we could be smarter in the >+ * case of NUMA.) >+ */ >+ do { >+ if (++cpu >= NR_CPUS) >+ cpu = 0; >+ } while (!cpu_online(cpu)); >+ >+ return cpu_physical_id(cpu); >+#else >+ return hard_smp_processor_id(); >+#endif >+} >+ > /* > * ACPI can describe IOSAPIC interrupts via static tables and namespace > * methods. This provides an interface to register those interrupts and >@@ -522,21 +559,35 @@ > unsigned long polarity, unsigned long trigger) > { > int vector; >- unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; >+ unsigned int dest; >+ unsigned long flags; > >- vector = gsi_to_vector(gsi); >- if (vector < 0) >- vector = assign_irq_vector(AUTO_ASSIGN); >+ /* >+ * If this GSI has already been registered (i.e., it's a >+ * shared interrupt, or we lost a race to register it), >+ * don't touch the RTE. >+ */ >+ spin_lock_irqsave(&iosapic_lock, flags); >+ { >+ vector = gsi_to_vector(gsi); >+ if (vector > 0) { >+ spin_unlock_irqrestore(&iosapic_lock, flags); >+ return vector; >+ } > >- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, >- polarity, trigger); >+ vector = assign_irq_vector(AUTO_ASSIGN); >+ dest = dest_cpu_lid(); >+ register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, >+ polarity, trigger); >+ } >+ spin_unlock_irqrestore(&iosapic_lock, flags); > >- printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", >- gsi, (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), >- (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector); >+ printk(KERN_INFO "GSI 0x%x (%s, %s) -> CPU %d (0x%04x) vector %d\n", >+ gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"), >+ (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), >+ cpu_logical_id(dest), dest, vector); > >- /* program the IOSAPIC routing table */ >- set_rte(vector, dest, 0); >+ set_rte(vector, dest); > return vector; > } > >@@ -576,15 +627,14 @@ > return -1; > } > >- register_intr(gsi, vector, delivery, polarity, >- trigger); >+ register_intr(gsi, vector, delivery, polarity, trigger); > >- printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x >vector %d\n", >- int_type, gsi, (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), >- (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector); >+ printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x (%s, %s) -> CPU %d >(0x%04x) vector %d\n", >+ int_type, gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"), >+ (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), >+ cpu_logical_id(dest), dest, vector); > >- /* program the IOSAPIC routing table */ >- set_rte(vector, dest, 0); >+ set_rte(vector, dest); > return vector; > } > >@@ -605,12 +655,12 @@ > > register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, >trigger); > >- DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n", >- isa_irq, gsi, polarity = IOSAPIC_POL_HIGH ? "high" : "low", >- trigger = IOSAPIC_EDGE ? "edge" : "level", dest, vector); >+ DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU %d (0x%04x) vector %d\n", >+ isa_irq, gsi, trigger = IOSAPIC_EDGE ? "edge" : "level", >+ polarity = IOSAPIC_POL_HIGH ? "high" : "low", >+ cpu_logical_id(dest), dest, vector); > >- /* program the IOSAPIC routing table */ >- set_rte(vector, dest, 0); >+ set_rte(vector, dest); > } > > void __init >@@ -665,104 +715,3 @@ > iosapic_override_isa_irq(isa_irq, isa_irq, >IOSAPIC_POL_HIGH, IOSAPIC_EDGE); > } > } >- >-void >-iosapic_enable_intr (unsigned int vector) >-{ >- unsigned int dest; >- irq_desc_t *desc; >- >- /* >- * In the case of a shared interrupt, do not re-route the vector, and >- * especially do not mask a running interrupt (startup will not get >- * called for a shared interrupt). >- */ >- desc = irq_descp(vector); >- if (desc->action) >- return; >- >-#ifdef CONFIG_SMP >- /* >- * For platforms that do not support interrupt redirect via the XTP >interface, we >- * can round-robin the PCI device interrupts to the processors >- */ >- if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { >- static int cpu_index = -1; >- >- do >- if (++cpu_index >= NR_CPUS) >- cpu_index = 0; >- while (!cpu_online(cpu_index)); >- >- dest = cpu_physical_id(cpu_index) & 0xffff; >- } else { >- /* >- * Direct the interrupt vector to the current cpu, platform >redirection >- * will distribute them. >- */ >- dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; >- } >-#else >- /* direct the interrupt vector to the running cpu id */ >- dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; >-#endif >- set_rte(vector, dest, 1); >- >- printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n", >- vector, dest); >-} >- >-#ifdef CONFIG_ACPI_PCI >- >-void __init >-iosapic_parse_prt (void) >-{ >- struct acpi_prt_entry *entry; >- struct list_head *node; >- unsigned int gsi; >- int vector; >- char pci_id[16]; >- struct hw_interrupt_type *irq_type = &irq_type_iosapic_level; >- irq_desc_t *idesc; >- >- list_for_each(node, &acpi_prt.entries) { >- entry = list_entry(node, struct acpi_prt_entry, node); >- >- /* We're only interested in static (non-link) entries. */ >- if (entry->link.handle) >- continue; >- >- gsi = entry->link.index; >- >- vector = gsi_to_vector(gsi); >- if (vector < 0) { >- if (find_iosapic(gsi) < 0) >- continue; >- >- /* allocate a vector for this interrupt line */ >- if (pcat_compat && (gsi < 16)) >- vector = isa_irq_to_vector(gsi); >- else >- /* new GSI; allocate a vector for it */ >- vector = assign_irq_vector(AUTO_ASSIGN); >- >- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, >IOSAPIC_POL_LOW, >- IOSAPIC_LEVEL); >- } >- entry->irq = vector; >- snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]", >- entry->id.segment, entry->id.bus, entry->id.device, 'A' >+ entry->pin); >- >- /* >- * If vector was previously initialized to a different >- * handler, re-initialize. >- */ >- idesc = irq_descp(vector); >- if (idesc->handler != irq_type) >- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, >IOSAPIC_POL_LOW, >- IOSAPIC_LEVEL); >- >- } >-} >- >-#endif /* CONFIG_ACPI */ >=== arch/ia64/pci/pci.c 1.48 vs edited ==>--- 1.48/arch/ia64/pci/pci.c Wed Apr 21 15:26:09 2004 >+++ edited/arch/ia64/pci/pci.c Sat May 15 14:12:33 2004 >@@ -134,10 +134,18 @@ > static int __init > pci_acpi_init (void) > { >- if (!acpi_pci_irq_init()) >- printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); >- else >- printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing >table\n"); >+ struct pci_dev *dev = NULL; >+ >+ printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); >+ >+ /* >+ * PCI IRQ routing is set up by pci_enable_device(), but we >+ * also do it here in case there are still broken drivers that >+ * don't use pci_enable_device(). >+ */ >+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) !NULL) >+ acpi_pci_irq_enable(dev); >+ > return 0; > } > >=== arch/x86_64/kernel/mpparse.c 1.27 vs edited ==>--- 1.27/arch/x86_64/kernel/mpparse.c Sat May 15 07:32:27 2004 >+++ edited/arch/x86_64/kernel/mpparse.c Sat May 15 14:16:33 2004 >@@ -887,88 +887,49 @@ > > extern FADT_DESCRIPTOR acpi_fadt; > >-#ifdef CONFIG_ACPI_PCI >- >-void __init mp_parse_prt (void) >+void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) > { >- struct list_head *node = NULL; >- struct acpi_prt_entry *entry = NULL; > int ioapic = -1; > int ioapic_pin = 0; >- int gsi = 0; > int idx, bit = 0; >- int edge_level = 0; >- int active_high_low = 0; > >- /* >- * Parsing through the PCI Interrupt Routing Table (PRT) and program >- * routing for all static (IOAPIC-direct) entries. >- */ >- list_for_each(node, &acpi_prt.entries) { >- entry = list_entry(node, struct acpi_prt_entry, node); >+ /* Don't set up the ACPI SCI because it's already set up */ >+ if (acpi_fadt.sci_int = gsi) >+ return; >+ >+ ioapic = mp_find_ioapic(gsi); >+ if (ioapic < 0) { >+ printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi); >+ return; >+ } > >- /* Need to get gsi for dynamic entry */ >- if (entry->link.handle) { >- gsi = acpi_pci_link_get_irq(entry->link.handle, entry- >>link.index, &edge_level, &active_high_low); >- if (!gsi) >- continue; >- } else { >- /* Hardwired GSI. Assume PCI standard settings */ >- gsi = entry->link.index; >- edge_level = 1; >- active_high_low = 1; >- } >- >- /* Don't set up the ACPI SCI because it's already set up */ >- if (acpi_fadt.sci_int = gsi) { >- /* we still need to set up the entry's irq */ >- acpi_gsi_to_irq(gsi, &entry->irq); >- continue; >- } >- >- ioapic = mp_find_ioapic(gsi); >- if (ioapic < 0) >- continue; >- ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; >- >- /* >- * Avoid pin reprogramming. PRTs typically include entries >- * with redundant pin->gsi mappings (but unique PCI devices); >- * we only only program the IOAPIC on the first. >- */ >- bit = ioapic_pin % 32; >- idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); >- if (idx > 3) { >- printk(KERN_ERR "Invalid reference to IOAPIC pin " >- "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, >- ioapic_pin); >- continue; >- } >- if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { >- Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", >- mp_ioapic_routing[ioapic].apic_id, ioapic_pin); >- acpi_gsi_to_irq(gsi, &entry->irq); >- continue; >- } >- >- mp_ioapic_routing[ioapic].pin_programmed[idx] |(1<<bit); >- if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, >edge_level, active_high_low)) { >- acpi_gsi_to_irq(gsi, &entry->irq); >- } >- printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", >- entry->id.segment, entry->id.bus, >- entry->id.device, ('A' + entry->pin), >- mp_ioapic_routing[ioapic].apic_id, ioapic_pin, >- entry->irq); >+ ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; >+ >+ /* >+ * Avoid pin reprogramming. PRTs typically include entries >+ * with redundant pin->gsi mappings (but unique PCI devices); >+ * we only program the IOAPIC on the first. >+ */ >+ bit = ioapic_pin % 32; >+ idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); >+ if (idx > 3) { >+ printk(KERN_ERR "Invalid reference to IOAPIC pin " >+ "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, >+ ioapic_pin); >+ return; >+ } >+ if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { >+ Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", >+ mp_ioapic_routing[ioapic].apic_id, ioapic_pin); >+ return; > } >- >- print_IO_APIC(); > >- return; >-} >+ mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); > >-#endif /*CONFIG_ACPI_PCI*/ >+ io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, >+ edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1, >+ active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1); >+} > > #endif /*CONFIG_X86_IO_APIC*/ >- > #endif /*CONFIG_ACPI_BOOT*/ >=== drivers/acpi/pci_irq.c 1.27 vs edited ==>--- 1.27/drivers/acpi/pci_irq.c Sat Apr 24 00:17:22 2004 >+++ edited/drivers/acpi/pci_irq.c Sat May 15 14:12:34 2004 >@@ -35,12 +35,6 @@ > #include <linux/pm.h> > #include <linux/pci.h> > #include <linux/acpi.h> >-#ifdef CONFIG_X86_IO_APIC >-#include <asm/mpspec.h> >-#endif >-#ifdef CONFIG_IOSAPIC >-# include <asm/iosapic.h> >-#endif > #include <acpi/acpi_bus.h> > #include <acpi/acpi_drivers.h> > >@@ -50,10 +44,6 @@ > > struct acpi_prt_list acpi_prt; > >-#ifdef CONFIG_X86 >-extern void eisa_set_level_irq(unsigned int irq); >-#endif >- > > /* ----------------------------------------------------------------------- >--- > PCI IRQ Routing Table (PRT) Support >@@ -237,12 +227,18 @@ > PCI Interrupt Routing Support > ----------------------------------------------------------------------- >--- */ > >-int >-acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin) >+static int >+acpi_pci_irq_lookup ( >+ struct pci_bus *bus, >+ int device, >+ int pin, >+ int *edge_level, >+ int *active_high_low) > { > struct acpi_prt_entry *entry = NULL; > int segment = pci_domain_nr(bus); > int bus_nr = bus->number; >+ int irq; > > ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); > >@@ -255,28 +251,30 @@ > ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); > return_VALUE(0); > } >- >- if (!entry->irq && entry->link.handle) { >- entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry- >>link.index, NULL, NULL); >- if (!entry->irq) { >+ >+ if (entry->link.handle) { >+ irq = acpi_pci_link_get_irq(entry->link.handle, entry- >>link.index, edge_level, active_high_low); >+ if (!irq) { > ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing >entry\n")); > return_VALUE(0); > } >- } >- else if (!entry->irq) { >- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry >(IRQ 0)\n")); >- return_VALUE(0); >+ } else { >+ irq = entry->link.index; >+ *edge_level = ACPI_LEVEL_SENSITIVE; >+ *active_high_low = ACPI_ACTIVE_LOW; > } > >- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq)); >+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); > >- return_VALUE(entry->irq); >+ return_VALUE(irq); > } > > static int > acpi_pci_irq_derive ( > struct pci_dev *dev, >- int pin) >+ int pin, >+ int *edge_level, >+ int *active_high_low) > { > struct pci_dev *bridge = dev; > int irq = 0; >@@ -308,8 +306,8 @@ > pin = bridge_pin; > } > >- irq = acpi_pci_irq_lookup(bridge->bus, >- PCI_SLOT(bridge->devfn), pin); >+ irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), >+ pin, edge_level, active_high_low); > } > > if (!irq) { >@@ -330,6 +328,8 @@ > { > int irq = 0; > u8 pin = 0; >+ int edge_level = ACPI_LEVEL_SENSITIVE; >+ int active_high_low = ACPI_ACTIVE_LOW; > > ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); > >@@ -352,21 +352,22 @@ > * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT > * values override any BIOS-assigned IRQs set during boot. > */ >- irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin); >+ irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, >&edge_level, &active_high_low); > > /* > * If no PRT entry was found, we'll try to derive an IRQ from the > * device's parent bridge. > */ > if (!irq) >- irq = acpi_pci_irq_derive(dev, pin); >+ irq = acpi_pci_irq_derive(dev, pin, &edge_level, >&active_high_low); > > /* > * No IRQ known to the ACPI subsystem - maybe the BIOS / > * driver reported one, then use it. Exit in any case. > */ > if (!irq) { >- printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c >of device %s", ('A' + pin), pci_name(dev)); >+ printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI", >+ pci_name(dev), ('A' + pin)); > /* Interrupt Line values above 0xF are forbidden */ > if (dev->irq && (dev->irq <= 0xF)) { > printk(" - using IRQ %d\n", dev->irq); >@@ -378,62 +379,14 @@ > } > } > >- dev->irq = irq; >+ dev->irq = acpi_register_gsi(irq, edge_level, active_high_low); > >- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", >pci_name(dev), dev->irq)); >- >- /* >- * Make sure all (legacy) PCI IRQs are set as level-triggered. >- */ >-#ifdef CONFIG_X86 >- { >- static u16 irq_mask; >- if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { >- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level- >triggered\n", dev->irq)); >- irq_mask |= (1 << dev->irq); >- eisa_set_level_irq(dev->irq); >- } >- } >-#endif >-#ifdef CONFIG_IOSAPIC >- if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC) >- iosapic_enable_intr(dev->irq); >-#endif >+ printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI 0x%x " >+ "(%s, %s) -> IRQ %d\n", >+ pci_name(dev), 'A' + pin, irq, >+ (edge_level = ACPI_LEVEL_SENSITIVE) ? "level" : "edge", >+ (active_high_low = ACPI_ACTIVE_LOW) ? "low" : "high", >+ dev->irq); > > return_VALUE(dev->irq); >-} >- >- >-int __init >-acpi_pci_irq_init (void) >-{ >- struct pci_dev *dev = NULL; >- >- ACPI_FUNCTION_TRACE("acpi_pci_irq_init"); >- >- if (!acpi_prt.count) { >- printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ " >- "routing entries\n"); >- return_VALUE(-ENODEV); >- } >- >- /* Make sure all link devices have a valid IRQ. */ >- if (acpi_pci_link_check()) { >- return_VALUE(-ENODEV); >- } >- >-#ifdef CONFIG_X86_IO_APIC >- /* Program IOAPICs using data from PRT entries. */ >- if (acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC) >- mp_parse_prt(); >-#endif >-#ifdef CONFIG_IOSAPIC >- if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC) >- iosapic_parse_prt(); >-#endif >- >- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) !NULL) >- acpi_pci_irq_enable(dev); >- >- return_VALUE(0); > } >=== drivers/acpi/pci_link.c 1.28 vs edited ==>--- 1.28/drivers/acpi/pci_link.c Mon May 10 14:42:35 2004 >+++ edited/drivers/acpi/pci_link.c Sat May 15 14:12:35 2004 >@@ -487,13 +487,13 @@ > }; > > int >-acpi_pci_link_check (void) >+acpi_irq_penalty_init(void) > { > struct list_head *node = NULL; > struct acpi_pci_link *link = NULL; > int i = 0; > >- ACPI_FUNCTION_TRACE("acpi_pci_link_check"); >+ ACPI_FUNCTION_TRACE("acpi_irq_penalty_init"); > > /* > * Update penalties to facilitate IRQ balancing. >=== drivers/serial/8250_acpi.c 1.8 vs edited ==>--- 1.8/drivers/serial/8250_acpi.c Mon Mar 15 15:53:32 2004 >+++ edited/drivers/serial/8250_acpi.c Sat May 15 14:12:35 2004 >@@ -58,28 +58,18 @@ > static acpi_status acpi_serial_ext_irq(struct serial_struct *req, > struct acpi_resource_ext_irq *ext_irq) > { >- if (ext_irq->number_of_interrupts > 0) { >-#ifdef CONFIG_IA64 >- req->irq = acpi_register_irq(ext_irq->interrupts[0], >- ext_irq->active_high_low, ext_irq->edge_level); >-#else >- req->irq = ext_irq->interrupts[0]; >-#endif >- } >+ if (ext_irq->number_of_interrupts > 0) >+ req->irq = acpi_register_gsi(ext_irq->interrupts[0], >+ ext_irq->edge_level, ext_irq->active_high_low); > return AE_OK; > } > > static acpi_status acpi_serial_irq(struct serial_struct *req, > struct acpi_resource_irq *irq) > { >- if (irq->number_of_interrupts > 0) { >-#ifdef CONFIG_IA64 >- req->irq = acpi_register_irq(irq->interrupts[0], >- irq->active_high_low, irq->edge_level); >-#else >- req->irq = irq->interrupts[0]; >-#endif >- } >+ if (irq->number_of_interrupts > 0) >+ req->irq = acpi_register_gsi(irq->interrupts[0], >+ irq->edge_level, irq->active_high_low); > return AE_OK; > } > >=== drivers/serial/8250_hcdp.c 1.6 vs edited ==>--- 1.6/drivers/serial/8250_hcdp.c Tue May 4 10:54:32 2004 >+++ edited/drivers/serial/8250_hcdp.c Sat May 15 14:12:36 2004 >@@ -183,16 +183,12 @@ > } > > if (HCDP_IRQ_SUPPORTED(hcdp_dev)) { >-#ifdef CONFIG_IA64 > if (HCDP_PCI_UART(hcdp_dev)) >- port.irq = acpi_register_irq(gsi, >- ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); >+ port.irq = acpi_register_gsi(gsi, >+ ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); > else >- port.irq = acpi_register_irq(gsi, >- ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE); >-#else >- port.irq = gsi; >-#endif >+ port.irq = acpi_register_gsi(gsi, >+ ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH); > port.flags |= UPF_AUTO_IRQ; > > if (HCDP_PCI_UART(hcdp_dev)) >=== include/acpi/acpi_drivers.h 1.17 vs edited ==>--- 1.17/include/acpi/acpi_drivers.h Mon Dec 15 17:46:29 2003 >+++ edited/include/acpi/acpi_drivers.h Sat May 15 14:12:36 2004 >@@ -55,7 +55,7 @@ > > /* ACPI PCI Interrupt Link (pci_link.c) */ > >-int acpi_pci_link_check (void); >+int acpi_irq_penalty_init (void); > int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, >int* active_high_low); > > /* ACPI PCI Interrupt Routing (pci_irq.c) */ >=== include/asm-i386/mpspec.h 1.20 vs edited ==>--- 1.20/include/asm-i386/mpspec.h Mon Apr 12 11:55:30 2004 >+++ edited/include/asm-i386/mpspec.h Sat May 15 14:12:37 2004 >@@ -33,7 +33,7 @@ > extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); > extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, >u32 gsi); > extern void mp_config_acpi_legacy_irqs (void); >-extern void mp_parse_prt (void); >+extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low); > #endif /*CONFIG_ACPI_BOOT*/ > > #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) >=== include/asm-ia64/iosapic.h 1.13 vs edited ==>--- 1.13/include/asm-ia64/iosapic.h Fri Feb 27 04:39:17 2004 >+++ edited/include/asm-ia64/iosapic.h Sat May 15 14:12:37 2004 >@@ -60,7 +60,6 @@ > unsigned int gsi_base); > extern int gsi_to_vector (unsigned int gsi); > extern int gsi_to_irq (unsigned int gsi); >-extern void __init iosapic_parse_prt (void); > extern void iosapic_enable_intr (unsigned int vector); > extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity, > unsigned long trigger); >=== include/asm-x86_64/mpspec.h 1.11 vs edited ==>--- 1.11/include/asm-x86_64/mpspec.h Mon Apr 12 11:55:30 2004 >+++ edited/include/asm-x86_64/mpspec.h Sat May 15 14:12:37 2004 >@@ -189,7 +189,7 @@ > extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); > extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, >u32 gsi); > extern void mp_config_acpi_legacy_irqs (void); >-extern void mp_parse_prt (void); >+extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low); > #endif /*CONFIG_X86_IO_APIC*/ > #endif > >=== include/linux/acpi.h 1.33 vs edited ==>--- 1.33/include/linux/acpi.h Fri Apr 2 06:48:53 2004 >+++ edited/include/linux/acpi.h Sat May 15 14:12:38 2004 >@@ -437,7 +437,7 @@ > struct pci_dev; > > int acpi_pci_irq_enable (struct pci_dev *dev); >-int acpi_pci_irq_init (void); >+unsigned int acpi_register_gsi (u32 gsi, int edge_level, int >active_high_low); > int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); > > struct acpi_pci_driver { > > >------------------------------------------------------- >This SF.Net email is sponsored by: SourceForge.net Broadband >Sign-up now for SourceForge Broadband and get the fastest >6.0/768 connection for only $19.95/mo for the first 3 months! >http://ads.osdn.com/?ad_id%62&alloc_ida84&op=click >_______________________________________________ >Acpi-devel mailing list >Acpi-devel@lists.sourceforge.net >https://lists.sourceforge.net/lists/listinfo/acpi-devel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework 2004-05-17 9:58 [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework Li, Shaohua @ 2004-05-17 15:41 ` Bjorn Helgaas 2004-05-17 16:16 ` Kenji Kaneshige 0 siblings, 1 reply; 5+ messages in thread From: Bjorn Helgaas @ 2004-05-17 15:41 UTC (permalink / raw) To: Li, Shaohua Cc: acpi-devel, Brown, Len, David Mosberger, Andi Kleen, Nakajima, Jun, linux-ia64 On Monday 17 May 2004 3:58 am, Li, Shaohua wrote: > For the IOSAPIC, your patch mask interrupts in initialization, but > should we mask platform interrupt? I mask the interrupt in the IOSAPIC when programming the RTE. This IOSAPIC programming happens before request_irq(), so I think it makes sense to leave the RTE masked, because there's nothing set up to do anything with an interrupt if it occurs. If somebody's actually interested in the interrupt, there should be a later request_irq() call, which will unmask the RTE via the request_irq->setup_irq->startup path. The only ia64 platform interrupt we do anything with is ACPI_INTERRUPT_CPEI. My usual test boxes don't support CPEI, but from reading the code, iosapic_register_platform_intr() programs the RTE (leaving it masked) when we parse the MADT. Then ia64_mca_init() looks up the vector assigned for CPEI and calls setup_irq() for it, which will unmask the RTE. Maybe we could do a little rework to make ia64_mca_init() use request_irq() (similar to how acpi_os_install_interrupt_handler() works), but I think the current scheme should work. Or do you have evidence to the contrary? Bjorn ^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework 2004-05-17 15:41 ` Bjorn Helgaas @ 2004-05-17 16:16 ` Kenji Kaneshige 2004-05-17 18:41 ` Bjorn Helgaas 0 siblings, 1 reply; 5+ messages in thread From: Kenji Kaneshige @ 2004-05-17 16:16 UTC (permalink / raw) To: 'Bjorn Helgaas', 'Li, Shaohua' Cc: acpi-devel, 'Brown, Len', 'David Mosberger', 'Andi Kleen', 'Nakajima, Jun', linux-ia64 I agree with you about CPEI, but how about PMI and INIT? I think PMI and INIT need to be unmasked in somewhere. Thanks, Kenji Kaneshige -----Original Message----- From: linux-ia64-owner@vger.kernel.org [mailto:linux-ia64-owner@vger.kernel.org] On Behalf Of Bjorn Helgaas Sent: Tuesday, May 18, 2004 12:42 AM To: Li, Shaohua Cc: acpi-devel@lists.sourceforge.net; Brown, Len; David Mosberger; Andi Kleen; Nakajima, Jun; linux-ia64@vger.kernel.org Subject: Re: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework On Monday 17 May 2004 3:58 am, Li, Shaohua wrote: > For the IOSAPIC, your patch mask interrupts in initialization, but > should we mask platform interrupt? I mask the interrupt in the IOSAPIC when programming the RTE. This IOSAPIC programming happens before request_irq(), so I think it makes sense to leave the RTE masked, because there's nothing set up to do anything with an interrupt if it occurs. If somebody's actually interested in the interrupt, there should be a later request_irq() call, which will unmask the RTE via the request_irq->setup_irq->startup path. The only ia64 platform interrupt we do anything with is ACPI_INTERRUPT_CPEI. My usual test boxes don't support CPEI, but from reading the code, iosapic_register_platform_intr() programs the RTE (leaving it masked) when we parse the MADT. Then ia64_mca_init() looks up the vector assigned for CPEI and calls setup_irq() for it, which will unmask the RTE. Maybe we could do a little rework to make ia64_mca_init() use request_irq() (similar to how acpi_os_install_interrupt_handler() works), but I think the current scheme should work. Or do you have evidence to the contrary? Bjorn - To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework 2004-05-17 16:16 ` Kenji Kaneshige @ 2004-05-17 18:41 ` Bjorn Helgaas 2004-05-18 9:30 ` Kenji Kaneshige 0 siblings, 1 reply; 5+ messages in thread From: Bjorn Helgaas @ 2004-05-17 18:41 UTC (permalink / raw) To: Kenji Kaneshige Cc: 'Li, Shaohua', acpi-devel, 'Brown, Len', 'David Mosberger', 'Andi Kleen', 'Nakajima, Jun', linux-ia64 On Monday 17 May 2004 10:16 am, Kenji Kaneshige wrote: > I agree with you about CPEI, but how about PMI and INIT? > I think PMI and INIT need to be unmasked in somewhere. Yes, you're right. The following patch unmasks platform interrupt IOSAPIC entries (except for CPEI) when we process them from the MADT. Out of curiosity, do you have a machine that routes INIT or PMI through an IOSAPIC? It's certainly allowed, and we should support it, but the HP and Intel boxes I've seen don't seem to do that. === arch/i386/kernel/mpparse.c 1.71 vs edited ==--- 1.71/arch/i386/kernel/mpparse.c Fri Apr 30 23:27:25 2004 +++ edited/arch/i386/kernel/mpparse.c Mon May 17 10:39:37 2004 @@ -1027,94 +1027,58 @@ extern FADT_DESCRIPTOR acpi_fadt; -#ifdef CONFIG_ACPI_PCI +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ + +#ifdef CONFIG_X86_IO_APIC -void __init mp_parse_prt (void) +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) { - struct list_head *node = NULL; - struct acpi_prt_entry *entry = NULL; int ioapic = -1; int ioapic_pin = 0; - int gsi = 0; int idx, bit = 0; - int edge_level = 0; - int active_high_low = 0; - /* - * Parsing through the PCI Interrupt Routing Table (PRT) and program - * routing for all entries. - */ - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int = gsi) + return; + + ioapic = mp_find_ioapic(gsi); + if (ioapic < 0) { + printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi); + return; + } + + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; - /* Need to get gsi for dynamic entry */ - if (entry->link.handle) { - gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); - if (!gsi) - continue; - } - else { - /* Hardwired GSI. Assume PCI standard settings */ - gsi = entry->link.index; - edge_level = 1; - active_high_low = 1; - } - - /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_fadt.sci_int = gsi) { - /* we still need to set entry's irq */ - acpi_gsi_to_irq(gsi, &entry->irq); - continue; - } - - ioapic = mp_find_ioapic(gsi); - if (ioapic < 0) - continue; - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; - - if (es7000_plat) { - if (!ioapic && (gsi < 16)) - gsi += 16; - } - - /* - * Avoid pin reprogramming. PRTs typically include entries - * with redundant pin->gsi mappings (but unique PCI devices); - * we only only program the IOAPIC on the first. - */ - bit = ioapic_pin % 32; - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); - if (idx > 3) { - printk(KERN_ERR "Invalid reference to IOAPIC pin " - "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, - ioapic_pin); - continue; - } - if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { - Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", - mp_ioapic_routing[ioapic].apic_id, ioapic_pin); - acpi_gsi_to_irq(gsi, &entry->irq); - continue; - } - - mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); - - if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) { - acpi_gsi_to_irq(gsi, &entry->irq); - } - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s %s\n", - entry->id.segment, entry->id.bus, - entry->id.device, ('A' + entry->pin), - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, - entry->irq, edge_level ? "level" : "edge", - active_high_low ? "low" : "high"); + if (es7000_plat) { + if (!ioapic && (gsi < 16)) + gsi += 16; } - print_IO_APIC(); + /* + * Avoid pin reprogramming. PRTs typically include entries + * with redundant pin->gsi mappings (but unique PCI devices); + * we only program the IOAPIC on the first. + */ + bit = ioapic_pin % 32; + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); + if (idx > 3) { + printk(KERN_ERR "Invalid reference to IOAPIC pin " + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, + ioapic_pin); + return; + } + if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { + Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", + mp_ioapic_routing[ioapic].apic_id, ioapic_pin); + return; + } - return; + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); + + io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, + edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1, + active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1); } -#endif /*CONFIG_ACPI_PCI*/ -#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ +#endif /*CONFIG_X86_IO_APIC*/ #endif /*CONFIG_ACPI_BOOT*/ === arch/i386/kernel/acpi/boot.c 1.61 vs edited ==--- 1.61/arch/i386/kernel/acpi/boot.c Sat May 15 00:11:59 2004 +++ edited/arch/i386/kernel/acpi/boot.c Mon May 17 10:39:37 2004 @@ -428,6 +428,28 @@ return 0; } +unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) +{ + static u16 irq_mask; + unsigned int irq; + extern void eisa_set_level_irq(unsigned int irq); + + /* + * Make sure all (legacy) PCI IRQs are set as level-triggered. + */ + if ((gsi < 16) && !((1 << gsi) & irq_mask)) { + printk(KERN_DEBUG PREFIX "Setting GSI 0x%x as level-triggered\n", gsi); + irq_mask |= (1 << gsi); + eisa_set_level_irq(gsi); + } + +#ifdef CONFIG_X86_IO_APIC + mp_register_gsi(gsi, edge_level, active_high_low); +#endif + acpi_gsi_to_irq(gsi, &irq); + return irq; +} + static unsigned long __init acpi_scan_rsdp ( unsigned long start, === arch/i386/pci/acpi.c 1.13 vs edited ==--- 1.13/arch/i386/pci/acpi.c Fri Apr 30 23:27:25 2004 +++ edited/arch/i386/pci/acpi.c Mon May 17 10:39:37 2004 @@ -1,6 +1,8 @@ #include <linux/pci.h> #include <linux/acpi.h> #include <linux/init.h> +#include <linux/irq.h> +#include <asm/hw_irq.h> #include "pci.h" struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) @@ -15,18 +17,28 @@ static int __init pci_acpi_init(void) { + struct pci_dev *dev = NULL; + if (pcibios_scanned) return 0; - if (!acpi_noirq) { - if (!acpi_pci_irq_init()) { - printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); - pcibios_scanned++; - pcibios_enable_irq = acpi_pci_irq_enable; - } else - printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n"); + if (acpi_noirq) + return 0; - } + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); + acpi_irq_penalty_init(); + pcibios_scanned++; + pcibios_enable_irq = acpi_pci_irq_enable; + + /* + * PCI IRQ routing is set up by pci_enable_device(), but we + * also do it here in case there are still broken drivers that + * don't use pci_enable_device(). + */ + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + acpi_pci_irq_enable(dev); + + print_IO_APIC(); return 0; } === arch/ia64/kernel/acpi.c 1.69 vs edited ==--- 1.69/arch/ia64/kernel/acpi.c Sat May 15 00:11:59 2004 +++ edited/arch/ia64/kernel/acpi.c Mon May 17 10:39:37 2004 @@ -508,9 +508,14 @@ #endif /* CONFIG_ACPI_NUMA */ unsigned int -acpi_register_gsi (u32 gsi, int polarity, int trigger) +acpi_register_gsi (u32 gsi, int edge_level, int active_high_low) { - return acpi_register_irq(gsi, polarity, trigger); + if (has_8259 && gsi < 16) + return isa_irq_to_vector(gsi); + + return iosapic_register_intr(gsi, + (active_high_low = ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (edge_level = ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); } EXPORT_SYMBOL(acpi_register_gsi); @@ -535,7 +540,7 @@ if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) acpi_legacy_devices = 1; - acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); + acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return 0; } @@ -648,17 +653,5 @@ } return 0; } - -int -acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) -{ - if (has_8259 && gsi < 16) - return isa_irq_to_vector(gsi); - - return iosapic_register_intr(gsi, - (polarity = ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, - (trigger = ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); -} -EXPORT_SYMBOL(acpi_register_irq); #endif /* CONFIG_ACPI_BOOT */ === arch/ia64/kernel/iosapic.c 1.42 vs edited ==--- 1.42/arch/ia64/kernel/iosapic.c Fri May 14 20:00:12 2004 +++ edited/arch/ia64/kernel/iosapic.c Mon May 17 11:51:35 2004 @@ -512,6 +512,42 @@ } } +static unsigned int +dest_cpu_lid (void) +{ +#ifdef CONFIG_SMP + static int cpu = -1; + + /* + * If the platform supports redirection via XTP, let it + * distribute interrupts. + */ + if (smp_int_redirect & SMP_IRQ_REDIRECTION) + return hard_smp_processor_id(); + + /* + * Some interrupts (ACPI SCI, for instance) are registered + * before the BSP is marked as online. + */ + if (!cpu_online(smp_processor_id())) + return hard_smp_processor_id(); + + /* + * Otherwise, round-robin interrupt vectors across all the + * processors. (It'd be nice if we could be smarter in the + * case of NUMA.) + */ + do { + if (++cpu >= NR_CPUS) + cpu = 0; + } while (!cpu_online(cpu)); + + return cpu_physical_id(cpu); +#else + return hard_smp_processor_id(); +#endif +} + /* * ACPI can describe IOSAPIC interrupts via static tables and namespace * methods. This provides an interface to register those interrupts and @@ -522,21 +558,35 @@ unsigned long polarity, unsigned long trigger) { int vector; - unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; + unsigned int dest; + unsigned long flags; - vector = gsi_to_vector(gsi); - if (vector < 0) - vector = assign_irq_vector(AUTO_ASSIGN); + /* + * If this GSI has already been registered (i.e., it's a + * shared interrupt, or we lost a race to register it), + * don't touch the RTE. + */ + spin_lock_irqsave(&iosapic_lock, flags); + { + vector = gsi_to_vector(gsi); + if (vector > 0) { + spin_unlock_irqrestore(&iosapic_lock, flags); + return vector; + } - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, - polarity, trigger); + vector = assign_irq_vector(AUTO_ASSIGN); + dest = dest_cpu_lid(); + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, + polarity, trigger); + } + spin_unlock_irqrestore(&iosapic_lock, flags); - printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", - gsi, (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), - (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector); + printk(KERN_INFO "GSI 0x%x (%s, %s) -> CPU %d (0x%04x) vector %d\n", + gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"), + (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), + cpu_logical_id(dest), dest, vector); - /* program the IOSAPIC routing table */ - set_rte(vector, dest, 0); + set_rte(vector, dest, 1); return vector; } @@ -549,8 +599,9 @@ int iosapic_vector, u16 eid, u16 id, unsigned long polarity, unsigned long trigger) { + static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"}; unsigned char delivery; - int vector; + int vector, mask = 0; unsigned int dest = ((id << 8) | eid) & 0xffff; switch (int_type) { @@ -570,21 +621,22 @@ case ACPI_INTERRUPT_CPEI: vector = IA64_CPE_VECTOR; delivery = IOSAPIC_LOWEST_PRIORITY; + mask = 1; break; default: - printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n"); + printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); return -1; } - register_intr(gsi, vector, delivery, polarity, - trigger); + register_intr(gsi, vector, delivery, polarity, trigger); - printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", - int_type, gsi, (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), - (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector); + printk(KERN_INFO "PLATFORM int %s (0x%x): GSI 0x%x (%s, %s) -> CPU %d (0x%04x) vector %d\n", + int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", + int_type, gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"), + (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), + cpu_logical_id(dest), dest, vector); - /* program the IOSAPIC routing table */ - set_rte(vector, dest, 0); + set_rte(vector, dest, mask); return vector; } @@ -599,18 +651,18 @@ unsigned long trigger) { int vector; - unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; + unsigned int dest = hard_smp_processor_id(); vector = isa_irq_to_vector(isa_irq); register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); - DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n", - isa_irq, gsi, polarity = IOSAPIC_POL_HIGH ? "high" : "low", - trigger = IOSAPIC_EDGE ? "edge" : "level", dest, vector); + DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU %d (0x%04x) vector %d\n", + isa_irq, gsi, trigger = IOSAPIC_EDGE ? "edge" : "level", + polarity = IOSAPIC_POL_HIGH ? "high" : "low", + cpu_logical_id(dest), dest, vector); - /* program the IOSAPIC routing table */ - set_rte(vector, dest, 0); + set_rte(vector, dest, 1); } void __init @@ -665,104 +717,3 @@ iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } } - -void -iosapic_enable_intr (unsigned int vector) -{ - unsigned int dest; - irq_desc_t *desc; - - /* - * In the case of a shared interrupt, do not re-route the vector, and - * especially do not mask a running interrupt (startup will not get - * called for a shared interrupt). - */ - desc = irq_descp(vector); - if (desc->action) - return; - -#ifdef CONFIG_SMP - /* - * For platforms that do not support interrupt redirect via the XTP interface, we - * can round-robin the PCI device interrupts to the processors - */ - if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { - static int cpu_index = -1; - - do - if (++cpu_index >= NR_CPUS) - cpu_index = 0; - while (!cpu_online(cpu_index)); - - dest = cpu_physical_id(cpu_index) & 0xffff; - } else { - /* - * Direct the interrupt vector to the current cpu, platform redirection - * will distribute them. - */ - dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; - } -#else - /* direct the interrupt vector to the running cpu id */ - dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; -#endif - set_rte(vector, dest, 1); - - printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n", - vector, dest); -} - -#ifdef CONFIG_ACPI_PCI - -void __init -iosapic_parse_prt (void) -{ - struct acpi_prt_entry *entry; - struct list_head *node; - unsigned int gsi; - int vector; - char pci_id[16]; - struct hw_interrupt_type *irq_type = &irq_type_iosapic_level; - irq_desc_t *idesc; - - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); - - /* We're only interested in static (non-link) entries. */ - if (entry->link.handle) - continue; - - gsi = entry->link.index; - - vector = gsi_to_vector(gsi); - if (vector < 0) { - if (find_iosapic(gsi) < 0) - continue; - - /* allocate a vector for this interrupt line */ - if (pcat_compat && (gsi < 16)) - vector = isa_irq_to_vector(gsi); - else - /* new GSI; allocate a vector for it */ - vector = assign_irq_vector(AUTO_ASSIGN); - - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, - IOSAPIC_LEVEL); - } - entry->irq = vector; - snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]", - entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin); - - /* - * If vector was previously initialized to a different - * handler, re-initialize. - */ - idesc = irq_descp(vector); - if (idesc->handler != irq_type) - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, - IOSAPIC_LEVEL); - - } -} - -#endif /* CONFIG_ACPI */ === arch/ia64/pci/pci.c 1.48 vs edited ==--- 1.48/arch/ia64/pci/pci.c Wed Apr 21 15:26:09 2004 +++ edited/arch/ia64/pci/pci.c Mon May 17 10:39:38 2004 @@ -134,10 +134,18 @@ static int __init pci_acpi_init (void) { - if (!acpi_pci_irq_init()) - printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); - else - printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n"); + struct pci_dev *dev = NULL; + + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); + + /* + * PCI IRQ routing is set up by pci_enable_device(), but we + * also do it here in case there are still broken drivers that + * don't use pci_enable_device(). + */ + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + acpi_pci_irq_enable(dev); + return 0; } === arch/x86_64/kernel/mpparse.c 1.27 vs edited ==--- 1.27/arch/x86_64/kernel/mpparse.c Sat May 15 07:32:27 2004 +++ edited/arch/x86_64/kernel/mpparse.c Mon May 17 10:39:38 2004 @@ -887,88 +887,49 @@ extern FADT_DESCRIPTOR acpi_fadt; -#ifdef CONFIG_ACPI_PCI - -void __init mp_parse_prt (void) +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) { - struct list_head *node = NULL; - struct acpi_prt_entry *entry = NULL; int ioapic = -1; int ioapic_pin = 0; - int gsi = 0; int idx, bit = 0; - int edge_level = 0; - int active_high_low = 0; - /* - * Parsing through the PCI Interrupt Routing Table (PRT) and program - * routing for all static (IOAPIC-direct) entries. - */ - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int = gsi) + return; + + ioapic = mp_find_ioapic(gsi); + if (ioapic < 0) { + printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi); + return; + } - /* Need to get gsi for dynamic entry */ - if (entry->link.handle) { - gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); - if (!gsi) - continue; - } else { - /* Hardwired GSI. Assume PCI standard settings */ - gsi = entry->link.index; - edge_level = 1; - active_high_low = 1; - } - - /* Don't set up the ACPI SCI because it's already set up */ - if (acpi_fadt.sci_int = gsi) { - /* we still need to set up the entry's irq */ - acpi_gsi_to_irq(gsi, &entry->irq); - continue; - } - - ioapic = mp_find_ioapic(gsi); - if (ioapic < 0) - continue; - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; - - /* - * Avoid pin reprogramming. PRTs typically include entries - * with redundant pin->gsi mappings (but unique PCI devices); - * we only only program the IOAPIC on the first. - */ - bit = ioapic_pin % 32; - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); - if (idx > 3) { - printk(KERN_ERR "Invalid reference to IOAPIC pin " - "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, - ioapic_pin); - continue; - } - if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { - Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", - mp_ioapic_routing[ioapic].apic_id, ioapic_pin); - acpi_gsi_to_irq(gsi, &entry->irq); - continue; - } - - mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); - if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) { - acpi_gsi_to_irq(gsi, &entry->irq); - } - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", - entry->id.segment, entry->id.bus, - entry->id.device, ('A' + entry->pin), - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, - entry->irq); + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; + + /* + * Avoid pin reprogramming. PRTs typically include entries + * with redundant pin->gsi mappings (but unique PCI devices); + * we only program the IOAPIC on the first. + */ + bit = ioapic_pin % 32; + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); + if (idx > 3) { + printk(KERN_ERR "Invalid reference to IOAPIC pin " + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, + ioapic_pin); + return; + } + if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { + Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", + mp_ioapic_routing[ioapic].apic_id, ioapic_pin); + return; } - - print_IO_APIC(); - return; -} + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); -#endif /*CONFIG_ACPI_PCI*/ + io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, + edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1, + active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1); +} #endif /*CONFIG_X86_IO_APIC*/ - #endif /*CONFIG_ACPI_BOOT*/ === drivers/acpi/pci_irq.c 1.27 vs edited ==--- 1.27/drivers/acpi/pci_irq.c Sat Apr 24 00:17:22 2004 +++ edited/drivers/acpi/pci_irq.c Mon May 17 10:39:38 2004 @@ -35,12 +35,6 @@ #include <linux/pm.h> #include <linux/pci.h> #include <linux/acpi.h> -#ifdef CONFIG_X86_IO_APIC -#include <asm/mpspec.h> -#endif -#ifdef CONFIG_IOSAPIC -# include <asm/iosapic.h> -#endif #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> @@ -50,10 +44,6 @@ struct acpi_prt_list acpi_prt; -#ifdef CONFIG_X86 -extern void eisa_set_level_irq(unsigned int irq); -#endif - /* -------------------------------------------------------------------------- PCI IRQ Routing Table (PRT) Support @@ -237,12 +227,18 @@ PCI Interrupt Routing Support -------------------------------------------------------------------------- */ -int -acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin) +static int +acpi_pci_irq_lookup ( + struct pci_bus *bus, + int device, + int pin, + int *edge_level, + int *active_high_low) { struct acpi_prt_entry *entry = NULL; int segment = pci_domain_nr(bus); int bus_nr = bus->number; + int irq; ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); @@ -255,28 +251,30 @@ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); return_VALUE(0); } - - if (!entry->irq && entry->link.handle) { - entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL); - if (!entry->irq) { + + if (entry->link.handle) { + irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low); + if (!irq) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); return_VALUE(0); } - } - else if (!entry->irq) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n")); - return_VALUE(0); + } else { + irq = entry->link.index; + *edge_level = ACPI_LEVEL_SENSITIVE; + *active_high_low = ACPI_ACTIVE_LOW; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); - return_VALUE(entry->irq); + return_VALUE(irq); } static int acpi_pci_irq_derive ( struct pci_dev *dev, - int pin) + int pin, + int *edge_level, + int *active_high_low) { struct pci_dev *bridge = dev; int irq = 0; @@ -308,8 +306,8 @@ pin = bridge_pin; } - irq = acpi_pci_irq_lookup(bridge->bus, - PCI_SLOT(bridge->devfn), pin); + irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), + pin, edge_level, active_high_low); } if (!irq) { @@ -330,6 +328,8 @@ { int irq = 0; u8 pin = 0; + int edge_level = ACPI_LEVEL_SENSITIVE; + int active_high_low = ACPI_ACTIVE_LOW; ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); @@ -352,21 +352,22 @@ * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT * values override any BIOS-assigned IRQs set during boot. */ - irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin); + irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, &edge_level, &active_high_low); /* * If no PRT entry was found, we'll try to derive an IRQ from the * device's parent bridge. */ if (!irq) - irq = acpi_pci_irq_derive(dev, pin); + irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low); /* * No IRQ known to the ACPI subsystem - maybe the BIOS / * driver reported one, then use it. Exit in any case. */ if (!irq) { - printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), pci_name(dev)); + printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI", + pci_name(dev), ('A' + pin)); /* Interrupt Line values above 0xF are forbidden */ if (dev->irq && (dev->irq <= 0xF)) { printk(" - using IRQ %d\n", dev->irq); @@ -378,62 +379,14 @@ } } - dev->irq = irq; + dev->irq = acpi_register_gsi(irq, edge_level, active_high_low); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", pci_name(dev), dev->irq)); - - /* - * Make sure all (legacy) PCI IRQs are set as level-triggered. - */ -#ifdef CONFIG_X86 - { - static u16 irq_mask; - if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq)); - irq_mask |= (1 << dev->irq); - eisa_set_level_irq(dev->irq); - } - } -#endif -#ifdef CONFIG_IOSAPIC - if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC) - iosapic_enable_intr(dev->irq); -#endif + printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI 0x%x " + "(%s, %s) -> IRQ %d\n", + pci_name(dev), 'A' + pin, irq, + (edge_level = ACPI_LEVEL_SENSITIVE) ? "level" : "edge", + (active_high_low = ACPI_ACTIVE_LOW) ? "low" : "high", + dev->irq); return_VALUE(dev->irq); -} - - -int __init -acpi_pci_irq_init (void) -{ - struct pci_dev *dev = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_init"); - - if (!acpi_prt.count) { - printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ " - "routing entries\n"); - return_VALUE(-ENODEV); - } - - /* Make sure all link devices have a valid IRQ. */ - if (acpi_pci_link_check()) { - return_VALUE(-ENODEV); - } - -#ifdef CONFIG_X86_IO_APIC - /* Program IOAPICs using data from PRT entries. */ - if (acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC) - mp_parse_prt(); -#endif -#ifdef CONFIG_IOSAPIC - if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC) - iosapic_parse_prt(); -#endif - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) - acpi_pci_irq_enable(dev); - - return_VALUE(0); } === drivers/acpi/pci_link.c 1.28 vs edited ==--- 1.28/drivers/acpi/pci_link.c Mon May 10 14:42:35 2004 +++ edited/drivers/acpi/pci_link.c Mon May 17 10:39:39 2004 @@ -487,13 +487,13 @@ }; int -acpi_pci_link_check (void) +acpi_irq_penalty_init(void) { struct list_head *node = NULL; struct acpi_pci_link *link = NULL; int i = 0; - ACPI_FUNCTION_TRACE("acpi_pci_link_check"); + ACPI_FUNCTION_TRACE("acpi_irq_penalty_init"); /* * Update penalties to facilitate IRQ balancing. === drivers/serial/8250_acpi.c 1.8 vs edited ==--- 1.8/drivers/serial/8250_acpi.c Mon Mar 15 15:53:32 2004 +++ edited/drivers/serial/8250_acpi.c Mon May 17 10:39:39 2004 @@ -58,28 +58,18 @@ static acpi_status acpi_serial_ext_irq(struct serial_struct *req, struct acpi_resource_ext_irq *ext_irq) { - if (ext_irq->number_of_interrupts > 0) { -#ifdef CONFIG_IA64 - req->irq = acpi_register_irq(ext_irq->interrupts[0], - ext_irq->active_high_low, ext_irq->edge_level); -#else - req->irq = ext_irq->interrupts[0]; -#endif - } + if (ext_irq->number_of_interrupts > 0) + req->irq = acpi_register_gsi(ext_irq->interrupts[0], + ext_irq->edge_level, ext_irq->active_high_low); return AE_OK; } static acpi_status acpi_serial_irq(struct serial_struct *req, struct acpi_resource_irq *irq) { - if (irq->number_of_interrupts > 0) { -#ifdef CONFIG_IA64 - req->irq = acpi_register_irq(irq->interrupts[0], - irq->active_high_low, irq->edge_level); -#else - req->irq = irq->interrupts[0]; -#endif - } + if (irq->number_of_interrupts > 0) + req->irq = acpi_register_gsi(irq->interrupts[0], + irq->edge_level, irq->active_high_low); return AE_OK; } === drivers/serial/8250_hcdp.c 1.6 vs edited ==--- 1.6/drivers/serial/8250_hcdp.c Tue May 4 10:54:32 2004 +++ edited/drivers/serial/8250_hcdp.c Mon May 17 10:39:39 2004 @@ -183,16 +183,12 @@ } if (HCDP_IRQ_SUPPORTED(hcdp_dev)) { -#ifdef CONFIG_IA64 if (HCDP_PCI_UART(hcdp_dev)) - port.irq = acpi_register_irq(gsi, - ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); + port.irq = acpi_register_gsi(gsi, + ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); else - port.irq = acpi_register_irq(gsi, - ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE); -#else - port.irq = gsi; -#endif + port.irq = acpi_register_gsi(gsi, + ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH); port.flags |= UPF_AUTO_IRQ; if (HCDP_PCI_UART(hcdp_dev)) === include/acpi/acpi_drivers.h 1.17 vs edited ==--- 1.17/include/acpi/acpi_drivers.h Mon Dec 15 17:46:29 2003 +++ edited/include/acpi/acpi_drivers.h Mon May 17 10:39:40 2004 @@ -55,7 +55,7 @@ /* ACPI PCI Interrupt Link (pci_link.c) */ -int acpi_pci_link_check (void); +int acpi_irq_penalty_init (void); int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low); /* ACPI PCI Interrupt Routing (pci_irq.c) */ === include/asm-i386/mpspec.h 1.20 vs edited ==--- 1.20/include/asm-i386/mpspec.h Mon Apr 12 11:55:30 2004 +++ edited/include/asm-i386/mpspec.h Mon May 17 10:39:40 2004 @@ -33,7 +33,7 @@ extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); extern void mp_config_acpi_legacy_irqs (void); -extern void mp_parse_prt (void); +extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low); #endif /*CONFIG_ACPI_BOOT*/ #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) === include/asm-ia64/iosapic.h 1.13 vs edited ==--- 1.13/include/asm-ia64/iosapic.h Fri Feb 27 04:39:17 2004 +++ edited/include/asm-ia64/iosapic.h Mon May 17 10:39:40 2004 @@ -60,7 +60,6 @@ unsigned int gsi_base); extern int gsi_to_vector (unsigned int gsi); extern int gsi_to_irq (unsigned int gsi); -extern void __init iosapic_parse_prt (void); extern void iosapic_enable_intr (unsigned int vector); extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity, unsigned long trigger); === include/asm-x86_64/mpspec.h 1.11 vs edited ==--- 1.11/include/asm-x86_64/mpspec.h Mon Apr 12 11:55:30 2004 +++ edited/include/asm-x86_64/mpspec.h Mon May 17 10:39:40 2004 @@ -189,7 +189,7 @@ extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); extern void mp_config_acpi_legacy_irqs (void); -extern void mp_parse_prt (void); +extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low); #endif /*CONFIG_X86_IO_APIC*/ #endif === include/linux/acpi.h 1.33 vs edited ==--- 1.33/include/linux/acpi.h Fri Apr 2 06:48:53 2004 +++ edited/include/linux/acpi.h Mon May 17 10:39:41 2004 @@ -437,7 +437,7 @@ struct pci_dev; int acpi_pci_irq_enable (struct pci_dev *dev); -int acpi_pci_irq_init (void); +unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); struct acpi_pci_driver { ^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework 2004-05-17 18:41 ` Bjorn Helgaas @ 2004-05-18 9:30 ` Kenji Kaneshige 0 siblings, 0 replies; 5+ messages in thread From: Kenji Kaneshige @ 2004-05-18 9:30 UTC (permalink / raw) To: Bjorn Helgaas, Kenji Kaneshige Cc: 'Li, Shaohua', acpi-devel, 'Brown, Len', 'David Mosberger', 'Andi Kleen', 'Nakajima, Jun', linux-ia64 > Out of curiosity, do you have a machine that routes INIT or > PMI through an IOSAPIC? It's certainly allowed, and we should > support it, but the HP and Intel boxes I've seen don't seem to > do that. No, I don't. My machine is Tiger4. As you said, it doesn't have PMI and INIT through an IOSAPIC. Thanks, Kenji Kaneshige > -----Original Message----- > From: linux-ia64-owner@vger.kernel.org > [mailto:linux-ia64-owner@vger.kernel.org]On Behalf Of Bjorn Helgaas > Sent: Tuesday, May 18, 2004 3:41 AM > To: Kenji Kaneshige > Cc: 'Li, Shaohua'; acpi-devel@lists.sourceforge.net; 'Brown, > Len'; 'David Mosberger'; 'Andi Kleen'; 'Nakajima, Jun'; > linux-ia64@vger.kernel.org > Subject: Re: [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework > > > On Monday 17 May 2004 10:16 am, Kenji Kaneshige wrote: > > I agree with you about CPEI, but how about PMI and INIT? > > I think PMI and INIT need to be unmasked in somewhere. > > Yes, you're right. > > The following patch unmasks platform interrupt IOSAPIC entries > (except for CPEI) when we process them from the MADT. > > Out of curiosity, do you have a machine that routes INIT or > PMI through an IOSAPIC? It's certainly allowed, and we should > support it, but the HP and Intel boxes I've seen don't seem to > do that. > > === arch/i386/kernel/mpparse.c 1.71 vs edited ==> --- 1.71/arch/i386/kernel/mpparse.c Fri Apr 30 23:27:25 2004 > +++ edited/arch/i386/kernel/mpparse.c Mon May 17 10:39:37 2004 > @@ -1027,94 +1027,58 @@ > > extern FADT_DESCRIPTOR acpi_fadt; > > -#ifdef CONFIG_ACPI_PCI > +#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ > + > +#ifdef CONFIG_X86_IO_APIC > > -void __init mp_parse_prt (void) > +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) > { > - struct list_head *node = NULL; > - struct acpi_prt_entry *entry = NULL; > int ioapic = -1; > int ioapic_pin = 0; > - int gsi = 0; > int idx, bit = 0; > - int edge_level = 0; > - int active_high_low = 0; > > - /* > - * Parsing through the PCI Interrupt Routing Table (PRT) and program > - * routing for all entries. > - */ > - list_for_each(node, &acpi_prt.entries) { > - entry = list_entry(node, struct acpi_prt_entry, node); > + /* Don't set up the ACPI SCI because it's already set up */ > + if (acpi_fadt.sci_int = gsi) > + return; > + > + ioapic = mp_find_ioapic(gsi); > + if (ioapic < 0) { > + printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi); > + return; > + } > + > + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; > > - /* Need to get gsi for dynamic entry */ > - if (entry->link.handle) { > - gsi > acpi_pci_link_get_irq(entry->link.handle, entry->link.index, > &edge_level, &active_high_low); > - if (!gsi) > - continue; > - } > - else { > - /* Hardwired GSI. Assume PCI standard settings */ > - gsi = entry->link.index; > - edge_level = 1; > - active_high_low = 1; > - } > - > - /* Don't set up the ACPI SCI because it's already set up */ > - if (acpi_fadt.sci_int = gsi) { > - /* we still need to set entry's irq */ > - acpi_gsi_to_irq(gsi, &entry->irq); > - continue; > - } > - > - ioapic = mp_find_ioapic(gsi); > - if (ioapic < 0) > - continue; > - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; > - > - if (es7000_plat) { > - if (!ioapic && (gsi < 16)) > - gsi += 16; > - } > - > - /* > - * Avoid pin reprogramming. PRTs typically include > entries > - * with redundant pin->gsi mappings (but unique PCI > devices); > - * we only only program the IOAPIC on the first. > - */ > - bit = ioapic_pin % 32; > - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); > - if (idx > 3) { > - printk(KERN_ERR "Invalid reference to IOAPIC pin " > - "%d-%d\n", > mp_ioapic_routing[ioapic].apic_id, > - ioapic_pin); > - continue; > - } > - if ((1<<bit) & > mp_ioapic_routing[ioapic].pin_programmed[idx]) { > - Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", > - mp_ioapic_routing[ioapic].apic_id, > ioapic_pin); > - acpi_gsi_to_irq(gsi, &entry->irq); > - continue; > - } > - > - mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); > - > - if (!io_apic_set_pci_routing(ioapic, ioapic_pin, > gsi, edge_level, active_high_low)) { > - acpi_gsi_to_irq(gsi, &entry->irq); > - } > - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> > IRQ %d %s %s\n", > - entry->id.segment, entry->id.bus, > - entry->id.device, ('A' + entry->pin), > - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, > - entry->irq, edge_level ? "level" : "edge", > - active_high_low ? "low" : "high"); > + if (es7000_plat) { > + if (!ioapic && (gsi < 16)) > + gsi += 16; > } > > - print_IO_APIC(); > + /* > + * Avoid pin reprogramming. PRTs typically include entries > + * with redundant pin->gsi mappings (but unique PCI devices); > + * we only program the IOAPIC on the first. > + */ > + bit = ioapic_pin % 32; > + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); > + if (idx > 3) { > + printk(KERN_ERR "Invalid reference to IOAPIC pin " > + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, > + ioapic_pin); > + return; > + } > + if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { > + Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", > + mp_ioapic_routing[ioapic].apic_id, ioapic_pin); > + return; > + } > > - return; > + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); > + > + io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, > + edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1, > + active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1); > } > > -#endif /*CONFIG_ACPI_PCI*/ > -#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ > +#endif /*CONFIG_X86_IO_APIC*/ > #endif /*CONFIG_ACPI_BOOT*/ > === arch/i386/kernel/acpi/boot.c 1.61 vs edited ==> --- 1.61/arch/i386/kernel/acpi/boot.c Sat May 15 00:11:59 2004 > +++ edited/arch/i386/kernel/acpi/boot.c Mon May 17 10:39:37 2004 > @@ -428,6 +428,28 @@ > return 0; > } > > +unsigned int acpi_register_gsi(u32 gsi, int edge_level, int > active_high_low) > +{ > + static u16 irq_mask; > + unsigned int irq; > + extern void eisa_set_level_irq(unsigned int irq); > + > + /* > + * Make sure all (legacy) PCI IRQs are set as level-triggered. > + */ > + if ((gsi < 16) && !((1 << gsi) & irq_mask)) { > + printk(KERN_DEBUG PREFIX "Setting GSI 0x%x as > level-triggered\n", gsi); > + irq_mask |= (1 << gsi); > + eisa_set_level_irq(gsi); > + } > + > +#ifdef CONFIG_X86_IO_APIC > + mp_register_gsi(gsi, edge_level, active_high_low); > +#endif > + acpi_gsi_to_irq(gsi, &irq); > + return irq; > +} > + > static unsigned long __init > acpi_scan_rsdp ( > unsigned long start, > === arch/i386/pci/acpi.c 1.13 vs edited ==> --- 1.13/arch/i386/pci/acpi.c Fri Apr 30 23:27:25 2004 > +++ edited/arch/i386/pci/acpi.c Mon May 17 10:39:37 2004 > @@ -1,6 +1,8 @@ > #include <linux/pci.h> > #include <linux/acpi.h> > #include <linux/init.h> > +#include <linux/irq.h> > +#include <asm/hw_irq.h> > #include "pci.h" > > struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device > *device, int domain, int busnum) > @@ -15,18 +17,28 @@ > > static int __init pci_acpi_init(void) > { > + struct pci_dev *dev = NULL; > + > if (pcibios_scanned) > return 0; > > - if (!acpi_noirq) { > - if (!acpi_pci_irq_init()) { > - printk(KERN_INFO "PCI: Using ACPI for IRQ > routing\n"); > - pcibios_scanned++; > - pcibios_enable_irq = acpi_pci_irq_enable; > - } else > - printk(KERN_WARNING "PCI: Invalid ACPI-PCI > IRQ routing table\n"); > + if (acpi_noirq) > + return 0; > > - } > + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); > + acpi_irq_penalty_init(); > + pcibios_scanned++; > + pcibios_enable_irq = acpi_pci_irq_enable; > + > + /* > + * PCI IRQ routing is set up by pci_enable_device(), but we > + * also do it here in case there are still broken drivers that > + * don't use pci_enable_device(). > + */ > + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) > + acpi_pci_irq_enable(dev); > + > + print_IO_APIC(); > > return 0; > } > === arch/ia64/kernel/acpi.c 1.69 vs edited ==> --- 1.69/arch/ia64/kernel/acpi.c Sat May 15 00:11:59 2004 > +++ edited/arch/ia64/kernel/acpi.c Mon May 17 10:39:37 2004 > @@ -508,9 +508,14 @@ > #endif /* CONFIG_ACPI_NUMA */ > > unsigned int > -acpi_register_gsi (u32 gsi, int polarity, int trigger) > +acpi_register_gsi (u32 gsi, int edge_level, int active_high_low) > { > - return acpi_register_irq(gsi, polarity, trigger); > + if (has_8259 && gsi < 16) > + return isa_irq_to_vector(gsi); > + > + return iosapic_register_intr(gsi, > + (active_high_low = ACPI_ACTIVE_HIGH) ? > IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, > + (edge_level = ACPI_EDGE_SENSITIVE) ? > IOSAPIC_EDGE : IOSAPIC_LEVEL); > } > EXPORT_SYMBOL(acpi_register_gsi); > > @@ -535,7 +540,7 @@ > if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) > acpi_legacy_devices = 1; > > - acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, > ACPI_LEVEL_SENSITIVE); > + acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, > ACPI_ACTIVE_LOW); > return 0; > } > > @@ -648,17 +653,5 @@ > } > return 0; > } > - > -int > -acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) > -{ > - if (has_8259 && gsi < 16) > - return isa_irq_to_vector(gsi); > - > - return iosapic_register_intr(gsi, > - (polarity = ACPI_ACTIVE_HIGH) ? > IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, > - (trigger = ACPI_EDGE_SENSITIVE) ? > IOSAPIC_EDGE : IOSAPIC_LEVEL); > -} > -EXPORT_SYMBOL(acpi_register_irq); > > #endif /* CONFIG_ACPI_BOOT */ > === arch/ia64/kernel/iosapic.c 1.42 vs edited ==> --- 1.42/arch/ia64/kernel/iosapic.c Fri May 14 20:00:12 2004 > +++ edited/arch/ia64/kernel/iosapic.c Mon May 17 11:51:35 2004 > @@ -512,6 +512,42 @@ > } > } > > +static unsigned int > +dest_cpu_lid (void) > +{ > +#ifdef CONFIG_SMP > + static int cpu = -1; > + > + /* > + * If the platform supports redirection via XTP, let it > + * distribute interrupts. > + */ > + if (smp_int_redirect & SMP_IRQ_REDIRECTION) > + return hard_smp_processor_id(); > + > + /* > + * Some interrupts (ACPI SCI, for instance) are registered > + * before the BSP is marked as online. > + */ > + if (!cpu_online(smp_processor_id())) > + return hard_smp_processor_id(); > + > + /* > + * Otherwise, round-robin interrupt vectors across all the > + * processors. (It'd be nice if we could be smarter in the > + * case of NUMA.) > + */ > + do { > + if (++cpu >= NR_CPUS) > + cpu = 0; > + } while (!cpu_online(cpu)); > + > + return cpu_physical_id(cpu); > +#else > + return hard_smp_processor_id(); > +#endif > +} > + > /* > * ACPI can describe IOSAPIC interrupts via static tables and namespace > * methods. This provides an interface to register those interrupts and > @@ -522,21 +558,35 @@ > unsigned long polarity, unsigned long trigger) > { > int vector; > - unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; > + unsigned int dest; > + unsigned long flags; > > - vector = gsi_to_vector(gsi); > - if (vector < 0) > - vector = assign_irq_vector(AUTO_ASSIGN); > + /* > + * If this GSI has already been registered (i.e., it's a > + * shared interrupt, or we lost a race to register it), > + * don't touch the RTE. > + */ > + spin_lock_irqsave(&iosapic_lock, flags); > + { > + vector = gsi_to_vector(gsi); > + if (vector > 0) { > + spin_unlock_irqrestore(&iosapic_lock, flags); > + return vector; > + } > > - register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, > - polarity, trigger); > + vector = assign_irq_vector(AUTO_ASSIGN); > + dest = dest_cpu_lid(); > + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, > + polarity, trigger); > + } > + spin_unlock_irqrestore(&iosapic_lock, flags); > > - printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", > - gsi, (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), > - (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector); > + printk(KERN_INFO "GSI 0x%x (%s, %s) -> CPU %d (0x%04x) vector %d\n", > + gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"), > + (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), > + cpu_logical_id(dest), dest, vector); > > - /* program the IOSAPIC routing table */ > - set_rte(vector, dest, 0); > + set_rte(vector, dest, 1); > return vector; > } > > @@ -549,8 +599,9 @@ > int iosapic_vector, u16 eid, u16 id, > unsigned long polarity, unsigned > long trigger) > { > + static const char * const name[] = {"unknown", "PMI", > "INIT", "CPEI"}; > unsigned char delivery; > - int vector; > + int vector, mask = 0; > unsigned int dest = ((id << 8) | eid) & 0xffff; > > switch (int_type) { > @@ -570,21 +621,22 @@ > case ACPI_INTERRUPT_CPEI: > vector = IA64_CPE_VECTOR; > delivery = IOSAPIC_LOWEST_PRIORITY; > + mask = 1; > break; > default: > - printk(KERN_ERR "iosapic_register_platform_irq(): > invalid int type\n"); > + printk(KERN_ERR "iosapic_register_platform_irq(): > invalid int type 0x%x\n", int_type); > return -1; > } > > - register_intr(gsi, vector, delivery, polarity, > - trigger); > + register_intr(gsi, vector, delivery, polarity, trigger); > > - printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU > 0x%04x vector %d\n", > - int_type, gsi, (polarity = IOSAPIC_POL_HIGH ? > "high" : "low"), > - (trigger = IOSAPIC_EDGE ? "edge" : "level"), dest, vector); > + printk(KERN_INFO "PLATFORM int %s (0x%x): GSI 0x%x (%s, %s) > -> CPU %d (0x%04x) vector %d\n", > + int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", > + int_type, gsi, (trigger = IOSAPIC_EDGE ? "edge" : "level"), > + (polarity = IOSAPIC_POL_HIGH ? "high" : "low"), > + cpu_logical_id(dest), dest, vector); > > - /* program the IOSAPIC routing table */ > - set_rte(vector, dest, 0); > + set_rte(vector, dest, mask); > return vector; > } > > @@ -599,18 +651,18 @@ > unsigned long trigger) > { > int vector; > - unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; > + unsigned int dest = hard_smp_processor_id(); > > vector = isa_irq_to_vector(isa_irq); > > register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, > polarity, trigger); > > - DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n", > - isa_irq, gsi, polarity = IOSAPIC_POL_HIGH ? "high" : "low", > - trigger = IOSAPIC_EDGE ? "edge" : "level", dest, vector); > + DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU %d (0x%04x) > vector %d\n", > + isa_irq, gsi, trigger = IOSAPIC_EDGE ? "edge" : "level", > + polarity = IOSAPIC_POL_HIGH ? "high" : "low", > + cpu_logical_id(dest), dest, vector); > > - /* program the IOSAPIC routing table */ > - set_rte(vector, dest, 0); > + set_rte(vector, dest, 1); > } > > void __init > @@ -665,104 +717,3 @@ > iosapic_override_isa_irq(isa_irq, isa_irq, > IOSAPIC_POL_HIGH, IOSAPIC_EDGE); > } > } > - > -void > -iosapic_enable_intr (unsigned int vector) > -{ > - unsigned int dest; > - irq_desc_t *desc; > - > - /* > - * In the case of a shared interrupt, do not re-route the > vector, and > - * especially do not mask a running interrupt (startup will not get > - * called for a shared interrupt). > - */ > - desc = irq_descp(vector); > - if (desc->action) > - return; > - > -#ifdef CONFIG_SMP > - /* > - * For platforms that do not support interrupt redirect via > the XTP interface, we > - * can round-robin the PCI device interrupts to the processors > - */ > - if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { > - static int cpu_index = -1; > - > - do > - if (++cpu_index >= NR_CPUS) > - cpu_index = 0; > - while (!cpu_online(cpu_index)); > - > - dest = cpu_physical_id(cpu_index) & 0xffff; > - } else { > - /* > - * Direct the interrupt vector to the current cpu, > platform redirection > - * will distribute them. > - */ > - dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; > - } > -#else > - /* direct the interrupt vector to the running cpu id */ > - dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; > -#endif > - set_rte(vector, dest, 1); > - > - printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n", > - vector, dest); > -} > - > -#ifdef CONFIG_ACPI_PCI > - > -void __init > -iosapic_parse_prt (void) > -{ > - struct acpi_prt_entry *entry; > - struct list_head *node; > - unsigned int gsi; > - int vector; > - char pci_id[16]; > - struct hw_interrupt_type *irq_type = &irq_type_iosapic_level; > - irq_desc_t *idesc; > - > - list_for_each(node, &acpi_prt.entries) { > - entry = list_entry(node, struct acpi_prt_entry, node); > - > - /* We're only interested in static (non-link) entries. */ > - if (entry->link.handle) > - continue; > - > - gsi = entry->link.index; > - > - vector = gsi_to_vector(gsi); > - if (vector < 0) { > - if (find_iosapic(gsi) < 0) > - continue; > - > - /* allocate a vector for this interrupt line */ > - if (pcat_compat && (gsi < 16)) > - vector = isa_irq_to_vector(gsi); > - else > - /* new GSI; allocate a vector for it */ > - vector = assign_irq_vector(AUTO_ASSIGN); > - > - register_intr(gsi, vector, > IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, > - IOSAPIC_LEVEL); > - } > - entry->irq = vector; > - snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]", > - entry->id.segment, entry->id.bus, > entry->id.device, 'A' + entry->pin); > - > - /* > - * If vector was previously initialized to a different > - * handler, re-initialize. > - */ > - idesc = irq_descp(vector); > - if (idesc->handler != irq_type) > - register_intr(gsi, vector, > IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, > - IOSAPIC_LEVEL); > - > - } > -} > - > -#endif /* CONFIG_ACPI */ > === arch/ia64/pci/pci.c 1.48 vs edited ==> --- 1.48/arch/ia64/pci/pci.c Wed Apr 21 15:26:09 2004 > +++ edited/arch/ia64/pci/pci.c Mon May 17 10:39:38 2004 > @@ -134,10 +134,18 @@ > static int __init > pci_acpi_init (void) > { > - if (!acpi_pci_irq_init()) > - printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); > - else > - printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ > routing table\n"); > + struct pci_dev *dev = NULL; > + > + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); > + > + /* > + * PCI IRQ routing is set up by pci_enable_device(), but we > + * also do it here in case there are still broken drivers that > + * don't use pci_enable_device(). > + */ > + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) > + acpi_pci_irq_enable(dev); > + > return 0; > } > > === arch/x86_64/kernel/mpparse.c 1.27 vs edited ==> --- 1.27/arch/x86_64/kernel/mpparse.c Sat May 15 07:32:27 2004 > +++ edited/arch/x86_64/kernel/mpparse.c Mon May 17 10:39:38 2004 > @@ -887,88 +887,49 @@ > > extern FADT_DESCRIPTOR acpi_fadt; > > -#ifdef CONFIG_ACPI_PCI > - > -void __init mp_parse_prt (void) > +void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) > { > - struct list_head *node = NULL; > - struct acpi_prt_entry *entry = NULL; > int ioapic = -1; > int ioapic_pin = 0; > - int gsi = 0; > int idx, bit = 0; > - int edge_level = 0; > - int active_high_low = 0; > > - /* > - * Parsing through the PCI Interrupt Routing Table (PRT) and program > - * routing for all static (IOAPIC-direct) entries. > - */ > - list_for_each(node, &acpi_prt.entries) { > - entry = list_entry(node, struct acpi_prt_entry, node); > + /* Don't set up the ACPI SCI because it's already set up */ > + if (acpi_fadt.sci_int = gsi) > + return; > + > + ioapic = mp_find_ioapic(gsi); > + if (ioapic < 0) { > + printk(KERN_WARNING "No IOAPIC for GSI 0x%x\n", gsi); > + return; > + } > > - /* Need to get gsi for dynamic entry */ > - if (entry->link.handle) { > - gsi > acpi_pci_link_get_irq(entry->link.handle, entry->link.index, > &edge_level, &active_high_low); > - if (!gsi) > - continue; > - } else { > - /* Hardwired GSI. Assume PCI standard settings */ > - gsi = entry->link.index; > - edge_level = 1; > - active_high_low = 1; > - } > - > - /* Don't set up the ACPI SCI because it's already set up */ > - if (acpi_fadt.sci_int = gsi) { > - /* we still need to set up the entry's irq */ > - acpi_gsi_to_irq(gsi, &entry->irq); > - continue; > - } > - > - ioapic = mp_find_ioapic(gsi); > - if (ioapic < 0) > - continue; > - ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; > - > - /* > - * Avoid pin reprogramming. PRTs typically include > entries > - * with redundant pin->gsi mappings (but unique PCI > devices); > - * we only only program the IOAPIC on the first. > - */ > - bit = ioapic_pin % 32; > - idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); > - if (idx > 3) { > - printk(KERN_ERR "Invalid reference to IOAPIC pin " > - "%d-%d\n", > mp_ioapic_routing[ioapic].apic_id, > - ioapic_pin); > - continue; > - } > - if ((1<<bit) & > mp_ioapic_routing[ioapic].pin_programmed[idx]) { > - Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", > - mp_ioapic_routing[ioapic].apic_id, > ioapic_pin); > - acpi_gsi_to_irq(gsi, &entry->irq); > - continue; > - } > - > - mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); > - if (!io_apic_set_pci_routing(ioapic, ioapic_pin, > gsi, edge_level, active_high_low)) { > - acpi_gsi_to_irq(gsi, &entry->irq); > - } > - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", > - entry->id.segment, entry->id.bus, > - entry->id.device, ('A' + entry->pin), > - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, > - entry->irq); > + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; > + > + /* > + * Avoid pin reprogramming. PRTs typically include entries > + * with redundant pin->gsi mappings (but unique PCI devices); > + * we only program the IOAPIC on the first. > + */ > + bit = ioapic_pin % 32; > + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); > + if (idx > 3) { > + printk(KERN_ERR "Invalid reference to IOAPIC pin " > + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, > + ioapic_pin); > + return; > + } > + if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { > + Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", > + mp_ioapic_routing[ioapic].apic_id, ioapic_pin); > + return; > } > - > - print_IO_APIC(); > > - return; > -} > + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); > > -#endif /*CONFIG_ACPI_PCI*/ > + io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, > + edge_level = ACPI_EDGE_SENSITIVE ? 0 : 1, > + active_high_low = ACPI_ACTIVE_HIGH ? 0 : 1); > +} > > #endif /*CONFIG_X86_IO_APIC*/ > - > #endif /*CONFIG_ACPI_BOOT*/ > === drivers/acpi/pci_irq.c 1.27 vs edited ==> --- 1.27/drivers/acpi/pci_irq.c Sat Apr 24 00:17:22 2004 > +++ edited/drivers/acpi/pci_irq.c Mon May 17 10:39:38 2004 > @@ -35,12 +35,6 @@ > #include <linux/pm.h> > #include <linux/pci.h> > #include <linux/acpi.h> > -#ifdef CONFIG_X86_IO_APIC > -#include <asm/mpspec.h> > -#endif > -#ifdef CONFIG_IOSAPIC > -# include <asm/iosapic.h> > -#endif > #include <acpi/acpi_bus.h> > #include <acpi/acpi_drivers.h> > > @@ -50,10 +44,6 @@ > > struct acpi_prt_list acpi_prt; > > -#ifdef CONFIG_X86 > -extern void eisa_set_level_irq(unsigned int irq); > -#endif > - > > /* > -------------------------------------------------------------------------- > PCI IRQ Routing Table (PRT) Support > @@ -237,12 +227,18 @@ > PCI Interrupt Routing Support > > ------------------------------------------------------------------ > -------- */ > > -int > -acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin) > +static int > +acpi_pci_irq_lookup ( > + struct pci_bus *bus, > + int device, > + int pin, > + int *edge_level, > + int *active_high_low) > { > struct acpi_prt_entry *entry = NULL; > int segment = pci_domain_nr(bus); > int bus_nr = bus->number; > + int irq; > > ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); > > @@ -255,28 +251,30 @@ > ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); > return_VALUE(0); > } > - > - if (!entry->irq && entry->link.handle) { > - entry->irq > acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL); > - if (!entry->irq) { > + > + if (entry->link.handle) { > + irq = acpi_pci_link_get_irq(entry->link.handle, > entry->link.index, edge_level, active_high_low); > + if (!irq) { > ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid > IRQ link routing entry\n")); > return_VALUE(0); > } > - } > - else if (!entry->irq) { > - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static > routing entry (IRQ 0)\n")); > - return_VALUE(0); > + } else { > + irq = entry->link.index; > + *edge_level = ACPI_LEVEL_SENSITIVE; > + *active_high_low = ACPI_ACTIVE_LOW; > } > > - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq)); > + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); > > - return_VALUE(entry->irq); > + return_VALUE(irq); > } > > static int > acpi_pci_irq_derive ( > struct pci_dev *dev, > - int pin) > + int pin, > + int *edge_level, > + int *active_high_low) > { > struct pci_dev *bridge = dev; > int irq = 0; > @@ -308,8 +306,8 @@ > pin = bridge_pin; > } > > - irq = acpi_pci_irq_lookup(bridge->bus, > - PCI_SLOT(bridge->devfn), pin); > + irq = acpi_pci_irq_lookup(bridge->bus, > PCI_SLOT(bridge->devfn), > + pin, edge_level, active_high_low); > } > > if (!irq) { > @@ -330,6 +328,8 @@ > { > int irq = 0; > u8 pin = 0; > + int edge_level = ACPI_LEVEL_SENSITIVE; > + int active_high_low = ACPI_ACTIVE_LOW; > > ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); > > @@ -352,21 +352,22 @@ > * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT > * values override any BIOS-assigned IRQs set during boot. > */ > - irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin); > + irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), > pin, &edge_level, &active_high_low); > > /* > * If no PRT entry was found, we'll try to derive an IRQ from the > * device's parent bridge. > */ > if (!irq) > - irq = acpi_pci_irq_derive(dev, pin); > + irq = acpi_pci_irq_derive(dev, pin, &edge_level, > &active_high_low); > > /* > * No IRQ known to the ACPI subsystem - maybe the BIOS / > * driver reported one, then use it. Exit in any case. > */ > if (!irq) { > - printk(KERN_WARNING PREFIX "No IRQ known for > interrupt pin %c of device %s", ('A' + pin), pci_name(dev)); > + printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI", > + pci_name(dev), ('A' + pin)); > /* Interrupt Line values above 0xF are forbidden */ > if (dev->irq && (dev->irq <= 0xF)) { > printk(" - using IRQ %d\n", dev->irq); > @@ -378,62 +379,14 @@ > } > } > > - dev->irq = irq; > + dev->irq = acpi_register_gsi(irq, edge_level, active_high_low); > > - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", > pci_name(dev), dev->irq)); > - > - /* > - * Make sure all (legacy) PCI IRQs are set as level-triggered. > - */ > -#ifdef CONFIG_X86 > - { > - static u16 irq_mask; > - if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { > - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting > IRQ %d as level-triggered\n", dev->irq)); > - irq_mask |= (1 << dev->irq); > - eisa_set_level_irq(dev->irq); > - } > - } > -#endif > -#ifdef CONFIG_IOSAPIC > - if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC) > - iosapic_enable_intr(dev->irq); > -#endif > + printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI 0x%x " > + "(%s, %s) -> IRQ %d\n", > + pci_name(dev), 'A' + pin, irq, > + (edge_level = ACPI_LEVEL_SENSITIVE) ? "level" : "edge", > + (active_high_low = ACPI_ACTIVE_LOW) ? "low" : "high", > + dev->irq); > > return_VALUE(dev->irq); > -} > - > - > -int __init > -acpi_pci_irq_init (void) > -{ > - struct pci_dev *dev = NULL; > - > - ACPI_FUNCTION_TRACE("acpi_pci_irq_init"); > - > - if (!acpi_prt.count) { > - printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ " > - "routing entries\n"); > - return_VALUE(-ENODEV); > - } > - > - /* Make sure all link devices have a valid IRQ. */ > - if (acpi_pci_link_check()) { > - return_VALUE(-ENODEV); > - } > - > -#ifdef CONFIG_X86_IO_APIC > - /* Program IOAPICs using data from PRT entries. */ > - if (acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC) > - mp_parse_prt(); > -#endif > -#ifdef CONFIG_IOSAPIC > - if (acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC) > - iosapic_parse_prt(); > -#endif > - > - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) > - acpi_pci_irq_enable(dev); > - > - return_VALUE(0); > } > === drivers/acpi/pci_link.c 1.28 vs edited ==> --- 1.28/drivers/acpi/pci_link.c Mon May 10 14:42:35 2004 > +++ edited/drivers/acpi/pci_link.c Mon May 17 10:39:39 2004 > @@ -487,13 +487,13 @@ > }; > > int > -acpi_pci_link_check (void) > +acpi_irq_penalty_init(void) > { > struct list_head *node = NULL; > struct acpi_pci_link *link = NULL; > int i = 0; > > - ACPI_FUNCTION_TRACE("acpi_pci_link_check"); > + ACPI_FUNCTION_TRACE("acpi_irq_penalty_init"); > > /* > * Update penalties to facilitate IRQ balancing. > === drivers/serial/8250_acpi.c 1.8 vs edited ==> --- 1.8/drivers/serial/8250_acpi.c Mon Mar 15 15:53:32 2004 > +++ edited/drivers/serial/8250_acpi.c Mon May 17 10:39:39 2004 > @@ -58,28 +58,18 @@ > static acpi_status acpi_serial_ext_irq(struct serial_struct *req, > struct acpi_resource_ext_irq > *ext_irq) > { > - if (ext_irq->number_of_interrupts > 0) { > -#ifdef CONFIG_IA64 > - req->irq = acpi_register_irq(ext_irq->interrupts[0], > - ext_irq->active_high_low, ext_irq->edge_level); > -#else > - req->irq = ext_irq->interrupts[0]; > -#endif > - } > + if (ext_irq->number_of_interrupts > 0) > + req->irq = acpi_register_gsi(ext_irq->interrupts[0], > + ext_irq->edge_level, ext_irq->active_high_low); > return AE_OK; > } > > static acpi_status acpi_serial_irq(struct serial_struct *req, > struct acpi_resource_irq *irq) > { > - if (irq->number_of_interrupts > 0) { > -#ifdef CONFIG_IA64 > - req->irq = acpi_register_irq(irq->interrupts[0], > - irq->active_high_low, irq->edge_level); > -#else > - req->irq = irq->interrupts[0]; > -#endif > - } > + if (irq->number_of_interrupts > 0) > + req->irq = acpi_register_gsi(irq->interrupts[0], > + irq->edge_level, irq->active_high_low); > return AE_OK; > } > > === drivers/serial/8250_hcdp.c 1.6 vs edited ==> --- 1.6/drivers/serial/8250_hcdp.c Tue May 4 10:54:32 2004 > +++ edited/drivers/serial/8250_hcdp.c Mon May 17 10:39:39 2004 > @@ -183,16 +183,12 @@ > } > > if (HCDP_IRQ_SUPPORTED(hcdp_dev)) { > -#ifdef CONFIG_IA64 > if (HCDP_PCI_UART(hcdp_dev)) > - port.irq = acpi_register_irq(gsi, > - ACPI_ACTIVE_LOW, > ACPI_LEVEL_SENSITIVE); > + port.irq = acpi_register_gsi(gsi, > + ACPI_LEVEL_SENSITIVE, > ACPI_ACTIVE_LOW); > else > - port.irq = acpi_register_irq(gsi, > - ACPI_ACTIVE_HIGH, > ACPI_EDGE_SENSITIVE); > -#else > - port.irq = gsi; > -#endif > + port.irq = acpi_register_gsi(gsi, > + ACPI_EDGE_SENSITIVE, > ACPI_ACTIVE_HIGH); > port.flags |= UPF_AUTO_IRQ; > > if (HCDP_PCI_UART(hcdp_dev)) > === include/acpi/acpi_drivers.h 1.17 vs edited ==> --- 1.17/include/acpi/acpi_drivers.h Mon Dec 15 17:46:29 2003 > +++ edited/include/acpi/acpi_drivers.h Mon May 17 10:39:40 2004 > @@ -55,7 +55,7 @@ > > /* ACPI PCI Interrupt Link (pci_link.c) */ > > -int acpi_pci_link_check (void); > +int acpi_irq_penalty_init (void); > int acpi_pci_link_get_irq (acpi_handle handle, int index, int* > edge_level, int* active_high_low); > > /* ACPI PCI Interrupt Routing (pci_irq.c) */ > === include/asm-i386/mpspec.h 1.20 vs edited ==> --- 1.20/include/asm-i386/mpspec.h Mon Apr 12 11:55:30 2004 > +++ edited/include/asm-i386/mpspec.h Mon May 17 10:39:40 2004 > @@ -33,7 +33,7 @@ > extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); > extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 > trigger, u32 gsi); > extern void mp_config_acpi_legacy_irqs (void); > -extern void mp_parse_prt (void); > +extern void mp_register_gsi (u32 gsi, int edge_level, int > active_high_low); > #endif /*CONFIG_ACPI_BOOT*/ > > #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) > === include/asm-ia64/iosapic.h 1.13 vs edited ==> --- 1.13/include/asm-ia64/iosapic.h Fri Feb 27 04:39:17 2004 > +++ edited/include/asm-ia64/iosapic.h Mon May 17 10:39:40 2004 > @@ -60,7 +60,6 @@ > unsigned int gsi_base); > extern int gsi_to_vector (unsigned int gsi); > extern int gsi_to_irq (unsigned int gsi); > -extern void __init iosapic_parse_prt (void); > extern void iosapic_enable_intr (unsigned int vector); > extern int iosapic_register_intr (unsigned int gsi, unsigned > long polarity, > unsigned long trigger); > === include/asm-x86_64/mpspec.h 1.11 vs edited ==> --- 1.11/include/asm-x86_64/mpspec.h Mon Apr 12 11:55:30 2004 > +++ edited/include/asm-x86_64/mpspec.h Mon May 17 10:39:40 2004 > @@ -189,7 +189,7 @@ > extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); > extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 > trigger, u32 gsi); > extern void mp_config_acpi_legacy_irqs (void); > -extern void mp_parse_prt (void); > +extern void mp_register_gsi (u32 gsi, int edge_level, int > active_high_low); > #endif /*CONFIG_X86_IO_APIC*/ > #endif > > === include/linux/acpi.h 1.33 vs edited ==> --- 1.33/include/linux/acpi.h Fri Apr 2 06:48:53 2004 > +++ edited/include/linux/acpi.h Mon May 17 10:39:41 2004 > @@ -437,7 +437,7 @@ > struct pci_dev; > > int acpi_pci_irq_enable (struct pci_dev *dev); > -int acpi_pci_irq_init (void); > +unsigned int acpi_register_gsi (u32 gsi, int edge_level, int > active_high_low); > int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); > > struct acpi_pci_driver { > - > To unsubscribe from this list: send the line "unsubscribe linux-ia64" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-05-18 9:30 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-05-17 9:58 [ACPI] Re: [PATCH] ACPI PCI IRQ routing rework Li, Shaohua 2004-05-17 15:41 ` Bjorn Helgaas 2004-05-17 16:16 ` Kenji Kaneshige 2004-05-17 18:41 ` Bjorn Helgaas 2004-05-18 9:30 ` Kenji Kaneshige
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox