mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
input: pwrkey: Handle out-of-order press and release interrupts
There is a possibility of receiving a release interrupt before press when both these actions (press and release) of the power-key are very close-by (~1-2ms) to the debounce time of the key. Handle this case by maintaining a state variable. Also mark the release interrupt as a wakeup source to wakeup the system when the above mentioned abnormal case occurs. CRs-Fixed: 394289 Change-Id: I74475c1e5159dd30e52aca91243eec7e2fac4d57 Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
This commit is contained in:
parent
75f55110dc
commit
93c63d759f
1 changed files with 26 additions and 3 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -35,6 +35,8 @@
|
|||
struct pmic8xxx_pwrkey {
|
||||
struct input_dev *pwr;
|
||||
int key_press_irq;
|
||||
int key_release_irq;
|
||||
bool press;
|
||||
const struct pm8xxx_pwrkey_platform_data *pdata;
|
||||
};
|
||||
|
||||
|
@ -42,6 +44,13 @@ static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey)
|
|||
{
|
||||
struct pmic8xxx_pwrkey *pwrkey = _pwrkey;
|
||||
|
||||
if (pwrkey->press == true) {
|
||||
pwrkey->press = false;
|
||||
return IRQ_HANDLED;
|
||||
} else {
|
||||
pwrkey->press = true;
|
||||
}
|
||||
|
||||
input_report_key(pwrkey->pwr, KEY_POWER, 1);
|
||||
input_sync(pwrkey->pwr);
|
||||
|
||||
|
@ -52,6 +61,14 @@ static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey)
|
|||
{
|
||||
struct pmic8xxx_pwrkey *pwrkey = _pwrkey;
|
||||
|
||||
if (pwrkey->press == false) {
|
||||
input_report_key(pwrkey->pwr, KEY_POWER, 1);
|
||||
input_sync(pwrkey->pwr);
|
||||
pwrkey->press = true;
|
||||
} else {
|
||||
pwrkey->press = false;
|
||||
}
|
||||
|
||||
input_report_key(pwrkey->pwr, KEY_POWER, 0);
|
||||
input_sync(pwrkey->pwr);
|
||||
|
||||
|
@ -63,8 +80,10 @@ static int pmic8xxx_pwrkey_suspend(struct device *dev)
|
|||
{
|
||||
struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
if (device_may_wakeup(dev)) {
|
||||
enable_irq_wake(pwrkey->key_press_irq);
|
||||
enable_irq_wake(pwrkey->key_release_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -73,8 +92,10 @@ static int pmic8xxx_pwrkey_resume(struct device *dev)
|
|||
{
|
||||
struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
if (device_may_wakeup(dev)) {
|
||||
disable_irq_wake(pwrkey->key_press_irq);
|
||||
disable_irq_wake(pwrkey->key_release_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -155,7 +176,9 @@ static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
pwrkey->key_press_irq = key_press_irq;
|
||||
pwrkey->key_release_irq = key_release_irq;
|
||||
pwrkey->pwr = pwr;
|
||||
pwrkey->press = false;
|
||||
|
||||
platform_set_drvdata(pdev, pwrkey);
|
||||
|
||||
|
|
Loading…
Reference in a new issue