diff options
author | Tony Lindgren <tony@atomide.com> | 2018-12-04 16:52:49 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-12-09 00:48:48 -0500 |
commit | e2ca26ec4f01486661b55b03597c13e2b9c18b73 (patch) | |
tree | ff14d8fd8a4b993b12086b11c0cb202c125b744a | |
parent | 6c3516fed7b61a3527459ccfa67fab130d910610 (diff) |
Input: omap-keypad - fix idle configuration to not block SoC idle states
With PM enabled, I noticed that pressing a key on the droid4 keyboard will
block deeper idle states for the SoC. Let's fix this by using IRQF_ONESHOT
and stop constantly toggling the device OMAP4_KBD_IRQENABLE register as
suggested by Dmitry Torokhov <dmitry.torokhov@gmail.com>.
From the hardware point of view, looks like we need to manage the registers
for OMAP4_KBD_IRQENABLE and OMAP4_KBD_WAKEUPENABLE together to avoid
blocking deeper SoC idle states. And with toggling of OMAP4_KBD_IRQENABLE
register now gone with IRQF_ONESHOT, also the SoC idle state problem is
gone during runtime. We still also need to clear OMAP4_KBD_WAKEUPENABLE in
omap4_keypad_close() though to pair it with omap4_keypad_open() to prevent
blocking deeper SoC idle states after rmmod omap4-keypad.
Reported-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/keyboard/omap4-keypad.c | 16 |
1 files changed, 4 insertions, 12 deletions
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index ce8e2baf31bb..616fdd94b069 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -126,12 +126,8 @@ static irqreturn_t omap4_keypad_irq_handler(int irq, void *dev_id) | |||
126 | { | 126 | { |
127 | struct omap4_keypad *keypad_data = dev_id; | 127 | struct omap4_keypad *keypad_data = dev_id; |
128 | 128 | ||
129 | if (kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)) { | 129 | if (kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)) |
130 | /* Disable interrupts */ | ||
131 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | ||
132 | OMAP4_VAL_IRQDISABLE); | ||
133 | return IRQ_WAKE_THREAD; | 130 | return IRQ_WAKE_THREAD; |
134 | } | ||
135 | 131 | ||
136 | return IRQ_NONE; | 132 | return IRQ_NONE; |
137 | } | 133 | } |
@@ -173,11 +169,6 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) | |||
173 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, | 169 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, |
174 | kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); | 170 | kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); |
175 | 171 | ||
176 | /* enable interrupts */ | ||
177 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | ||
178 | OMAP4_DEF_IRQENABLE_EVENTEN | | ||
179 | OMAP4_DEF_IRQENABLE_LONGKEY); | ||
180 | |||
181 | return IRQ_HANDLED; | 172 | return IRQ_HANDLED; |
182 | } | 173 | } |
183 | 174 | ||
@@ -214,9 +205,10 @@ static void omap4_keypad_close(struct input_dev *input) | |||
214 | 205 | ||
215 | disable_irq(keypad_data->irq); | 206 | disable_irq(keypad_data->irq); |
216 | 207 | ||
217 | /* Disable interrupts */ | 208 | /* Disable interrupts and wake-up events */ |
218 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, | 209 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, |
219 | OMAP4_VAL_IRQDISABLE); | 210 | OMAP4_VAL_IRQDISABLE); |
211 | kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE, 0); | ||
220 | 212 | ||
221 | /* clear pending interrupts */ | 213 | /* clear pending interrupts */ |
222 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, | 214 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, |
@@ -364,7 +356,7 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
364 | } | 356 | } |
365 | 357 | ||
366 | error = request_threaded_irq(keypad_data->irq, omap4_keypad_irq_handler, | 358 | error = request_threaded_irq(keypad_data->irq, omap4_keypad_irq_handler, |
367 | omap4_keypad_irq_thread_fn, 0, | 359 | omap4_keypad_irq_thread_fn, IRQF_ONESHOT, |
368 | "omap4-keypad", keypad_data); | 360 | "omap4-keypad", keypad_data); |
369 | if (error) { | 361 | if (error) { |
370 | dev_err(&pdev->dev, "failed to register interrupt\n"); | 362 | dev_err(&pdev->dev, "failed to register interrupt\n"); |