From cbb37908effbe2fb3e3ee0fe6ba1fd0f7f47b359 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 29 Aug 2026 04:12:18 -0700 Subject: [PATCH] Input: st-keyscan - disable interrupt while clock is gated The driver gates off its peripheral clock when the input device is not open and during system suspend without wakeup. However, the interrupt is requested without IRQF_NO_AUTOEN and remains unmasked when the device is stopped. If a pending or spurious interrupt fires while the clock is disabled, keyscan_isr() will attempt to read the matrix state register with the clock gated off, triggering a bus fault (synchronous external abort) and panicking the system. Request the interrupt with IRQF_NO_AUTOEN, enable it in keyscan_start(), and disable it in keyscan_stop() prior to gating the clock. Drop the pointless clock enable/stop sequence in keyscan_probe(), leaving the clock gated and hardware untouched until the device is opened. Fixes: 062589b13991 ("Input: add st-keyscan driver") Reported-by: sashiko-bot@kernel.org Assisted-by: LLM Link: https://patch.msgid.link/apK-PZ5c97mCxBSC@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/st-keyscan.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c index ca177a708e55..2fbdf373fe99 100644 --- a/drivers/input/keyboard/st-keyscan.c +++ b/drivers/input/keyboard/st-keyscan.c @@ -75,6 +75,8 @@ static int keyscan_start(struct st_keyscan *keypad) writel(KEYSCAN_CONFIG_ENABLE, keypad->base + KEYSCAN_CONFIG_OFF); + enable_irq(keypad->irq); + return 0; } @@ -82,6 +84,8 @@ static void keyscan_stop(struct st_keyscan *keypad) { writel(0, keypad->base + KEYSCAN_CONFIG_OFF); + disable_irq(keypad->irq); + clk_disable(keypad->clk); } @@ -176,20 +180,12 @@ static int keyscan_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(keypad_data->clk), "cannot get clock\n"); - error = clk_enable(keypad_data->clk); - if (error) { - dev_err(&pdev->dev, "failed to enable clock\n"); - return error; - } - - keyscan_stop(keypad_data); - keypad_data->irq = platform_get_irq(pdev, 0); if (keypad_data->irq < 0) return keypad_data->irq; - error = devm_request_irq(&pdev->dev, keypad_data->irq, keyscan_isr, 0, - pdev->name, keypad_data); + error = devm_request_irq(&pdev->dev, keypad_data->irq, keyscan_isr, + IRQF_NO_AUTOEN, pdev->name, keypad_data); if (error) return error;