diff options
| -rw-r--r-- | arch/mips/include/asm/mach-loongson/loongson.h | 1 | ||||
| -rw-r--r-- | arch/mips/loongson/lemote-2f/irq.c | 4 | ||||
| -rw-r--r-- | arch/mips/loongson/lemote-2f/pm.c | 71 |
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); | |||
| 41 | extern void __init set_irq_trigger_mode(void); | 41 | extern void __init set_irq_trigger_mode(void); |
| 42 | extern void __init mach_init_irq(void); | 42 | extern void __init mach_init_irq(void); |
| 43 | extern void mach_irq_dispatch(unsigned int pending); | 43 | extern void mach_irq_dispatch(unsigned int pending); |
| 44 | extern 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 | */ |
| 33 | static inline int mach_i8259_irq(void) | 34 | int 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 | } |
| 64 | EXPORT_SYMBOL(mach_i8259_irq); | ||
| 63 | 65 | ||
| 64 | static void i8259_irqdispatch(void) | 66 | static 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 | */ | ||
| 55 | void setup_wakeup_events(void) | 55 | void 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 | |||
| 82 | static struct delayed_work lid_task; | ||
| 83 | static int initialized; | ||
| 84 | /* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */ | ||
| 85 | sci_handler yeeloong_report_lid_status; | ||
| 86 | EXPORT_SYMBOL(yeeloong_report_lid_status); | ||
| 87 | static 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 | |||
| 93 | int 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 | } | ||
