Commit 357dd96a authored by Natalie Protasevich's avatar Natalie Protasevich Committed by Linus Torvalds

[PATCH] Incorrect PCI interrupt assignment on ES7000 for platform GSI

In arch/i386/kernel/acpi/boot.c, platform GSI does not propagate back from
mp_register_gsi() to a calling routine which results in IRQ to be set for
wrong GSI.  This causes most of the PCI slots on the first PCI module to
fail.  This patch fixes the problem by returning new GSI back to
acpi_register_gsi().
Signed-off-by: default avatarNatalie Protasevich <Natalie.Protasevich@unisys.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f5b3f8e9
...@@ -450,6 +450,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) ...@@ -450,6 +450,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
{ {
unsigned int irq; unsigned int irq;
unsigned int plat_gsi = gsi;
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/* /*
...@@ -471,10 +472,10 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) ...@@ -471,10 +472,10 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
mp_register_gsi(gsi, edge_level, active_high_low); plat_gsi = mp_register_gsi(gsi, edge_level, active_high_low);
} }
#endif #endif
acpi_gsi_to_irq(gsi, &irq); acpi_gsi_to_irq(plat_gsi, &irq);
return irq; return irq;
} }
EXPORT_SYMBOL(acpi_register_gsi); EXPORT_SYMBOL(acpi_register_gsi);
......
...@@ -1051,7 +1051,7 @@ void __init mp_config_acpi_legacy_irqs (void) ...@@ -1051,7 +1051,7 @@ void __init mp_config_acpi_legacy_irqs (void)
int (*platform_rename_gsi)(int ioapic, int gsi); int (*platform_rename_gsi)(int ioapic, int gsi);
void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
{ {
int ioapic = -1; int ioapic = -1;
int ioapic_pin = 0; int ioapic_pin = 0;
...@@ -1060,13 +1060,13 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) ...@@ -1060,13 +1060,13 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
#ifdef CONFIG_ACPI_BUS #ifdef CONFIG_ACPI_BUS
/* 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 == gsi) if (acpi_fadt.sci_int == gsi)
return; return gsi;
#endif #endif
ioapic = mp_find_ioapic(gsi); ioapic = mp_find_ioapic(gsi);
if (ioapic < 0) { if (ioapic < 0) {
printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
return; return gsi;
} }
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
...@@ -1085,12 +1085,12 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) ...@@ -1085,12 +1085,12 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
printk(KERN_ERR "Invalid reference to IOAPIC pin " printk(KERN_ERR "Invalid reference to IOAPIC pin "
"%d-%d\n", mp_ioapic_routing[ioapic].apic_id, "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
ioapic_pin); ioapic_pin);
return; return gsi;
} }
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin); mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
return; return gsi;
} }
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
...@@ -1098,6 +1098,7 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) ...@@ -1098,6 +1098,7 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
return gsi;
} }
#endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/ #endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/
......
...@@ -895,25 +895,25 @@ void __init mp_config_acpi_legacy_irqs (void) ...@@ -895,25 +895,25 @@ void __init mp_config_acpi_legacy_irqs (void)
return; return;
} }
void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
{ {
int ioapic = -1; int ioapic = -1;
int ioapic_pin = 0; int ioapic_pin = 0;
int idx, bit = 0; int idx, bit = 0;
if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
return; return gsi;
#ifdef CONFIG_ACPI_BUS #ifdef CONFIG_ACPI_BUS
/* 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 == gsi) if (acpi_fadt.sci_int == gsi)
return; return gsi;
#endif #endif
ioapic = mp_find_ioapic(gsi); ioapic = mp_find_ioapic(gsi);
if (ioapic < 0) { if (ioapic < 0) {
printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
return; return gsi;
} }
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start; ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
...@@ -929,12 +929,12 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) ...@@ -929,12 +929,12 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
printk(KERN_ERR "Invalid reference to IOAPIC pin " printk(KERN_ERR "Invalid reference to IOAPIC pin "
"%d-%d\n", mp_ioapic_routing[ioapic].apic_id, "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
ioapic_pin); ioapic_pin);
return; return gsi;
} }
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin); mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
return; return gsi;
} }
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
...@@ -942,6 +942,7 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low) ...@@ -942,6 +942,7 @@ void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
return gsi;
} }
#endif /*CONFIG_X86_IO_APIC*/ #endif /*CONFIG_X86_IO_APIC*/
......
...@@ -33,7 +33,7 @@ extern void mp_register_lapic_address (u64 address); ...@@ -33,7 +33,7 @@ extern void mp_register_lapic_address (u64 address);
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); 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_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void); extern void mp_config_acpi_legacy_irqs (void);
extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low); extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
#endif /*CONFIG_ACPI_BOOT*/ #endif /*CONFIG_ACPI_BOOT*/
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
......
...@@ -188,7 +188,7 @@ extern void mp_register_lapic_address (u64 address); ...@@ -188,7 +188,7 @@ extern void mp_register_lapic_address (u64 address);
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); 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_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void); extern void mp_config_acpi_legacy_irqs (void);
extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low); extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
#endif /*CONFIG_X86_IO_APIC*/ #endif /*CONFIG_X86_IO_APIC*/
#endif #endif
......
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