From: Bjorn Helgaas Add "acpi_gsi_to_irq()" as a generic replacement for "acpi_irq_to_vector()". This converts from an ACPI global system interrupt number to a Linux IRQ. Also, convert i386-specific terminology to use GSI when appropriate. --- 25-akpm/arch/i386/kernel/acpi/boot.c | 12 ++++ 25-akpm/arch/i386/kernel/mpparse.c | 94 +++++++++++++++++------------------ 25-akpm/include/asm-i386/acpi.h | 3 - 25-akpm/include/asm-i386/mpspec.h | 8 +- 4 files changed, 65 insertions(+), 52 deletions(-) diff -puN arch/i386/kernel/acpi/boot.c~acpi-gsi-irq-conversions-fix arch/i386/kernel/acpi/boot.c --- 25/arch/i386/kernel/acpi/boot.c~acpi-gsi-irq-conversions-fix 2004-03-21 00:05:11.202350104 -0800 +++ 25-akpm/arch/i386/kernel/acpi/boot.c 2004-03-21 00:05:11.208349192 -0800 @@ -351,6 +351,7 @@ __setup("acpi_pic_sci=", acpi_pic_sci_se #endif /* CONFIG_ACPI_BUS */ #ifdef CONFIG_X86_IO_APIC +/* deprecated in favor of acpi_gsi_to_irq */ int acpi_irq_to_vector(u32 irq) { if (use_pci_vector() && !platform_legacy_irq(irq)) @@ -359,6 +360,17 @@ int acpi_irq_to_vector(u32 irq) } #endif +int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) +{ +#ifdef CONFIG_X86_IO_APIC + if (use_pci_vector() && !platform_legacy_irq(gsi)) + *irq = IO_APIC_VECTOR(gsi); + else +#endif + *irq = gsi; + return 0; +} + static unsigned long __init acpi_scan_rsdp ( unsigned long start, diff -puN arch/i386/kernel/mpparse.c~acpi-gsi-irq-conversions-fix arch/i386/kernel/mpparse.c --- 25/arch/i386/kernel/mpparse.c~acpi-gsi-irq-conversions-fix 2004-03-21 00:05:11.204349800 -0800 +++ 25-akpm/arch/i386/kernel/mpparse.c 2004-03-21 00:05:11.210348888 -0800 @@ -1,5 +1,5 @@ /* - * Intel Multiprocessor Specificiation 1.1 and 1.4 + * Intel Multiprocessor Specification 1.1 and 1.4 * compliant MP-table parsing routines. * * (c) 1995 Alan Cox, Building #3 @@ -851,25 +851,25 @@ void __init mp_register_lapic ( struct mp_ioapic_routing { int apic_id; - int irq_start; - int irq_end; + int gsi_base; + int gsi_end; u32 pin_programmed[4]; } mp_ioapic_routing[MAX_IO_APICS]; static int __init mp_find_ioapic ( - int irq) + int gsi) { int i = 0; - /* Find the IOAPIC that manages this IRQ. */ + /* Find the IOAPIC that manages this GSI. */ for (i = 0; i < nr_ioapics; i++) { - if ((irq >= mp_ioapic_routing[i].irq_start) - && (irq <= mp_ioapic_routing[i].irq_end)) + if ((gsi >= mp_ioapic_routing[i].gsi_base) + && (gsi <= mp_ioapic_routing[i].gsi_end)) return i; } - printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d\n", irq); + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); return -1; } @@ -878,7 +878,7 @@ static int __init mp_find_ioapic ( void __init mp_register_ioapic ( u8 id, u32 address, - u32 irq_base) + u32 gsi_base) { int idx = 0; @@ -904,19 +904,19 @@ void __init mp_register_ioapic ( mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); /* - * Build basic IRQ lookup table to facilitate irq->io_apic lookups - * and to prevent reprogramming of IOAPIC pins (PCI IRQs). + * Build basic GSI lookup table to facilitate gsi->io_apic lookups + * and to prevent reprogramming of IOAPIC pins (PCI GSIs). */ mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; - mp_ioapic_routing[idx].irq_start = irq_base; - mp_ioapic_routing[idx].irq_end = irq_base + + mp_ioapic_routing[idx].gsi_base = gsi_base; + mp_ioapic_routing[idx].gsi_end = gsi_base + io_apic_get_redir_entries(idx); printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " - "IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, + "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, - mp_ioapic_routing[idx].irq_start, - mp_ioapic_routing[idx].irq_end); + mp_ioapic_routing[idx].gsi_base, + mp_ioapic_routing[idx].gsi_end); return; } @@ -926,7 +926,7 @@ void __init mp_override_legacy_irq ( u8 bus_irq, u8 polarity, u8 trigger, - u32 global_irq) + u32 gsi) { struct mpc_config_intsrc intsrc; int i = 0; @@ -935,12 +935,12 @@ void __init mp_override_legacy_irq ( int pin = -1; /* - * Convert 'global_irq' to 'ioapic.pin'. + * Convert 'gsi' to 'ioapic.pin'. */ - ioapic = mp_find_ioapic(global_irq); + ioapic = mp_find_ioapic(gsi); if (ioapic < 0) return; - pin = global_irq - mp_ioapic_routing[ioapic].irq_start; + pin = gsi - mp_ioapic_routing[ioapic].gsi_base; /* * TBD: This check is for faulty timer entries, where the override @@ -965,7 +965,7 @@ void __init mp_override_legacy_irq ( /* * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it. - * Otherwise create a new entry (e.g. global_irq == 2). + * Otherwise create a new entry (e.g. gsi == 2). */ for (i = 0; i < mp_irq_entries; i++) { if ((mp_irqs[i].mpc_srcbus == intsrc.mpc_srcbus) @@ -1036,7 +1036,7 @@ void __init mp_config_acpi_legacy_irqs ( extern FADT_DESCRIPTOR acpi_fadt; -void __init mp_config_ioapic_for_sci(int irq) +void __init mp_config_ioapic_for_sci(u32 gsi) { int ioapic; int ioapic_pin; @@ -1083,11 +1083,11 @@ found: */ flags = entry->flags; acpi_fadt.sci_int = entry->global_irq; - irq = entry->global_irq; + gsi = entry->global_irq; - ioapic = mp_find_ioapic(irq); + ioapic = mp_find_ioapic(gsi); - ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; /* * MPS INTI flags: @@ -1095,7 +1095,7 @@ found: * polarity: 0=default, 1=high, 3=low * Per ACPI spec, default for SCI means level/low. */ - io_apic_set_pci_routing(ioapic, ioapic_pin, irq, + io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, (flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1)); } @@ -1107,7 +1107,7 @@ void __init mp_parse_prt (void) struct acpi_prt_entry *entry = NULL; int ioapic = -1; int ioapic_pin = 0; - int irq = 0; + int gsi = 0; int idx, bit = 0; int edge_level = 0; int active_high_low = 0; @@ -1119,39 +1119,39 @@ void __init mp_parse_prt (void) list_for_each(node, &acpi_prt.entries) { entry = list_entry(node, struct acpi_prt_entry, node); - /* Need to get irq for dynamic entry */ + /* Need to get gsi for dynamic entry */ if (entry->link.handle) { - irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); - if (!irq) + gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); + if (!gsi) continue; } else { - /* Hardwired IRQ. Assume PCI standard settings */ - irq = entry->link.index; + /* 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 == irq) { - irq = acpi_irq_to_vector(irq); - entry->irq = irq; /* we still need to set entry's irq */ + 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(irq); + ioapic = mp_find_ioapic(gsi); if (ioapic < 0) continue; - ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; if (es7000_plat) { - if (!ioapic && (irq < 16)) - irq += 16; + if (!ioapic && (gsi < 16)) + gsi += 16; } /* * Avoid pin reprogramming. PRTs typically include entries - * with redundant pin->irq mappings (but unique PCI devices); + * with redundant pin->gsi mappings (but unique PCI devices); * we only only program the IOAPIC on the first. */ bit = ioapic_pin % 32; @@ -1165,19 +1165,19 @@ void __init mp_parse_prt (void) if ((1<irq = acpi_irq_to_vector(irq); + acpi_gsi_to_irq(gsi, &entry->irq); continue; } mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = acpi_irq_to_vector(irq); - } + 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->id.segment, entry->id.bus, + entry->id.device, ('A' + entry->pin), + mp_ioapic_routing[ioapic].apic_id, ioapic_pin, entry->irq); } diff -puN include/asm-i386/acpi.h~acpi-gsi-irq-conversions-fix include/asm-i386/acpi.h --- 25/include/asm-i386/acpi.h~acpi-gsi-irq-conversions-fix 2004-03-21 00:05:11.205349648 -0800 +++ 25-akpm/include/asm-i386/acpi.h 2004-03-21 00:05:11.211348736 -0800 @@ -123,9 +123,10 @@ static inline void disable_acpi(void) { /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ #define FIX_ACPI_PAGES 4 +extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); #ifdef CONFIG_X86_IO_APIC extern int skip_ioapic_setup; -extern int acpi_irq_to_vector(u32 irq); +extern int acpi_irq_to_vector(u32 irq); /* deprecated in favor of acpi_gsi_to_irq */ static inline void disable_ioapic_setup(void) { diff -puN include/asm-i386/mpspec.h~acpi-gsi-irq-conversions-fix include/asm-i386/mpspec.h --- 25/include/asm-i386/mpspec.h~acpi-gsi-irq-conversions-fix 2004-03-21 00:05:11.206349496 -0800 +++ 25-akpm/include/asm-i386/mpspec.h 2004-03-21 00:05:11.211348736 -0800 @@ -30,15 +30,15 @@ extern int using_apic_timer; #ifdef CONFIG_ACPI_BOOT extern void mp_register_lapic (u8 id, u8 enabled); extern void mp_register_lapic_address (u64 address); -extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base); -extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq); +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); #ifdef CONFIG_X86_IO_APIC -extern void mp_config_ioapic_for_sci(int irq); +extern void mp_config_ioapic_for_sci(u32 gsi); #else -static inline void mp_config_ioapic_for_sci(int irq) +static inline void mp_config_ioapic_for_sci(u32 gsi) { } #endif #endif /*CONFIG_ACPI_BOOT*/ _