public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
* [Linux-ia64] [BUG] Interrupt source override (Re: ACPI power button events)
@ 2002-01-16  3:02 KOCHI, Takayoshi
  2002-01-16 18:47 ` [Linux-ia64] [BUG] Interrupt source override (Re: ACPI power Sluder, Charles
  0 siblings, 1 reply; 2+ messages in thread
From: KOCHI, Takayoshi @ 2002-01-16  3:02 UTC (permalink / raw)
  To: linux-ia64

[-- Attachment #1: Type: text/plain, Size: 1059 bytes --]

On BigSur, there's an interrupt source override record for IRQ9 (SCI)
in ACPI table and the kernel should set it correct.
But the current code doesn't reprogram IO-SAPIC correctly and set
interrupt handler type, so the SCI interrupts were never delivered
to running CPUs.

This patch fixes this problem.  This is against 2.4.17 + 011226 ia64
patch (only affects arch/ia64/kernel/iosapic.c and acpi.c).

And with this patch, I can cat /proc/acpi/event and see
"button power 00000080 00000000" now!

On Mon, 14 Jan 2002 16:04:28 -0800
"KOCHI, Takayoshi" <t-kouchi@mvf.biglobe.ne.jp> wrote:

> Oh well, our BigSur says
> 
>  39:	0	0   IO-SAPIC-edge  acpi
> 
> But ACPI specification says the SCI (ACPI interrupt) should be
> active low, level and shareable.  I'll look into it...

The spec says active low, but the trigger mode is actually
platform-dependent.  BigSur and AzusA defines IRQ9 override
as active-high.
Anyway we should obey what the interrupt override record says...

Thanks,
-- 
KOCHI Takayoshi <t-kouchi@cq.jp.nec.com/t-kouchi@mvf.biglobe.ne.jp>

[-- Attachment #2: intoverride.diff --]
[-- Type: application/octet-stream, Size: 3227 bytes --]

Index: acpi.c
===================================================================
RCS file: /data/cvsroot/linux/arch/ia64/kernel/acpi.c,v
retrieving revision 1.1.1.9
diff -u -r1.1.1.9 acpi.c
--- acpi.c	8 Dec 2001 03:03:40 -0000	1.1.1.9
+++ acpi.c	16 Jan 2002 02:40:13 -0000
@@ -101,7 +101,7 @@
 acpi_legacy_irq (char *p)
 {
 	acpi_entry_int_override_t *legacy = (acpi_entry_int_override_t *) p;
-	unsigned long polarity = 0, edge_triggered = 0;
+	unsigned long polarity = 0, trigger = 0;
 
 	/*
 	 * If the platform we're running doesn't define
@@ -110,17 +110,10 @@
 	if (!iosapic_register_legacy_irq)
 		return;
 
-	switch (legacy->flags) {
-	      case 0x5:	polarity = 1; edge_triggered = 1; break;
-	      case 0x7: polarity = 0; edge_triggered = 1; break;
-	      case 0xd: polarity = 1; edge_triggered = 0; break;
-	      case 0xf: polarity = 0; edge_triggered = 0; break;
-	      default:
-		printk("    ACPI Legacy IRQ 0x%02x: Unknown flags 0x%x\n", legacy->isa_irq,
-		       legacy->flags);
-		break;
-	}
-	iosapic_register_legacy_irq(legacy->isa_irq, legacy->pin, polarity, edge_triggered);
+	polarity = legacy->flags & 0x03;
+	trigger = (legacy->flags >> 2) & 0x03;
+	
+	iosapic_register_legacy_irq(legacy->isa_irq, legacy->pin, polarity, trigger);
 }
 
 /*
Index: iosapic.c
===================================================================
RCS file: /data/cvsroot/linux/arch/ia64/kernel/iosapic.c,v
retrieving revision 1.1.1.10
diff -u -r1.1.1.10 iosapic.c
--- iosapic.c	8 Dec 2001 03:10:42 -0000	1.1.1.10
+++ iosapic.c	16 Jan 2002 02:40:13 -0000
@@ -453,24 +453,43 @@
  * ACPI calls this when it finds an entry for a legacy ISA interrupt.  Note that the
  * irq_base and IOSAPIC address must be set in iosapic_init().
  */
+
+#define POLARITY_ACTIVE_HIGH	(0x01)
+#define POLARITY_ACTIVE_LOW	(0x03)
+#define TRIGGER_EDGE		(0x01)
+#define TRIGGER_LEVEL		(0x03)
+
 void
 iosapic_register_legacy_irq (unsigned long irq,
 			     unsigned long pin, unsigned long polarity,
-			     unsigned long edge_triggered)
+			     unsigned long trigger)
 {
 	unsigned int vector = isa_irq_to_vector(irq);
+	irq_desc_t *idesc = irq_desc(vector);
+	struct hw_interrupt_type *irq_type;
 
 #ifdef DEBUG_IRQ_ROUTING
 	printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (%s, %s) -> vector %02x\n",
 	       (unsigned) irq, (unsigned) pin,
-	       polarity ? "high" : "low", edge_triggered ? "edge" : "level",
+	       (polarity == POLARITY_ACTIVE_HIGH) ? "high" : "low",
+	       (trigger == TRIGGER_EDGE) ? "edge" : "level",
 	       vector);
 #endif
 
 	iosapic_irq[vector].pin = pin;
 	iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY;
-	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
-	iosapic_irq[vector].trigger = edge_triggered ? IOSAPIC_EDGE : IOSAPIC_LEVEL;
+	iosapic_irq[vector].polarity = (polarity == POLARITY_ACTIVE_HIGH)
+		? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
+	if (trigger == TRIGGER_EDGE) {
+		iosapic_irq[vector].trigger = IOSAPIC_EDGE;
+		idesc->handler = &irq_type_iosapic_edge;
+	} else {
+		iosapic_irq[vector].trigger = IOSAPIC_LEVEL;
+		idesc->handler = &irq_type_iosapic_level;
+	}
+
+	/* reprogram IOSAPIC */
+	set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 }
 
 void __init

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-01-16 18:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-01-16  3:02 [Linux-ia64] [BUG] Interrupt source override (Re: ACPI power button events) KOCHI, Takayoshi
2002-01-16 18:47 ` [Linux-ia64] [BUG] Interrupt source override (Re: ACPI power Sluder, Charles

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox