Commit 2f99ffd8 authored by Jacky Bai's avatar Jacky Bai Committed by Dmitry Torokhov
Browse files

Input: bbnsm_pwrkey - fix missed key press after suspend



Report input event directly on wakeup to ensure no press event is missed
when resuming from suspend.

Signed-off-by: default avatarJacky Bai <ping.bai@nxp.com>
Reviewed-by: default avatarPeng Fan <peng.fan@nxp.com>
Acked-by: default avatarJason Liu <jason.hui.liu@nxp.com>
Signed-off-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240716000721.3485597-1-Frank.Li@nxp.com


Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 5d33d04e
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ struct bbnsm_pwrkey {
	int irq;
	int keycode;
	int keystate;  /* 1:pressed */
	bool suspended;
	struct timer_list check_timer;
	struct input_dev *input;
};
@@ -70,6 +71,7 @@ static irqreturn_t bbnsm_pwrkey_interrupt(int irq, void *dev_id)
{
	struct platform_device *pdev = dev_id;
	struct bbnsm_pwrkey *bbnsm = platform_get_drvdata(pdev);
	struct input_dev *input = bbnsm->input;
	u32 event;

	regmap_read(bbnsm->regmap, BBNSM_EVENTS, &event);
@@ -78,6 +80,18 @@ static irqreturn_t bbnsm_pwrkey_interrupt(int irq, void *dev_id)

	pm_wakeup_event(bbnsm->input->dev.parent, 0);

	/*
	 * Directly report key event after resume to make sure key press
	 * event is never missed.
	 */
	if (bbnsm->suspended) {
		bbnsm->keystate = 1;
		input_event(input, EV_KEY, bbnsm->keycode, 1);
		input_sync(input);
		/* Fire at most once per suspend/resume cycle */
		bbnsm->suspended = false;
	}

	mod_timer(&bbnsm->check_timer,
		   jiffies + msecs_to_jiffies(DEBOUNCE_TIME));

@@ -173,6 +187,29 @@ static int bbnsm_pwrkey_probe(struct platform_device *pdev)
	return 0;
}

static int __maybe_unused bbnsm_pwrkey_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct bbnsm_pwrkey *bbnsm = platform_get_drvdata(pdev);

	bbnsm->suspended = true;

	return 0;
}

static int __maybe_unused bbnsm_pwrkey_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct bbnsm_pwrkey *bbnsm = platform_get_drvdata(pdev);

	bbnsm->suspended = false;

	return 0;
}

static SIMPLE_DEV_PM_OPS(bbnsm_pwrkey_pm_ops, bbnsm_pwrkey_suspend,
		bbnsm_pwrkey_resume);

static const struct of_device_id bbnsm_pwrkey_ids[] = {
	{ .compatible = "nxp,imx93-bbnsm-pwrkey" },
	{ /* sentinel */ }
@@ -182,6 +219,7 @@ MODULE_DEVICE_TABLE(of, bbnsm_pwrkey_ids);
static struct platform_driver bbnsm_pwrkey_driver = {
	.driver = {
		.name = "bbnsm_pwrkey",
		.pm = &bbnsm_pwrkey_pm_ops,
		.of_match_table = bbnsm_pwrkey_ids,
	},
	.probe = bbnsm_pwrkey_probe,