[debian-yeeloong-project] linux kernel: suspend patch changes need testing

Andreas Barth aba at not.so.argh.org
Thu Sep 15 19:19:37 UTC 2011


Hi,

I just wrote a patch moving pm.c from arch/mips/loongson/lemote-2f to
arch/mips/loongson/common (with the goal to produce a kernel running
on 2e and 2f). I however lack hardware using suspend, so I cannot test
it.

The patch is below (arch/mips/loongson/lemote-2f/Makefile probably
won't apply cleanly, but well). I put an (otherwise?) working kernel on
http://alius.ayous.org/~aba/linux-lemote-2f-suspendpatch.tgz (this is
just a tar file containing a 3.1.0-rc6 kernel) with this md5sum:
15c2cabaa9768a25526cd62d028e4c19  linux-lemote-2f-suspendpatch.tgz



Feedback welcome.


Andi


---
 arch/mips/loongson/common/pm.c        |  126 +++++++++++++++++++++++++++-
 arch/mips/loongson/lemote-2f/Makefile |    2 -
 arch/mips/loongson/lemote-2f/pm.c     |  149 ---------------------------------
 3 files changed, 125 insertions(+), 152 deletions(-)
 delete mode 100644 arch/mips/loongson/lemote-2f/pm.c

diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c
index f55e07a..9ba07e5 100644
--- a/arch/mips/loongson/common/pm.c
+++ b/arch/mips/loongson/common/pm.c
@@ -12,9 +12,15 @@
 #include <linux/suspend.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/i8042.h>
+#include <linux/module.h>
 
 #include <asm/i8259.h>
 #include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+#include "ec_kb3310b.h"
 
 #include <loongson.h>
 
@@ -60,18 +66,132 @@ void arch_suspend_enable_irqs(void)
 /*
  * Setup the board-specific events for waking up loongson from wait mode
  */
-void __weak setup_wakeup_events(void)
+
+#define I8042_KBD_IRQ		1
+#define I8042_CTR_KBDINT	0x01
+#define I8042_CTR_KBDDIS	0x10
+
+static unsigned char i8042_ctr;
+
+static int i8042_enable_kbd_port(void)
 {
+
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
+		pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port."
+		"\n");
+	}
+
+	i8042_ctr &= ~I8042_CTR_KBDDIS;
+	i8042_ctr |= I8042_CTR_KBDINT;
+
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+		i8042_ctr &= ~I8042_CTR_KBDINT;
+		i8042_ctr |= I8042_CTR_KBDDIS;
+		pr_err("i8042.c: Failed to enable KBD port.\n");
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+void setup_wakeup_events(void)
+{
+	int irq_mask;
+
+	switch (mips_machtype) {
+	case MACH_LEMOTE_ML2F7:
+	case MACH_LEMOTE_YL2F89:
+		/* open the keyboard irq in i8259A */
+		outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR);
+		irq_mask = inb(PIC_MASTER_IMR);
+
+		/* enable keyboard port */
+		i8042_enable_kbd_port();
+
+		/* Wakeup CPU via SCI lid open event */
+		outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR);
+		inb(PIC_MASTER_IMR);
+		outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR);
+		inb(PIC_SLAVE_IMR);
+
+		break;
+
+	default:
+		break;
+	}
 }
 
 /*
  * Check wakeup events
  */
+int wakeup_loongson_2f(void);
 int __weak wakeup_loongson(void)
 {
+        if (mips_machtype != MACH_LEMOTE_FL2E)
+		return wakeup_loongson_2f();
 	return 1;
 }
 
