From 2dfbba90d4a0774f9dc40b2648dd6d4f3978a447 Mon Sep 17 00:00:00 2001
From: Andy Grover <agrover@groveronline.com>
Date: Wed, 18 Sep 2002 04:45:30 -0700
Subject: [PATCH] ACPI: Ensure that the SCI has the proper polarity and
 trigger, even on systems that do not have an interrupt override entry in the
 MADT.

---
 arch/i386/kernel/io_apic.c |  2 +-
 arch/i386/kernel/mpparse.c | 26 ++++++++++++++++++--------
 drivers/acpi/bus.c         |  2 +-
 include/asm-i386/mpspec.h  |  1 +
 4 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 1e4ef81d5e8e..25c6ad13b85b 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1885,7 +1885,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq)
 	io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
-	return entry.vector;
+	return 0;
 }
 
 #endif /*CONFIG_ACPI_BOOT*/
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index ba96793892ce..fb2a52ad37fe 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -976,7 +976,7 @@ void __init mp_override_legacy_irq (
 	intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;	   /* APIC ID */
 	intsrc.mpc_dstirq = pin;				    /* INTIN# */
 
-	Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", 
+	Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n",
 		intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
 		(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
 		intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
@@ -1049,8 +1049,20 @@ void __init mp_config_acpi_legacy_irqs (void)
 		if (++mp_irq_entries == MAX_IRQ_SOURCES)
 			panic("Max # of irq sources exceeded!\n");
 	}
+}
 
-	return;
+/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
+
+void __init mp_config_ioapic_for_sci(int irq)
+{
+	int ioapic;
+	int ioapic_pin;
+
+	ioapic = mp_find_ioapic(irq);
+
+	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+
+	io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
 }
 
 #ifdef CONFIG_ACPI_PCI
@@ -1059,7 +1071,6 @@ void __init mp_parse_prt (void)
 {
 	struct list_head	*node = NULL;
 	struct acpi_prt_entry	*entry = NULL;
-	int			vector = 0;
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
 	int			irq = 0;
@@ -1104,14 +1115,13 @@ void __init mp_parse_prt (void)
 
 		mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-		vector = io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
-		if (vector)
+		if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq))
 			entry->irq = irq;
 
-		printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> vector 0x%02x"
-			" -> IRQ %d\n", entry->id.segment, entry->id.bus, 
+		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, vector, 
+			mp_ioapic_routing[ioapic].apic_id, ioapic_pin, 
 			entry->irq);
 	}
 	
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 000684a1348b..3c89b289651c 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -612,7 +612,7 @@ acpi_bus_init (void)
 #ifdef CONFIG_X86
 	/* Ensure the SCI is set to level-triggered, active-low */
 	if (acpi_ioapic)
-		mp_override_legacy_irq(acpi_fadt.sci_int, 3, 3, acpi_fadt.sci_int);
+		mp_config_ioapic_for_sci(acpi_fadt.sci_int);
 	else
 		eisa_set_level_irq(acpi_fadt.sci_int);
 #endif
diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h
index 91ac8d8a5ad0..d658d4086846 100644
--- a/include/asm-i386/mpspec.h
+++ b/include/asm-i386/mpspec.h
@@ -226,6 +226,7 @@ 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_config_acpi_legacy_irqs (void);
+extern void mp_config_ioapic_for_sci(int irq);
 extern void mp_parse_prt (void);
 #endif /*CONFIG_ACPI_BOOT*/
 
-- 
2.30.9