MLK-9987: Input: imx_keypad: Fix suspend/resume while keypad is pressed
authorFabio Estevam <fabio.estevam@freescale.com>
Thu, 11 Dec 2014 15:14:22 +0000 (13:14 -0200)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:57:59 +0000 (14:57 -0500)
Since commit commit 560a64749d1dd0ff ("ENGR00318936-2 input: keyboard: imx:
remove usless release interrupt enabled) the following problem happens:

- Keep any keypad key pressed
- Enter low power mode via "echo mem > /sys/power/state"
- Then we are no longer able to wake-up the system via the keypad

The reason for this behaviour is that the KRIE (Release Interrupt) is not
enabled.

In order to fix this problem, we should enable KRIE when a key is pressed
(KPKD bit is set) or enable KDIE when no key is pressed (KPKR is set).

This way we will always have a valid source of keypad interrupt no matter if
the system entered low power mode while a keypad key was pressed or not.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
(cherry picked from commit 5a7ab47e67d1045cb2f5d408c112617dff48dee2)
(cherry picked from commit f75c35512bd3df7dbb26f4a35cf17dcbb6ffb724)

drivers/input/keyboard/imx_keypad.c

index ffc983d..a2a1630 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for the IMX keypad port.
  * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -544,9 +544,10 @@ static int __maybe_unused imx_kbd_suspend(struct device *dev)
        mutex_unlock(&input_dev->mutex);
 
        if (device_may_wakeup(&pdev->dev)) {
-               /* make sure KDI interrupt enabled */
-               reg_val |= KBD_STAT_KDIE;
-               reg_val &= ~KBD_STAT_KRIE;
+               if (reg_val & KBD_STAT_KPKD)
+                       reg_val |= KBD_STAT_KRIE;
+               if (reg_val & KBD_STAT_KPKR)
+                       reg_val |= KBD_STAT_KDIE;
                writew(reg_val, kbd->mmio_base + KPSR);
 
                enable_irq_wake(kbd->irq);