aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/keyboard/corgikbd.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index a31c3d64af32..43d6edb3cf09 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/input.h> 17#include <linux/input.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/jiffies.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <asm/irq.h> 22#include <asm/irq.h>
@@ -78,6 +79,9 @@ struct corgikbd {
78 79
79 struct timer_list timer; 80 struct timer_list timer;
80 struct timer_list htimer; 81 struct timer_list htimer;
82
83 unsigned int suspended;
84 unsigned long suspend_jiffies;
81}; 85};
82 86
83static void handle_scancode(unsigned int pressed,unsigned int scancode, struct corgikbd *corgikbd_data) 87static void handle_scancode(unsigned int pressed,unsigned int scancode, struct corgikbd *corgikbd_data)
@@ -85,8 +89,11 @@ static void handle_scancode(unsigned int pressed,unsigned int scancode, struct c
85 if (pressed && !(corgikbd_data->state[scancode] & CORGIKBD_PRESSED)) { 89 if (pressed && !(corgikbd_data->state[scancode] & CORGIKBD_PRESSED)) {
86 corgikbd_data->state[scancode] |= CORGIKBD_PRESSED; 90 corgikbd_data->state[scancode] |= CORGIKBD_PRESSED;
87 input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 1); 91 input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 1);
88 if (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF) 92 if ((corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
93 && time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
89 input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1); 94 input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
95 corgikbd_data->suspend_jiffies=jiffies;
96 }
90 } else if (!pressed && corgikbd_data->state[scancode] & CORGIKBD_PRESSED) { 97 } else if (!pressed && corgikbd_data->state[scancode] & CORGIKBD_PRESSED) {
91 corgikbd_data->state[scancode] &= ~CORGIKBD_PRESSED; 98 corgikbd_data->state[scancode] &= ~CORGIKBD_PRESSED;
92 input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 0); 99 input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], 0);
@@ -153,6 +160,9 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
153 unsigned long flags; 160 unsigned long flags;
154 unsigned int num_pressed; 161 unsigned int num_pressed;
155 162
163 if (corgikbd_data->suspended)
164 return;
165
156 spin_lock_irqsave(&corgikbd_data->lock, flags); 166 spin_lock_irqsave(&corgikbd_data->lock, flags);
157 167
158 if (regs) 168 if (regs)
@@ -255,6 +265,32 @@ static void corgikbd_hinge_timer(unsigned long data)
255 mod_timer(&corgikbd_data->htimer, jiffies + HINGE_SCAN_INTERVAL); 265 mod_timer(&corgikbd_data->htimer, jiffies + HINGE_SCAN_INTERVAL);
256} 266}
257 267
268#ifdef CONFIG_PM
269static int corgikbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
270{
271 if (level == SUSPEND_POWER_DOWN) {
272 struct corgikbd *corgikbd = dev_get_drvdata(dev);
273 corgikbd->suspended = 1;
274 }
275 return 0;
276}
277
278static int corgikbd_resume(struct device *dev, uint32_t level)
279{
280 if (level == RESUME_POWER_ON) {
281 struct corgikbd *corgikbd = dev_get_drvdata(dev);
282
283 /* Upon resume, ignore the suspend key for a short while */
284 corgikbd->suspend_jiffies=jiffies;
285 corgikbd->suspended = 0;
286 }
287 return 0;
288}
289#else
290#define corgikbd_suspend NULL
291#define corgikbd_resume NULL
292#endif
293
258static int __init corgikbd_probe(struct device *dev) 294static int __init corgikbd_probe(struct device *dev)
259{ 295{
260 int i; 296 int i;
@@ -279,6 +315,8 @@ static int __init corgikbd_probe(struct device *dev)
279 corgikbd->htimer.function = corgikbd_hinge_timer; 315 corgikbd->htimer.function = corgikbd_hinge_timer;
280 corgikbd->htimer.data = (unsigned long) corgikbd; 316 corgikbd->htimer.data = (unsigned long) corgikbd;
281 317
318 corgikbd->suspend_jiffies=jiffies;
319
282 init_input_dev(&corgikbd->input); 320 init_input_dev(&corgikbd->input);
283 corgikbd->input.private = corgikbd; 321 corgikbd->input.private = corgikbd;
284 corgikbd->input.name = "Corgi Keyboard"; 322 corgikbd->input.name = "Corgi Keyboard";
@@ -343,6 +381,8 @@ static struct device_driver corgikbd_driver = {
343 .bus = &platform_bus_type, 381 .bus = &platform_bus_type,
344 .probe = corgikbd_probe, 382 .probe = corgikbd_probe,
345 .remove = corgikbd_remove, 383 .remove = corgikbd_remove,
384 .suspend = corgikbd_suspend,
385 .resume = corgikbd_resume,
346}; 386};
347 387
348static int __devinit corgikbd_init(void) 388static int __devinit corgikbd_init(void)