From ea4dac67b9849ed076982e81b3753ef5044f5df3 Mon Sep 17 00:00:00 2001 From: Xingyu Chen Date: Thu, 15 Mar 2018 11:11:12 +0800 Subject: [PATCH] keypad: avoid repetition of reporting power key event PD#160889: keypad: avoid repetition of reporting power key event If the adc_keypad and gpio_keypad driver are enabled at the same time, the system will report two power key event when it resumes, and the second event will result in the system suspend again. The patch resolves the bug. Change-Id: Iea4d9e2bf6632e4603dc9743fce07e5af74d0273 Signed-off-by: Xingyu Chen --- drivers/amlogic/input/keyboard/adc_keypad.c | 20 ++++++++++---- drivers/amlogic/input/keyboard/gpio_keypad.c | 29 +++++++++++++++----- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/amlogic/input/keyboard/adc_keypad.c b/drivers/amlogic/input/keyboard/adc_keypad.c index 146f4bfc2bae..6c61fb769f93 100644 --- a/drivers/amlogic/input/keyboard/adc_keypad.c +++ b/drivers/amlogic/input/keyboard/adc_keypad.c @@ -609,14 +609,24 @@ static int meson_adc_kp_suspend(struct platform_device *pdev, static int meson_adc_kp_resume(struct platform_device *pdev) { + struct adc_key *key; struct meson_adc_kp *kp = platform_get_drvdata(pdev); if (get_resume_method() == POWER_KEY_WAKEUP) { - dev_info(&pdev->dev, "adc keypad wakeup\n"); - input_report_key(kp->poll_dev->input, KEY_POWER, 1); - input_sync(kp->poll_dev->input); - input_report_key(kp->poll_dev->input, KEY_POWER, 0); - input_sync(kp->poll_dev->input); + list_for_each_entry(key, &kp->adckey_head, list) { + if (key->code == KEY_POWER) { + dev_info(&pdev->dev, "adc keypad wakeup\n"); + + input_report_key(kp->poll_dev->input, + KEY_POWER, 1); + input_sync(kp->poll_dev->input); + input_report_key(kp->poll_dev->input, + KEY_POWER, 0); + input_sync(kp->poll_dev->input); + + break; + } + } } return 0; } diff --git a/drivers/amlogic/input/keyboard/gpio_keypad.c b/drivers/amlogic/input/keyboard/gpio_keypad.c index cc26ff9e1f41..35abea93ba2e 100644 --- a/drivers/amlogic/input/keyboard/gpio_keypad.c +++ b/drivers/amlogic/input/keyboard/gpio_keypad.c @@ -51,6 +51,9 @@ #define MOD_NAME "gpio_key" +#undef pr_fmt +#define pr_fmt(fmt) "gpio_key: " fmt + struct gpio_key { int code; /* input key code */ const char *name; @@ -154,7 +157,7 @@ static irqreturn_t kp_isr(int irq, void *data) { struct kp *kp_data = (struct kp *)data; - schedule_work(&(kp_data->work_update)); + queue_work(system_freezable_wq, &(kp_data->work_update)); /* if (!deep_suspend_flag) * clr_pwr_key(); @@ -167,7 +170,7 @@ void kp_timer_sr(unsigned long data) { struct kp *kp_data = (struct kp *)data; - schedule_work(&(kp_data->work_update)); + queue_work(system_freezable_wq, &(kp_data->work_update)); mod_timer(&kp_data->timer, jiffies+msecs_to_jiffies(25)); } #endif @@ -441,12 +444,24 @@ static int gpio_key_suspend(struct platform_device *dev, pm_message_t state) static int gpio_key_resume(struct platform_device *dev) { + int i; + struct gpio_platform_data *pdata; + + pdata = (struct gpio_platform_data *)platform_get_drvdata(dev); + if (get_resume_method() == POWER_KEY_WAKEUP) { - pr_info("gpio keypad wakeup\n"); - input_report_key(gp_kp->input, KEY_POWER, 1); - input_sync(gp_kp->input); - input_report_key(gp_kp->input, KEY_POWER, 0); - input_sync(gp_kp->input); + for (i = 0; i < pdata->key_num; i++) { + if (pdata->key[i].code == KEY_POWER) { + pr_info("gpio keypad wakeup\n"); + + input_report_key(gp_kp->input, KEY_POWER, 1); + input_sync(gp_kp->input); + input_report_key(gp_kp->input, KEY_POWER, 0); + input_sync(gp_kp->input); + + break; + } + } } return 0; }