+
+static struct delayed_work lid_task;
+static int initialized;
+/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */
+sci_handler yeeloong_report_lid_status;
+EXPORT_SYMBOL(yeeloong_report_lid_status);
+static void yeeloong_lid_update_task(struct work_struct *work)
+{
+	if (yeeloong_report_lid_status)
+		yeeloong_report_lid_status(BIT_LID_DETECT_ON);
+}
+
+int wakeup_loongson_2f(void)
+{
+	int irq;
+
+	/* query the interrupt number */
+	irq = mach_i8259_irq();
+	if (irq < 0)
+		return 0;
+
+	printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
+
+	if (irq == I8042_KBD_IRQ)
+		return 1;
+	else if (irq == SCI_IRQ_NUM) {
+		int ret, sci_event;
+		/* query the event number */
+		ret = ec_query_seq(CMD_GET_EVENT_NUM);
+		if (ret < 0)
+			return 0;
+		sci_event = ec_get_event_num();
+		if (sci_event < 0)
+			return 0;
+		if (sci_event == EVENT_LID) {
+			int lid_status;
+			/* check the LID status */
+			lid_status = ec_read(REG_LID_DETECT);
+			/* wakeup cpu when people open the LID */
+			if (lid_status == BIT_LID_DETECT_ON) {
+				/* If we call it directly here, the WARNING
+				 * will be sent out by getnstimeofday
+				 * via "WARN_ON(timekeeping_suspended);"
+				 * because we can not schedule in suspend mode.
+				 */
+				if (initialized == 0) {
+					INIT_DELAYED_WORK(&lid_task,
+						yeeloong_lid_update_task);
+					initialized = 1;
+				}
+				schedule_delayed_work(&lid_task, 1);
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
 /*
  * If the events are really what we want to wakeup the CPU, wake it up
  * otherwise put the CPU asleep again.
@@ -116,10 +236,14 @@ static void loongson_suspend_enter(void)
 
 void __weak mach_suspend(void)
 {
+        if (mips_machtype != MACH_LEMOTE_FL2E)
+		disable_mfgpt0_counter();
 }
 
 void __weak mach_resume(void)
 {
+        if (mips_machtype != MACH_LEMOTE_FL2E)
+		enable_mfgpt0_counter();
 }
 
 static int loongson_pm_enter(suspend_state_t state)
diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile
index 8f676cd..3e37018 100644
--- a/arch/mips/loongson/lemote-2f/Makefile
+++ b/arch/mips/loongson/lemote-2f/Makefile
@@ -7,5 +7,3 @@ obj-y += irq.o
 #
 # Suspend Support
 #
-
-obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c
deleted file mode 100644
index c48ba65..0000000
--- a/arch/mips/loongson/lemote-2f/pm.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *  Lemote loongson2f family machines' specific suspend support
- *
- *  Copyright (C) 2009 Lemote Inc.
- *  Author: Wu Zhangjin <wuzhangjin at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/suspend.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/i8042.h>
-#include <linux/module.h>
-
-#include <asm/i8259.h>
-#include <asm/mipsregs.h>
-#include <asm/bootinfo.h>
-
-#include <loongson.h>
-
-#include <cs5536/cs5536_mfgpt.h>
-#include "../common/ec_kb3310b.h"
-
-#define I8042_KBD_IRQ		1
-#define I8042_CTR_KBDINT	0x01
-#define I8042_CTR_KBDDIS	0x10
-
-static unsigned char i8042_ctr;
-
-static int i8042_enable_kbd_port(void)
-{
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
-		pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port."
-		       "\n");
-		return -EIO;
-	}
-
-	i8042_ctr &= ~I8042_CTR_KBDDIS;
-	i8042_ctr |= I8042_CTR_KBDINT;
-
-	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		i8042_ctr &= ~I8042_CTR_KBDINT;
-		i8042_ctr |= I8042_CTR_KBDDIS;
-		pr_err("i8042.c: Failed to enable KBD port.\n");
-
-		return -EIO;
-	}
-
-	return 0;
-}
-
-void setup_wakeup_events(void)
-{
-	int irq_mask;
-
-	switch (mips_machtype) {
-	case MACH_LEMOTE_ML2F7:
-	case MACH_LEMOTE_YL2F89:
-		/* open the keyboard irq in i8259A */
-		outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR);
-		irq_mask = inb(PIC_MASTER_IMR);
-
-		/* enable keyboard port */
-		i8042_enable_kbd_port();
-
-		/* Wakeup CPU via SCI lid open event */
-		outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR);
-		inb(PIC_MASTER_IMR);
-		outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR);
-		inb(PIC_SLAVE_IMR);
-
-		break;
-
-	default:
-		break;
-	}
-}
-
-static struct delayed_work lid_task;
-static int initialized;
-/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */
-sci_handler yeeloong_report_lid_status;
-EXPORT_SYMBOL(yeeloong_report_lid_status);
-static void yeeloong_lid_update_task(struct work_struct *work)
-{
-	if (yeeloong_report_lid_status)
-		yeeloong_report_lid_status(BIT_LID_DETECT_ON);
-}
-
-int wakeup_loongson(void)
-{
-	int irq;
-
-	/* query the interrupt number */
-	irq = mach_i8259_irq();
-	if (irq < 0)
-		return 0;
-
-	printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
-
-	if (irq == I8042_KBD_IRQ)
-		return 1;
-	else if (irq == SCI_IRQ_NUM) {
-		int ret, sci_event;
-		/* query the event number */
-		ret = ec_query_seq(CMD_GET_EVENT_NUM);
-		if (ret < 0)
-			return 0;
-		sci_event = ec_get_event_num();
-		if (sci_event < 0)
-			return 0;
-		if (sci_event == EVENT_LID) {
-			int lid_status;
-			/* check the LID status */
-			lid_status = ec_read(REG_LID_DETECT);
-			/* wakeup cpu when people open the LID */
-			if (lid_status == BIT_LID_DETECT_ON) {
-				/* If we call it directly here, the WARNING
-				 * will be sent out by getnstimeofday
-				 * via "WARN_ON(timekeeping_suspended);"
-				 * because we can not schedule in suspend mode.
-				 */
-				if (initialized == 0) {
-					INIT_DELAYED_WORK(&lid_task,
-						yeeloong_lid_update_task);
-					initialized = 1;
-				}
-				schedule_delayed_work(&lid_task, 1);
-				return 1;
-			}
-		}
-	}
-
-	return 0;
-}
-
-void __weak mach_suspend(void)
-{
-	disable_mfgpt0_counter();
-}
-
-void __weak mach_resume(void)
-{
-	enable_mfgpt0_counter();
-}
-- 
1.7.5.4



More information about the debian-yeeloong-project mailing list