From: Anson Huang <anson.huang@nxp.com> To: "dmitry.torokhov@gmail.com" <dmitry.torokhov@gmail.com>, "shawnguo@kernel.org" <shawnguo@kernel.org>, "s.hauer@pengutronix.de" <s.hauer@pengutronix.de>, "kernel@pengutronix.de" <kernel@pengutronix.de>, "festevam@gmail.com" <festevam@gmail.com>, "linux-input@vger.kernel.org" <linux-input@vger.kernel.org>, "linux-arm-kernel@lists.infradead.org" <linux-arm-kernel@lists.infradead.org>, "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org> Cc: dl-linux-imx <linux-imx@nxp.com> Subject: [PATCH 2/2] input: keyboard: imx: make sure keyboard can always wake up system Date: Fri, 29 Mar 2019 07:00:46 +0000 [thread overview] Message-ID: <1553842562-8481-2-git-send-email-Anson.Huang@nxp.com> (raw) In-Reply-To: <1553842562-8481-1-git-send-email-Anson.Huang@nxp.com> There are several scenarios that keyboard can NOT wake up system from suspend, e.g., if a keyboard is depressed between system device suspend phase and device noirq suspend phase, the keyboard ISR will be called and both keyboard depress and release interrupts will be disabled, then keyboard will no longer be able to wake up system. Another scenario would be, if a keyboard is kept depressed, and then system goes into suspend, the expected behavior would be when keyboard is released, system will be waked up, but current implementation can NOT achieve that, because both depress and release interrupts are disabled in ISR, and the event check is still in progress. To fix these issues, need to make sure keyboard's depress or release interrupt is enabled after noirq device suspend phase, this patch moves the suspend/resume callback to noirq suspend/resume phase, and enable the corresponding interrupt according to current keyboard status. Signed-off-by: Anson Huang <Anson.Huang@nxp.com> --- drivers/input/keyboard/imx_keypad.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 7e32c36..9ae2090 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -521,11 +521,12 @@ static int imx_keypad_probe(struct platform_device *pdev) return 0; } -static int __maybe_unused imx_kbd_suspend(struct device *dev) +static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx_keypad *kbd = platform_get_drvdata(pdev); struct input_dev *input_dev = kbd->input_dev; + unsigned short reg_val = readw(kbd->mmio_base + KPSR); /* imx kbd can wake up system even clock is disabled */ mutex_lock(&input_dev->mutex); @@ -535,13 +536,20 @@ static int __maybe_unused imx_kbd_suspend(struct device *dev) mutex_unlock(&input_dev->mutex); - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(&pdev->dev)) { + 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); + } return 0; } -static int __maybe_unused imx_kbd_resume(struct device *dev) +static int __maybe_unused imx_kbd_noirq_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx_keypad *kbd = platform_get_drvdata(pdev); @@ -565,7 +573,9 @@ static int __maybe_unused imx_kbd_resume(struct device *dev) return ret; } -static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); +static const struct dev_pm_ops imx_kbd_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_kbd_noirq_suspend, imx_kbd_noirq_resume) +}; static struct platform_driver imx_keypad_driver = { .driver = { -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Anson Huang <anson.huang@nxp.com> To: "dmitry.torokhov@gmail.com" <dmitry.torokhov@gmail.com>, "shawnguo@kernel.org" <shawnguo@kernel.org>, "s.hauer@pengutronix.de" <s.hauer@pengutronix.de>, "kernel@pengutronix.de" <kernel@pengutronix.de>, "festevam@gmail.com" <festevam@gmail.com>, "linux-input@vger.kernel.org" <linux-input@vger.kernel.org>, "linux-arm-kernel@lists.infradead.org" <linux-arm-kernel@lists.infradead.org>, "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org> Cc: dl-linux-imx <linux-imx@nxp.com> Subject: [PATCH 2/2] input: keyboard: imx: make sure keyboard can always wake up system Date: Fri, 29 Mar 2019 07:00:46 +0000 [thread overview] Message-ID: <1553842562-8481-2-git-send-email-Anson.Huang@nxp.com> (raw) In-Reply-To: <1553842562-8481-1-git-send-email-Anson.Huang@nxp.com> There are several scenarios that keyboard can NOT wake up system from suspend, e.g., if a keyboard is depressed between system device suspend phase and device noirq suspend phase, the keyboard ISR will be called and both keyboard depress and release interrupts will be disabled, then keyboard will no longer be able to wake up system. Another scenario would be, if a keyboard is kept depressed, and then system goes into suspend, the expected behavior would be when keyboard is released, system will be waked up, but current implementation can NOT achieve that, because both depress and release interrupts are disabled in ISR, and the event check is still in progress. To fix these issues, need to make sure keyboard's depress or release interrupt is enabled after noirq device suspend phase, this patch moves the suspend/resume callback to noirq suspend/resume phase, and enable the corresponding interrupt according to current keyboard status. Signed-off-by: Anson Huang <Anson.Huang@nxp.com> --- drivers/input/keyboard/imx_keypad.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 7e32c36..9ae2090 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -521,11 +521,12 @@ static int imx_keypad_probe(struct platform_device *pdev) return 0; } -static int __maybe_unused imx_kbd_suspend(struct device *dev) +static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx_keypad *kbd = platform_get_drvdata(pdev); struct input_dev *input_dev = kbd->input_dev; + unsigned short reg_val = readw(kbd->mmio_base + KPSR); /* imx kbd can wake up system even clock is disabled */ mutex_lock(&input_dev->mutex); @@ -535,13 +536,20 @@ static int __maybe_unused imx_kbd_suspend(struct device *dev) mutex_unlock(&input_dev->mutex); - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(&pdev->dev)) { + 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); + } return 0; } -static int __maybe_unused imx_kbd_resume(struct device *dev) +static int __maybe_unused imx_kbd_noirq_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx_keypad *kbd = platform_get_drvdata(pdev); @@ -565,7 +573,9 @@ static int __maybe_unused imx_kbd_resume(struct device *dev) return ret; } -static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); +static const struct dev_pm_ops imx_kbd_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_kbd_noirq_suspend, imx_kbd_noirq_resume) +}; static struct platform_driver imx_keypad_driver = { .driver = { -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-03-29 7:00 UTC|newest] Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-29 7:00 [PATCH 1/2] input: keyboard: imx: no need to control interrupt status in event check Anson Huang 2019-03-29 7:00 ` Anson Huang 2019-03-29 7:00 ` Anson Huang 2019-03-29 7:00 ` Anson Huang [this message] 2019-03-29 7:00 ` [PATCH 2/2] input: keyboard: imx: make sure keyboard can always wake up system Anson Huang 2019-03-29 7:00 ` Anson Huang 2019-04-03 21:48 ` [PATCH 1/2] input: keyboard: imx: no need to control interrupt status in event check dmitry.torokhov 2019-04-03 21:48 ` dmitry.torokhov 2019-04-03 21:48 ` dmitry.torokhov 2019-04-04 1:29 ` Anson Huang 2019-04-04 1:29 ` Anson Huang 2019-04-04 1:29 ` Anson Huang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1553842562-8481-2-git-send-email-Anson.Huang@nxp.com \ --to=anson.huang@nxp.com \ --cc=dmitry.torokhov@gmail.com \ --cc=festevam@gmail.com \ --cc=kernel@pengutronix.de \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-imx@nxp.com \ --cc=linux-input@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=s.hauer@pengutronix.de \ --cc=shawnguo@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.