Commit 49596747 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ia32 MSI vector handling fix

From: "Nakajima, Jun" <jun.nakajima@intel.com>

To get the vector-based interrupt handling work, we need to give the vector
number to device drivers instead of the IRQ if IRQ < 16.  It was not
happening for SCI, and the patch fixes it.  In many cases, the IRQ for SCI is
9, and the problem was not detected, but one particular machine exposed the
bug.
parent 5d790751
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/irq.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include <asm/apic.h> #include <asm/apic.h>
...@@ -311,7 +312,14 @@ __setup("acpi_pic_sci=", acpi_pic_sci_setup); ...@@ -311,7 +312,14 @@ __setup("acpi_pic_sci=", acpi_pic_sci_setup);
#endif /* CONFIG_ACPI_BUS */ #endif /* CONFIG_ACPI_BUS */
#ifdef CONFIG_X86_IO_APIC
int acpi_irq_to_vector(u32 irq)
{
if (use_pci_vector() && !platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
return irq;
}
#endif
static unsigned long __init static unsigned long __init
acpi_scan_rsdp ( acpi_scan_rsdp (
......
...@@ -1126,7 +1126,8 @@ void __init mp_parse_prt (void) ...@@ -1126,7 +1126,8 @@ void __init mp_parse_prt (void)
/* Don't set up the ACPI SCI because it's already set up */ /* Don't set up the ACPI SCI because it's already set up */
if (acpi_fadt.sci_int == irq) { if (acpi_fadt.sci_int == irq) {
entry->irq = irq; /*we still need to set entry's irq*/ irq = acpi_irq_to_vector(irq);
entry->irq = irq; /* we still need to set entry's irq */
continue; continue;
} }
...@@ -1156,18 +1157,14 @@ void __init mp_parse_prt (void) ...@@ -1156,18 +1157,14 @@ void __init mp_parse_prt (void)
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
printk(KERN_DEBUG "Pin %d-%d already programmed\n", printk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin); mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
if (use_pci_vector() && !platform_legacy_irq(irq)) entry->irq = acpi_irq_to_vector(irq);
irq = IO_APIC_VECTOR(irq);
entry->irq = irq;
continue; continue;
} }
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) { if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) {
if (use_pci_vector() && !platform_legacy_irq(irq)) entry->irq = acpi_irq_to_vector(irq);
irq = IO_APIC_VECTOR(irq);
entry->irq = irq;
} }
printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
entry->id.segment, entry->id.bus, entry->id.segment, entry->id.bus,
......
...@@ -249,7 +249,7 @@ acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) ...@@ -249,7 +249,7 @@ acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
*/ */
irq = acpi_fadt.sci_int; irq = acpi_fadt.sci_int;
#ifdef CONFIG_IA64 #if defined(CONFIG_IA64) || defined(CONFIG_PCI_USE_VECTOR)
irq = acpi_irq_to_vector(irq); irq = acpi_irq_to_vector(irq);
if (irq < 0) { if (irq < 0) {
printk(KERN_ERR PREFIX "SCI (ACPI interrupt %d) not registered\n", printk(KERN_ERR PREFIX "SCI (ACPI interrupt %d) not registered\n",
...@@ -272,7 +272,7 @@ acpi_status ...@@ -272,7 +272,7 @@ acpi_status
acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
{ {
if (irq) { if (irq) {
#ifdef CONFIG_IA64 #if defined(CONFIG_IA64) || defined(CONFIG_PCI_USE_VECTOR)
irq = acpi_irq_to_vector(irq); irq = acpi_irq_to_vector(irq);
#endif #endif
free_irq(irq, acpi_irq); free_irq(irq, acpi_irq);
......
...@@ -116,6 +116,7 @@ extern int acpi_noirq; ...@@ -116,6 +116,7 @@ extern int acpi_noirq;
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
extern int skip_ioapic_setup; extern int skip_ioapic_setup;
extern int acpi_irq_to_vector(u32 irq);
static inline void disable_ioapic_setup(void) static inline void disable_ioapic_setup(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment