[ltp] Patch to reenable APM suspend on 2.6.1-rc1

Charles Lepple linux-thinkpad@linux-thinkpad.org
Sun, 4 Jan 2004 12:04:38 -0500


--Boundary-00=_meE+/C0tXAq2y8u
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

The following patch to 2.6.1-rc1 enables my ThinkPad 770 to suspend (without 
the scripts I mentioned in previous emails). When using this patch, it is no 
longer necessary to configure the i8042 driver as a module.

It could easily be adapted to work on ACPI as well as APM, but since I don't 
know for certain whether the ACPI systems have the same problem, I will leave 
that patch to someone else.

On receipt of a suspend event from the APM BIOS, it stops the timer which 
polls the i8042 ports several times a second. This polling seems to be the 
reason why the ThinkPad APM BIOS will not suspend with 2.6 kernels.

I would be grateful to anyone who is willing to test this before I post it to 
the LKML. If it doesn't work, including your ThinkPad model along with the 
last few kernel messages ("dmesg | tail") would be helpful, along with a 
description of what the LEDs are doing when you try to suspend.

-- 
Charles Lepple
http://www.ghz.cc/charles/

--Boundary-00=_meE+/C0tXAq2y8u
Content-Type: text/x-diff;
  charset="us-ascii";
  name="i8042-stop-timer-on-suspend.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="i8042-stop-timer-on-suspend.patch"

--- linux-2.6.0/drivers/input/serio/i8042.c	2004-01-04 09:16:36.000000000 -0500
+++ linux-2.6.1-rc1/drivers/input/serio/i8042.c	2004-01-04 09:09:42.000000000 -0500
@@ -70,6 +70,7 @@
 static unsigned char i8042_sysdev_initialized;
 static struct pm_dev *i8042_pm_dev;
 struct timer_list i8042_timer;
+static int i8042_suspend;
 
 /*
  * Shared IRQ's require a device pointer, but this driver doesn't support
@@ -645,7 +646,8 @@
 static void i8042_timer_func(unsigned long data)
 {
 	i8042_interrupt(0, NULL, NULL);
-	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+	if(!i8042_suspend)
+		mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 }
 
 
@@ -858,6 +860,7 @@
 	return i8042_controller_resume();
 }
 
+/* TODO: add ThinkPad suspend handler here */
 static struct sysdev_class kbc_sysclass = {
        set_kset_name("i8042"),
        .resume = i8042_resume,
@@ -873,9 +876,19 @@
  */
 static int i8042_pm_callback(struct pm_dev *dev, pm_request_t request, void *dummy)
 {
-	if (request == PM_RESUME)
+	if (request == PM_RESUME) {
+		printk(KERN_DEBUG __FILE__ ": i8042_pm_callback(PM_RESUME)\n");
+		i8042_suspend = 0;
+		mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 		return i8042_controller_resume();
-
+	}
+	
+	if (request == PM_SUSPEND) {
+		printk(KERN_DEBUG __FILE__ ": i8042_pm_callback(PM_SUSPEND)\n");
+		i8042_suspend = 1;
+	}
+	
+	printk(KERN_DEBUG __FILE__ ": i8042_pm_callback(0x%x) -> 0\n", request);
 	return 0;
 }
 

--Boundary-00=_meE+/C0tXAq2y8u--