1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
From 71f219082f5c04a80f9b143fc92a51a3de5c6683 Mon Sep 17 00:00:00 2001
From: \\\\\\\"Mike (mwester)\\\\\\ <mwester@dls.net>
Date: Tue, 14 Oct 2008 05:46:34 +0100
Subject: [PATCH] suppress "onkey" events on resume [Was: Re: Where are actions configured for buttons in FSO?]
Michael 'Mickey' Lauer wrote:
...
> The problem is (and this is the reason why I'm crossposting this to the
> kernel mailing list), the kernel is not swallowing the power button
> presses that triggers the resume, so you need some "real" programming
> (as opposed to the expressional complexity of our rules) in order to
> prevent falling asleep right after resume.
>
> Kernel-guys, can we change that?
suppress-resume-onkey-event.patch
This suppresses the key press and key release events from the
power button, in the case where the power button is the wake
event for the GTA01 or GTA02 device.
Signed-off-by: Mike Westerhof <mwester@dls.net>
---
drivers/i2c/chips/pcf50606.c | 34 +++++++++++++++++++++++++++++-----
drivers/i2c/chips/pcf50633.c | 30 ++++++++++++++++++++++++++----
2 files changed, 55 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
index 18263fb..706ce6d 100644
--- a/drivers/i2c/chips/pcf50606.c
+++ b/drivers/i2c/chips/pcf50606.c
@@ -120,6 +120,7 @@ struct pcf50606_data {
int onkey_seconds;
int irq;
int coldplug_done;
+ int suppress_onkey_events;
enum pcf50606_suspend_states suspend_state;
#ifdef CONFIG_PM
struct {
@@ -656,9 +657,21 @@ static void pcf50606_work(struct work_struct *work)
*
* pcf50606 resume is really really over now then.
*/
- if (pcf->suspend_state != PCF50606_SS_RUNNING)
+ if (pcf->suspend_state != PCF50606_SS_RUNNING) {
pcf->suspend_state = PCF50606_SS_RUNNING;
+ /* peek at the IRQ reason, if power button then set a flag
+ * so that we do not signal the event to userspace
+ */
+ if (pcfirq[0] & (PCF50606_INT1_ONKEYF | PCF50606_INT1_ONKEYR)) {
+ pcf->suppress_onkey_events = 1;
+ dev_dbg(&pcf->client.dev,
+ "Wake by ONKEY, suppressing ONKEY events");
+ } else {
+ pcf->suppress_onkey_events = 0;
+ }
+ }
+
if (!pcf->coldplug_done) {
DEBUGPC("PMU Coldplug init\n");
@@ -689,9 +702,13 @@ static void pcf50606_work(struct work_struct *work)
if (pcfirq[0] & PCF50606_INT1_ONKEYF) {
/* ONKEY falling edge (start of button press) */
- DEBUGPC("ONKEYF ");
pcf->flags |= PCF50606_F_PWR_PRESSED;
- input_report_key(pcf->input_dev, KEY_POWER, 1);
+ if (!pcf->suppress_onkey_events) {
+ DEBUGPC("ONKEYF ");
+ input_report_key(pcf->input_dev, KEY_POWER, 1);
+ } else {
+ DEBUGPC("ONKEYF(unreported) ");
+ }
}
if (pcfirq[0] & PCF50606_INT1_ONKEY1S) {
/* ONKEY pressed for more than 1 second */
@@ -706,10 +723,16 @@ static void pcf50606_work(struct work_struct *work)
}
if (pcfirq[0] & PCF50606_INT1_ONKEYR) {
/* ONKEY rising edge (end of button press) */
- DEBUGPC("ONKEYR ");
pcf->flags &= ~PCF50606_F_PWR_PRESSED;
pcf->onkey_seconds = -1;
- input_report_key(pcf->input_dev, KEY_POWER, 0);
+ if (!pcf->suppress_onkey_events) {
+ DEBUGPC("ONKEYR ");
+ input_report_key(pcf->input_dev, KEY_POWER, 0);
+ } else {
+ DEBUGPC("ONKEYR(suppressed) ");
+ /* don't suppress any more power button events */
+ pcf->suppress_onkey_events = 0;
+ }
/* disable SECOND interrupt in case RTC didn't
* request it */
if (!(pcf->flags & PCF50606_F_RTC_SECOND))
@@ -1766,6 +1789,7 @@ static int pcf50606_detect(struct i2c_adapter *adapter, int address, int kind)
INIT_WORK(&data->work, pcf50606_work);
data->irq = irq;
data->working = 0;
+ data->suppress_onkey_events = 0;
data->onkey_seconds = -1;
data->pdata = pcf50606_pdev->dev.platform_data;
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index c186fdb..490e34d 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -135,6 +135,7 @@ struct pcf50633_data {
int usb_removal_count;
u8 pcfirq_resume[5];
int probe_completed;
+ int suppress_onkey_events;
/* if he pulls battery while charging, we notice that and correctly
* report that the charger is idle. But there is no interrupt that
@@ -848,6 +849,16 @@ static void pcf50633_work(struct work_struct *work)
/* pcf50633 resume is really really over now then */
pcf->suspend_state = PCF50633_SS_RUNNING;
+
+ /* peek at the IRQ reason, if power button then set a flag
+ * so that we do not signal the event to userspace
+ */
+ if (pcfirq[1] & (PCF50633_INT2_ONKEYF | PCF50633_INT2_ONKEYR)) {
+ pcf->suppress_onkey_events = 1;
+ DEBUGP("Wake by ONKEY, suppressing ONKEY event");
+ } else {
+ pcf->suppress_onkey_events = 0;
+ }
}
if (!pcf->coldplug_done) {
@@ -988,16 +999,26 @@ static void pcf50633_work(struct work_struct *work)
if (pcfirq[1] & PCF50633_INT2_ONKEYF) {
/* ONKEY falling edge (start of button press) */
- DEBUGPC("ONKEYF ");
pcf->flags |= PCF50633_F_PWR_PRESSED;
- input_report_key(pcf->input_dev, KEY_POWER, 1);
+ if (!pcf->suppress_onkey_events) {
+ DEBUGPC("ONKEYF ");
+ input_report_key(pcf->input_dev, KEY_POWER, 1);
+ } else {
+ DEBUGPC("ONKEYF(unreported) ");
+ }
}
if (pcfirq[1] & PCF50633_INT2_ONKEYR) {
/* ONKEY rising edge (end of button press) */
- DEBUGPC("ONKEYR ");
pcf->flags &= ~PCF50633_F_PWR_PRESSED;
pcf->onkey_seconds = -1;
- input_report_key(pcf->input_dev, KEY_POWER, 0);
+ if (!pcf->suppress_onkey_events) {
+ DEBUGPC("ONKEYR ");
+ input_report_key(pcf->input_dev, KEY_POWER, 0);
+ } else {
+ DEBUGPC("ONKEYR(unreported) ");
+ /* don't suppress any more power button events */
+ pcf->suppress_onkey_events = 0;
+ }
/* disable SECOND interrupt in case RTC didn't
* request it */
if (!(pcf->flags & PCF50633_F_RTC_SECOND))
@@ -2135,6 +2156,7 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
INIT_WORK(&pcf->work_usb_curlimit, pcf50633_work_usbcurlim);
pcf->irq = irq;
pcf->working = 0;
+ pcf->suppress_onkey_events = 0;
pcf->onkey_seconds = -1;
pcf->pdata = pcf50633_pdev->dev.platform_data;
--
1.5.6.5
|