diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/arch/ia64/kernel/acpi.c 30_sci/arch/ia64/kernel/acpi.c --- 20_iosapic_gsi/arch/ia64/kernel/acpi.c Sun Jul 21 03:03:28 2002 +++ 30_sci/arch/ia64/kernel/acpi.c Mon Jul 22 04:56:58 2002 @@ -213,6 +213,7 @@ static int total_cpus __initdata; static int available_cpus __initdata; struct acpi_table_madt * acpi_madt __initdata; +u8 has_8259; static int __init @@ -335,9 +336,8 @@ if (iosapic_init) { #ifndef CONFIG_ITANIUM - /* PCAT_COMPAT flag indicates dual-8259 setup */ iosapic_init(iosapic->address, iosapic->global_irq_base, - acpi_madt->flags.pcat_compat); + has_8259); #else /* Firmware on old Itanium systems is broken */ iosapic_init(iosapic->address, iosapic->global_irq_base, 1); @@ -444,6 +444,8 @@ return -ENODEV; } + has_8259 = acpi_madt->flags.pcat_compat; + /* Initialize platform interrupt vector array */ for (i = 0; i < ACPI_MAX_PLATFORM_IRQS; i++) @@ -461,6 +463,39 @@ } +static int __init +acpi_parse_facp (unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_header *facp_header; + fadt_descriptor_rev2 *facp; + u32 irq, irq_base = 0; + char *iosapic_address = NULL; + + if (!phys_addr || !size) + return -EINVAL; + + if (!iosapic_register_irq) + return -ENODEV; + + facp_header = (struct acpi_table_header *) __va(phys_addr); + + /* Only deal with ACPI 2.0 FACP */ + if (facp_header->revision != 3) + return -ENODEV; + + facp = (fadt_descriptor_rev2 *)facp_header; + irq = facp->sci_int; + + if (has_8259 && irq < 16) + return 0; /* legacy, no setup required */ + + if (!acpi_find_iosapic(irq, &irq_base, &iosapic_address)) + iosapic_register_irq(irq, 0, 0, irq_base, iosapic_address); + + return 0; +} + + unsigned long __init acpi_find_rsdp (void) { @@ -611,6 +646,13 @@ return result; } + /* + * The FADT table contains an SCI_INT line, by which the system + * gets interrupts such as power and sleep buttons. If it's not + * on a Legacy interrupt, it needs to be setup. + */ + acpi_table_parse(ACPI_FACP, acpi_parse_facp); + #ifdef CONFIG_SERIAL_ACPI /* * TBD: Need phased approach to table parsing (only do those absolutely @@ -691,6 +733,15 @@ *type = ACPI_IRQ_MODEL_IOSAPIC; return 0; +} + +int +acpi_irq_to_vector(u32 irq) +{ + if (has_8259 && irq < 16) + return isa_irq_to_vector(irq); + + return iosapic_irq_to_vector(irq); } #endif /* CONFIG_ACPI_BOOT */ diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/arch/ia64/kernel/iosapic.c 30_sci/arch/ia64/kernel/iosapic.c --- 20_iosapic_gsi/arch/ia64/kernel/iosapic.c Sun Jul 21 03:03:33 2002 +++ 30_sci/arch/ia64/kernel/iosapic.c Sun Jul 21 03:03:38 2002 @@ -124,8 +124,8 @@ * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector. If no * entry exists, return -1. */ -static int -iosapic_irq_to_vector (int irq) +int +iosapic_irq_to_vector (unsigned int irq) { int vector; diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/drivers/acpi/osl.c 30_sci/drivers/acpi/osl.c --- 20_iosapic_gsi/drivers/acpi/osl.c Sun Jul 21 03:03:33 2002 +++ 30_sci/drivers/acpi/osl.c Mon Jul 22 04:22:26 2002 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "acpi.h" @@ -41,11 +42,6 @@ u64 efi_mem_attributes (u64 phys_addr); #endif -#ifdef CONFIG_IA64 -#include -#include -#endif - #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME ("osl") @@ -235,8 +231,15 @@ acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) { #ifdef CONFIG_IA64 - irq = isa_irq_to_vector(irq); -#endif /* CONFIG_IA64 */ + int vector; + + vector = acpi_irq_to_vector(irq); + if (vector < 0) { + printk(KERN_ERR PREFIX "SCI (IRQ%d) not registered\n", irq); + return AE_OK; + } + irq = vector; +#endif acpi_irq_irq = irq; acpi_irq_handler = handler; acpi_irq_context = context; @@ -253,8 +256,8 @@ { if (acpi_irq_handler) { #ifdef CONFIG_IA64 - irq = isa_irq_to_vector(irq); -#endif /* CONFIG_IA64 */ + irq = acpi_irq_to_vector(irq); +#endif free_irq(irq, acpi_irq); acpi_irq_handler = NULL; } diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/include/asm-ia64/iosapic.h 30_sci/include/asm-ia64/iosapic.h --- 20_iosapic_gsi/include/asm-ia64/iosapic.h Fri Nov 9 15:26:17 2001 +++ 30_sci/include/asm-ia64/iosapic.h Sun Jul 21 03:03:38 2002 @@ -53,6 +53,7 @@ extern void __init iosapic_init (unsigned long address, unsigned int base_irq, int pcat_compat); +extern int iosapic_irq_to_vector (unsigned int irq); extern int iosapic_register_irq (u32 global_vector, unsigned long polarity, unsigned long edge_triggered, u32 base_irq, char *iosapic_address); diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/include/linux/acpi.h 30_sci/include/linux/acpi.h --- 20_iosapic_gsi/include/linux/acpi.h Mon Jul 22 03:12:16 2002 +++ 30_sci/include/linux/acpi.h Sun Jul 21 03:40:16 2002 @@ -377,6 +377,7 @@ #ifdef CONFIG_ACPI int acpi_init(void); +int acpi_irq_to_vector(u32 irq); #endif /*CONFIG_ACPI*/