diff options
author | Sivakumar Pothireddy <sivakumar.pothireddy@ti.com> | 2011-12-26 02:18:51 -0600 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 13:00:36 +0200 |
commit | 72429f9e56e52c57ca61357549bd549e54133f62 (patch) | |
tree | 126ba59abf045b19559e971a7b475ef6137298f2 /drivers/input | |
parent | dc868b791b4ea7ac19b3f64e208bda9685f9301f (diff) | |
download | kernel_samsung_tuna-72429f9e56e52c57ca61357549bd549e54133f62.zip kernel_samsung_tuna-72429f9e56e52c57ca61357549bd549e54133f62.tar.gz kernel_samsung_tuna-72429f9e56e52c57ca61357549bd549e54133f62.tar.bz2 |
OMAP4: Workaround to avoid Long Key Press to resume from suspend.
TWL PIH interrupt gets enabled earlier than the module level interrupts.
KeyPress has 2 events. Press and Release event for each Key press. There
is only bit in the Register which maintains both the status.
Due to delay in interrupt enabling we are loosing Press event interrupts.
This patch maintains the prev state of keyevent. If current event is
same as prev event we provide press/release event to the upper layer.
Change-Id: I01808c7a52e62c951b8da178b02e1a5f9edb3b03
Signed-off-by: Sivakumar Pothireddy <sivakumar.pothireddy@ti.com>
Signed-off-by: Rajeev Kulkarni <rajeevk@ti.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/misc/twl6030-pwrbutton.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/input/misc/twl6030-pwrbutton.c b/drivers/input/misc/twl6030-pwrbutton.c index d653eae..ad9cd97 100644 --- a/drivers/input/misc/twl6030-pwrbutton.c +++ b/drivers/input/misc/twl6030-pwrbutton.c @@ -33,6 +33,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/i2c/twl.h> +#include <linux/delay.h> #define PWR_PWRON_IRQ (1 << 0) #define STS_HW_CONDITIONS 0x21 @@ -76,12 +77,28 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) { struct twl6030_pwr_button *pwr = _pwr; int hw_state; + int pwr_val; + static int prev_hw_state = 0xFFFF; hw_state = twl6030_readb(pwr, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); + pwr_val = !(hw_state & PWR_PWRON_IRQ); + if (prev_hw_state != pwr_val) { + input_report_key(pwr->input_dev, pwr->report_key, + pwr_val); + input_sync(pwr->input_dev); + } else { + input_report_key(pwr->input_dev, pwr->report_key, + !pwr_val); + input_sync(pwr->input_dev); + + msleep(20); + + input_report_key(pwr->input_dev, pwr->report_key, + pwr_val); + input_sync(pwr->input_dev); + } - input_report_key(pwr->input_dev, pwr->report_key, - !(hw_state & PWR_PWRON_IRQ)); - input_sync(pwr->input_dev); + prev_hw_state = pwr_val; return IRQ_HANDLED; } |