diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 21fc029..128ae25 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -344,7 +344,9 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) * stash over-ride to indicate we've been here * and for later update of acpi_gbl_FADT */ + printk(KERN_INFO "%s: %d -> %d (%d, %d)\n", __FUNCTION__, acpi_sci_override_gsi, gsi, trigger, polarity); acpi_sci_override_gsi = gsi; + return; } diff --git a/arch/x86/xen/pci.c b/arch/x86/xen/pci.c index f999ad8..4cee777 100644 --- a/arch/x86/xen/pci.c +++ b/arch/x86/xen/pci.c @@ -69,7 +69,41 @@ int xen_register_gsi(u32 gsi, int triggering, int polarity) } return irq; } +static int xen_sci_override = 0; +static int xen_sci_trigger = ACPI_ACTIVE_LOW; +static int xen_sci_polarity = ACPI_EDGE_SENSITIVE; +static int __init +xen_sci_override_func(char *str) +{ + int val; + + while (*str) { + if (!strncmp(str, "level", 5)) { + xen_sci_trigger = ACPI_LEVEL_SENSITIVE; + str+=5; + } + if (!strncmp(str, "edge", 4)) { + xen_sci_trigger = ACPI_EDGE_SENSITIVE; + str+=4; + } + if (!strncmp(str, "high", 4)) { + xen_sci_polarity = ACPI_ACTIVE_HIGH; + str+=4; + } + if (!strncmp(str, "low", 3)) { + xen_sci_polarity = ACPI_ACTIVE_LOW; + str+=3; + } + str = strpbrk(str, ","); + if (!str) + break; + str++; /* skip ',' */ + } + xen_sci_override = 1; + return 0; +} +__setup("xen_sci=", xen_sci_override_func); void __init xen_setup_pirqs(void) { int irq; @@ -84,13 +118,56 @@ void __init xen_setup_pirqs(void) for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { int trigger, polarity; - if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) { + printk(KERN_INFO "%s: skipping %d\n", __FUNCTION__, irq); continue; + } + xen_register_gsi(irq, + trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE, + polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH); + } + /* For SCI that is above NR_IRQS_LEGACY or xen_sci_override is turned on*/ + if ((acpi_gbl_FADT.sci_interrupt > NR_IRQS_LEGACY) || + (acpi_sci_override_gsi > NR_IRQS_LEGACY) || + (xen_sci_override)) { + + int trigger, polarity; + + irq = acpi_gbl_FADT.sci_interrupt; + + if ((acpi_sci_override_gsi > NR_IRQS_LEGACY) && + (acpi_gbl_FADT.sci_interrupt <= NR_IRQS_LEGACY)) + irq = acpi_sci_override_gsi; + + if ((acpi_sci_override_gsi <= NR_IRQS_LEGACY) && + (acpi_gbl_FADT.sci_interrupt > NR_IRQS_LEGACY)) + irq = acpi_gbl_FADT.sci_interrupt; + printk(KERN_INFO "%s: FADT.SCI: %d ACPI.SCI:%d. Using IRQ %d.\n", + __FUNCTION__, + acpi_gbl_FADT.sci_interrupt, acpi_sci_override_gsi, irq); + + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) { + printk(KERN_INFO "%s: acpi_get_override_irq fails for %d. \n", __FUNCTION__, irq); + } + if (xen_sci_override) { +#define trig2str(x) (x == ACPI_LEVEL_SENSITIVE) ? "level" : "edge" +#define pol2str(x) (x == ACPI_ACTIVE_LOW) ? "low" : "high" + printk(KERN_INFO "%s: SCI override: trigger: %s->%s, polarity: %s->%s\n", + __FUNCTION__, + trig2str(trigger), trig2str(xen_sci_trigger), + pol2str(polarity), pol2str(xen_sci_polarity)); +#undef trig2str +#undef pol2str + trigger = xen_sci_trigger; + polarity = xen_sci_polarity; + } xen_register_gsi(irq, trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE, polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH); + } + } #ifdef CONFIG_PCI_MSI diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 7411915..82d60a4 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -688,6 +688,7 @@ void __init acpi_early_init(void) * update it with result from INT_SRC_OVR parsing */ acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi; + printk(KERN_INFO "%s: FADT.SCI = %d\n", __FUNCTION__,acpi_sci_override_gsi); } #endif