aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h1
-rw-r--r--arch/mips/loongson/lemote-2f/irq.c4
-rw-r--r--arch/mips/loongson/lemote-2f/pm.c71
3 files changed, 72 insertions, 4 deletions
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index a7fa66e85988..06c28f387116 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -41,6 +41,7 @@ extern void __init bonito_irq_init(void);
41extern void __init set_irq_trigger_mode(void); 41extern void __init set_irq_trigger_mode(void);
42extern void __init mach_init_irq(void); 42extern void __init mach_init_irq(void);
43extern void mach_irq_dispatch(unsigned int pending); 43extern void mach_irq_dispatch(unsigned int pending);
44extern int mach_i8259_irq(void);
44 45
45/* We need this in some places... */ 46/* We need this in some places... */
46#define delay() ({ \ 47#define delay() ({ \
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
index 50e7bb6012b7..77d32f9cf31e 100644
--- a/arch/mips/loongson/lemote-2f/irq.c
+++ b/arch/mips/loongson/lemote-2f/irq.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/module.h>
12 13
13#include <asm/irq_cpu.h> 14#include <asm/irq_cpu.h>
14#include <asm/i8259.h> 15#include <asm/i8259.h>
@@ -30,7 +31,7 @@
30 * The generic i8259_irq() make the kernel hang on booting. Since we cannot 31 * The generic i8259_irq() make the kernel hang on booting. Since we cannot
31 * get the irq via the IRR directly, we access the ISR instead. 32 * get the irq via the IRR directly, we access the ISR instead.
32 */ 33 */
33static inline int mach_i8259_irq(void) 34int mach_i8259_irq(void)
34{ 35{
35 int irq, isr; 36 int irq, isr;
36 37
@@ -60,6 +61,7 @@ static inline int mach_i8259_irq(void)
60 61
61 return irq; 62 return irq;
62} 63}
64EXPORT_SYMBOL(mach_i8259_irq);
63 65
64static void i8259_irqdispatch(void) 66static void i8259_irqdispatch(void)
65{ 67{
diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c
index 8090d0514221..81c06410aa76 100644
--- a/arch/mips/loongson/lemote-2f/pm.c
+++ b/arch/mips/loongson/lemote-2f/pm.c
@@ -14,6 +14,7 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/pm.h> 15#include <linux/pm.h>
16#include <linux/i8042.h> 16#include <linux/i8042.h>
17#include <linux/module.h>
17 18
18#include <asm/i8259.h> 19#include <asm/i8259.h>
19#include <asm/mipsregs.h> 20#include <asm/mipsregs.h>
@@ -21,6 +22,8 @@
21 22
22#include <loongson.h> 23#include <loongson.h>
23 24
25#include "ec_kb3310b.h"
26
24#define I8042_KBD_IRQ 1 27#define I8042_KBD_IRQ 1
25#define I8042_CTR_KBDINT 0x01 28#define I8042_CTR_KBDINT 0x01
26#define I8042_CTR_KBDDIS 0x10 29#define I8042_CTR_KBDDIS 0x10
@@ -49,9 +52,6 @@ static int i8042_enable_kbd_port(void)
49 return 0; 52 return 0;
50} 53}
51 54
52/*
53 * The i8042 is connnected to i8259A
54 */
55void setup_wakeup_events(void) 55void setup_wakeup_events(void)
56{ 56{
57 int irq_mask; 57 int irq_mask;
@@ -65,9 +65,74 @@ void setup_wakeup_events(void)
65 65
66 /* enable keyboard port */ 66 /* enable keyboard port */
67 i8042_enable_kbd_port(); 67 i8042_enable_kbd_port();
68
69 /* Wakeup CPU via SCI lid open event */
70 outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR);
71 inb(PIC_MASTER_IMR);
72 outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR);
73 inb(PIC_SLAVE_IMR);
74
68 break; 75 break;
69 76
70 default: 77 default:
71 break; 78 break;
72 } 79 }
73} 80}
81
82static struct delayed_work lid_task;
83static int initialized;
84/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */
85sci_handler yeeloong_report_lid_status;
86EXPORT_SYMBOL(yeeloong_report_lid_status);
87static void yeeloong_lid_update_task(struct work_struct *work)
88{
89 if (yeeloong_report_lid_status)
90 yeeloong_report_lid_status(BIT_LID_DETECT_ON);
91}
92
93int wakeup_loongson(void)
94{
95 int irq;
96
97 /* query the interrupt number */
98 irq = mach_i8259_irq();
99 if (irq < 0)
100 return 0;
101
102 printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
103
104 if (irq == I8042_KBD_IRQ)
105 return 1;
106 else if (irq == SCI_IRQ_NUM) {
107 int ret, sci_event;
108 /* query the event number */
109 ret = ec_query_seq(CMD_GET_EVENT_NUM);
110 if (ret < 0)
111 return 0;
112 sci_event = ec_get_event_num();
113 if (sci_event < 0)
114 return 0;
115 if (sci_event == EVENT_LID) {
116 int lid_status;
117 /* check the LID status */
118 lid_status = ec_read(REG_LID_DETECT);
119 /* wakeup cpu when people open the LID */
120 if (lid_status == BIT_LID_DETECT_ON) {
121 /* If we call it directly here, the WARNING
122 * will be sent out by getnstimeofday
123 * via "WARN_ON(timekeeping_suspended);"
124 * because we can not schedule in suspend mode.
125 */
126 if (initialized == 0) {
127 INIT_DELAYED_WORK(&lid_task,
128 yeeloong_lid_update_task);
129 initialized = 1;
130 }
131 schedule_delayed_work(&lid_task, 1);
132 return 1;
133 }
134 }
135 }
136
137 return 0;
138}