Re: acpi-20040715: functional regression on ASUS M2N

Georg C. F. Greve
2004-08-04T00:23:31Z

[-- Attachment #1.1: Type: text/plain, Size: 697 bytes --]

|| On Mon, 02 Aug 2004 12:45:16 -0400
|| Nathan Bryant <nbryant-p32f3XyCuykqcZcGjlUOXw@public.gmane.org> wrote:

>> I added your suggested patch to arch/i386/kernel/i8259.c and
>> recompiled. Problem persists, no difference I could tell.

nb> I don't know why the patch masks out the reserved
nb> interrupts. None of the other code that sets ELCR is masking out
nb> those bits, and it all works fine. Possibly some chipsets use
nb> different edge/level behavior for these, and the save code is
nb> forcing them back to edge. Does the problem persist if you go
nb> into arch/i386/kernel/i8259.c and change: [...]

Yup. Problem persists.

Just took a working, patched 2.6.7 and applied

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: fix-acpi-after-s3.patch --]
[-- Type: text/x-patch, Size: 2410 bytes --]

===== arch/i386/kernel/i8259.c 1.30 vs edited =====
--- 1.30/arch/i386/kernel/i8259.c Thu Apr 22 19:15:40 2004
+++ edited/arch/i386/kernel/i8259.c Tue Jun 29 15:35:28 2004
@@ -238,14 +238,39 @@
}
}

+static char irq_trigger[2];
+/**
+ * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
+ */
+static void restore_ELCR(char *trigger)
+{
+ outb(trigger[0], 0x4d0);
+ outb(trigger[1], 0x4d1);
+}
+
+static void save_ELCR(char *trigger)
+{
+ /* IRQ 0,1,2,8,13 are marked as reserved */
+ trigger[0] = inb(0x4d0) & 0xF8;
+ trigger[1] = inb(0x4d1) & 0xDE;
+}
+
static int i8259A_resume(struct sys_device *dev)
{
init_8259A(0);
+ restore_ELCR(irq_trigger);
+ return 0;
+}
+
+static int i8259A_suspend(struct sys_device *dev, u32 state)
+{
+ save_ELCR(irq_trigger);
return 0;
}

static struct sysdev_class i8259_sysdev_class = {
set_kset_name("i8259"),
+ .suspend = i8259A_suspend,
.resume = i8259A_resume,
};

===== arch/x86_64/kernel/i8259.c 1.12 vs edited =====
--- 1.12/arch/x86_64/kernel/i8259.c Wed Apr 21 08:55:12 2004
+++ edited/arch/x86_64/kernel/i8259.c Tue Jun 29 15:36:08 2004
@@ -318,7 +318,7 @@
}
}

-void __init init_8259A(int auto_eoi)
+void init_8259A(int auto_eoi)
{
unsigned long flags;

@@ -360,6 +360,57 @@

spin_unlock_irqrestore(&i8259A_lock, flags);
}
+
+static char irq_trigger[2];
+/**
+ * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
+ */
+static void restore_ELCR(char *trigger)
+{
+ outb(trigger[0], 0x4d0);
+ outb(trigger[1], 0x4d1);
+}
+
+static void save_ELCR(char *trigger)
+{
+ /* IRQ 0,1,2,8,13 are marked as reserved */
+ trigger[0] = inb(0x4d0) & 0xF8;
+ trigger[1] = inb(0x4d1) & 0xDE;
+}
+
+static int i8259A_resume(struct sys_device *dev)
+{
+ init_8259A(0);
+ restore_ELCR(irq_trigger);
+ return 0;
+}
+
+static int i8259A_suspend(struct sys_device *dev, u32 state)
+{
+ save_ELCR(irq_trigger);
+ return 0;
+}
+
+static struct sysdev_class i8259_sysdev_class = {
+ set_kset_name("i8259"),
+ .suspend = i8259A_suspend,
+ .resume = i8259A_resume,
+};
+
+static struct sys_device device_i8259A = {
+ .id = 0,
+ .cls = &i8259_sysdev_class,
+};
+
+static int __init i8259A_init_sysfs(void)
+{
+ int error = sysdev_class_register(&i8259_sysdev_class);
+ if (!error)
+ error = sysdev_register(&device_i8259A);
+ return error;
+}
+
+device_initcall(i8259A_init_sysfs);

/*
* IRQ2 is cascade interrupt to second interrupt controller

[-- Attachment #1.3: Type: text/plain, Size: 40 bytes --]

which is causing the problem and also

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.4: S3-fix.patch --]
[-- Type: text/x-patch, Size: 660 bytes --]

--- arch/i386/kernel/i8259.c.orig 2004-08-04 01:44:05.000000000 +0200
+++ arch/i386/kernel/i8259.c 2004-08-04 01:45:43.000000000 +0200
@@ -251,14 +251,18 @@ static void restore_ELCR(char *trigger)
static void save_ELCR(char *trigger)
{
/* IRQ 0,1,2,8,13 are marked as reserved */
- trigger[0] = inb(0x4d0) & 0xF8;
- trigger[1] = inb(0x4d1) & 0xDE;
+ trigger[0] = inb(0x4d0);
+ trigger[1] = inb(0x4d1);
}

static int i8259A_resume(struct sys_device *dev)
{
- init_8259A(0);
+ unsigned long flags;
+ init_8259A(0);
+
+ spin_lock_irqsave(&i8259A_lock, flags);
restore_ELCR(irq_trigger);
+ spin_unlock_irqrestore(&i8259A_lock, flags);
return 0;
}

[-- Attachment #1.5: Type: text/plain, Size: 659 bytes --]

which we hoped to be fixing the problem.

The machine goes into S3 and upon wake up shows same behaviour as
without "hopefully fixing patch": Crashes with "inu" in yellow on the
left in upper row visible. After poweroff, only "needle-pushed reset"
will bring it back to life.

So current ACPI is still showing functional regression on ASUS M2N.

Anyone other ideas? Anyone ready to solve the puzzle?

Regards,
Georg

--
Georg C. F. Greve <greve-mXXj517/zsQ@public.gmane.org>
Free Software Foundation Europe (http://fsfeurope.org)
Brave GNU World (http://brave-gnu-world.org)

[-- Attachment #2: Type: application/pgp-signature, Size: 188 bytes --]