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 <[email protected]>
- *
- * 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


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]
Archive: http://lists.debian.org/[email protected]

Reply via email to