* FAILED: patch "[PATCH] Revert "Input: matrix_keypad - force switch rows to input mode"" failed to apply to 6.6-stable tree
@ 2026-11-07 10:36 Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
0 siblings, 1 reply; 7+ messages in thread
From: Sasha Levin @ 2026-11-07 10:36 UTC (permalink / raw)
To: al.kochet, lis8215, paul, dmitry.torokhov; +Cc: stable
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 1527451f87dfe368b8ddeeb501c24ac9bde6b589
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '20261107053642-failed-6.6-1527451f87df@kernel.org' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From 1527451f87dfe368b8ddeeb501c24ac9bde6b589 Mon Sep 17 00:00:00 2001
From: Alexander Kochetkov <al.kochet@gmail.com>
Date: Fri, 2 Oct 2026 13:09:35 +0300
Subject: [PATCH] Revert "Input: matrix_keypad - force switch rows to input
mode"
This reverts commit 01c84b03d80aab9f04c4e3e1f9085f4202ff7c29.
The commit makes every scan call gpiod_direction_input() on the row
GPIOs. On pin controllers where GPIO input and interrupt are separate
pinmux functions this switches the row pins out of interrupt mode, and
enable_row_irqs() does not switch them back: it only unmasks the
interrupts. Row interrupts then never arrive and the keypad stops
working. Seen with a matrix keypad on an Allwinner A64 board (PINE
A64-LTS); it works again with the commit reverted.
The workaround is not needed on Ingenic either: the author of the
reverted commit re-tested all available JZ47xx SoCs and they all report
the live pin state in interrupt mode, see the thread in Link.
Fixes: 01c84b03d80a ("Input: matrix_keypad - force switch rows to input mode")
Link: https://lore.kernel.org/all/4130C026-2A83-408B-836A-ECA044491C47@gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
Acked-by: Siarhei Volkau <lis8215@gmail.com>
Acked-by: Paul Cercueil <paul@crapouillou.net>
Link: https://patch.msgid.link/20261002100935.449473-1-al.kochet@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/keyboard/matrix_keypad.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 14a13abf32720..d14d1d7274870 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -134,9 +134,6 @@ static void matrix_keypad_scan(struct work_struct *work)
memset(new_state, 0, sizeof(new_state));
- for (row = 0; row < keypad->num_row_gpios; row++)
- gpiod_direction_input(keypad->row_gpios[row]);
-
/* assert each column and read the row status out */
for (col = 0; col < keypad->num_col_gpios; col++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void
2026-11-07 10:36 FAILED: patch "[PATCH] Revert "Input: matrix_keypad - force switch rows to input mode"" failed to apply to 6.6-stable tree Sasha Levin
@ 2026-11-11 2:03 ` Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 2/6] Input: matrix_keypad - avoid repeatedly converting GPIO to IRQ Sasha Levin
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Sasha Levin @ 2026-11-11 2:03 UTC (permalink / raw)
To: stable; +Cc: Uwe Kleine-König, Dmitry Torokhov, Sasha Levin
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit af90388a598d39584283c18e4047124fee8f1801 ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new() which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20230920125829.1478827-6-u.kleine-koenig@pengutronix.de
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Stable-dep-of: 1527451f87df ("Revert "Input: matrix_keypad - force switch rows to input mode"")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/matrix_keypad.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index a1b037891af25..50fa764c82d2b 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -549,15 +549,13 @@ static int matrix_keypad_probe(struct platform_device *pdev)
return err;
}
-static int matrix_keypad_remove(struct platform_device *pdev)
+static void matrix_keypad_remove(struct platform_device *pdev)
{
struct matrix_keypad *keypad = platform_get_drvdata(pdev);
matrix_keypad_free_gpio(keypad);
input_unregister_device(keypad->input_dev);
kfree(keypad);
-
- return 0;
}
#ifdef CONFIG_OF
@@ -570,7 +568,7 @@ MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match);
static struct platform_driver matrix_keypad_driver = {
.probe = matrix_keypad_probe,
- .remove = matrix_keypad_remove,
+ .remove_new = matrix_keypad_remove,
.driver = {
.name = "matrix-keypad",
.pm = pm_sleep_ptr(&matrix_keypad_pm_ops),
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 2/6] Input: matrix_keypad - avoid repeatedly converting GPIO to IRQ
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
@ 2026-11-11 2:03 ` Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 3/6] Input: matrix_keypad - consolidate handling of clustered interrupt Sasha Levin
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2026-11-11 2:03 UTC (permalink / raw)
To: stable; +Cc: Dmitry Torokhov, Sasha Levin
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ Upstream commit a96fb711c6be76bcfbcf594a865002fa7c0eb525 ]
There is no need to do conversion from GPIOs to interrupt numbers.
Convert row GPIOs to interrupt numbers once in probe() and use
this information when the driver needs to enable or disable given
interrupt line.
Link: https://lore.kernel.org/r/20240121053232.276968-1-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Stable-dep-of: 1527451f87df ("Revert "Input: matrix_keypad - force switch rows to input mode"")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/matrix_keypad.c | 48 ++++++++++++++------------
1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 50fa764c82d2b..1cd1ffb80401a 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -27,6 +27,7 @@ struct matrix_keypad {
const struct matrix_keypad_platform_data *pdata;
struct input_dev *input_dev;
unsigned int row_shift;
+ unsigned int row_irqs[MATRIX_MAX_ROWS];
DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
@@ -92,7 +93,7 @@ static void enable_row_irqs(struct matrix_keypad *keypad)
enable_irq(pdata->clustered_irq);
else {
for (i = 0; i < pdata->num_row_gpios; i++)
- enable_irq(gpio_to_irq(pdata->row_gpios[i]));
+ enable_irq(keypad->row_irqs[i]);
}
}
@@ -105,7 +106,7 @@ static void disable_row_irqs(struct matrix_keypad *keypad)
disable_irq_nosync(pdata->clustered_irq);
else {
for (i = 0; i < pdata->num_row_gpios; i++)
- disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
+ disable_irq_nosync(keypad->row_irqs[i]);
}
}
@@ -233,7 +234,6 @@ static void matrix_keypad_stop(struct input_dev *dev)
static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
{
const struct matrix_keypad_platform_data *pdata = keypad->pdata;
- unsigned int gpio;
int i;
if (pdata->clustered_irq > 0) {
@@ -241,21 +241,16 @@ static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
keypad->gpio_all_disabled = true;
} else {
- for (i = 0; i < pdata->num_row_gpios; i++) {
- if (!test_bit(i, keypad->disabled_gpios)) {
- gpio = pdata->row_gpios[i];
-
- if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
+ for (i = 0; i < pdata->num_row_gpios; i++)
+ if (!test_bit(i, keypad->disabled_gpios))
+ if (enable_irq_wake(keypad->row_irqs[i]) == 0)
__set_bit(i, keypad->disabled_gpios);
- }
- }
}
}
static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
{
const struct matrix_keypad_platform_data *pdata = keypad->pdata;
- unsigned int gpio;
int i;
if (pdata->clustered_irq > 0) {
@@ -264,12 +259,9 @@ static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
keypad->gpio_all_disabled = false;
}
} else {
- for (i = 0; i < pdata->num_row_gpios; i++) {
- if (test_and_clear_bit(i, keypad->disabled_gpios)) {
- gpio = pdata->row_gpios[i];
- disable_irq_wake(gpio_to_irq(gpio));
- }
- }
+ for (i = 0; i < pdata->num_row_gpios; i++)
+ if (test_and_clear_bit(i, keypad->disabled_gpios))
+ disable_irq_wake(keypad->row_irqs[i]);
}
}
@@ -306,7 +298,7 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
struct matrix_keypad *keypad)
{
const struct matrix_keypad_platform_data *pdata = keypad->pdata;
- int i, err;
+ int i, irq, err;
/* initialized strobe lines as outputs, activated */
for (i = 0; i < pdata->num_col_gpios; i++) {
@@ -345,11 +337,19 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
}
} else {
for (i = 0; i < pdata->num_row_gpios; i++) {
- err = request_any_context_irq(
- gpio_to_irq(pdata->row_gpios[i]),
+ irq = gpio_to_irq(pdata->row_gpios[i]);
+ if (irq < 0) {
+ err = irq;
+ dev_err(&pdev->dev,
+ "Unable to convert GPIO line %i to irq: %d\n",
+ pdata->row_gpios[i], err);
+ goto err_free_irqs;
+ }
+
+ err = request_any_context_irq(irq,
matrix_keypad_interrupt,
IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
+ IRQF_TRIGGER_FALLING,
"matrix-keypad", keypad);
if (err < 0) {
dev_err(&pdev->dev,
@@ -357,6 +357,8 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
pdata->row_gpios[i]);
goto err_free_irqs;
}
+
+ keypad->row_irqs[i] = irq;
}
}
@@ -366,7 +368,7 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
err_free_irqs:
while (--i >= 0)
- free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
+ free_irq(keypad->row_irqs[i], keypad);
i = pdata->num_row_gpios;
err_free_rows:
while (--i >= 0)
@@ -388,7 +390,7 @@ static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
free_irq(pdata->clustered_irq, keypad);
} else {
for (i = 0; i < pdata->num_row_gpios; i++)
- free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
+ free_irq(keypad->row_irqs[i], keypad);
}
for (i = 0; i < pdata->num_row_gpios; i++)
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 3/6] Input: matrix_keypad - consolidate handling of clustered interrupt
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 2/6] Input: matrix_keypad - avoid repeatedly converting GPIO to IRQ Sasha Levin
@ 2026-11-11 2:03 ` Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 4/6] Input: matrix_keypad - switch to using managed resources Sasha Levin
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2026-11-11 2:03 UTC (permalink / raw)
To: stable; +Cc: Dmitry Torokhov, Sasha Levin
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ Upstream commit 8cf4b3683a713a4b54d44565e8a32b4cca357084 ]
Now that the driver stores interrupt numbers corresponding to individual
GPIOs in non-clustered mode, it is possible to unify handling of both
modes by storing clustered interrupt at position 0 and setting the
number of interrupts in this case to 1.
Link: https://lore.kernel.org/r/20240121053232.276968-2-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Stable-dep-of: 1527451f87df ("Revert "Input: matrix_keypad - force switch rows to input mode"")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/matrix_keypad.c | 63 ++++++++------------------
1 file changed, 20 insertions(+), 43 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 1cd1ffb80401a..44ef600b8f191 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -27,9 +27,10 @@ struct matrix_keypad {
const struct matrix_keypad_platform_data *pdata;
struct input_dev *input_dev;
unsigned int row_shift;
- unsigned int row_irqs[MATRIX_MAX_ROWS];
- DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
+ unsigned int row_irqs[MATRIX_MAX_ROWS];
+ unsigned int num_row_irqs;
+ DECLARE_BITMAP(wakeup_enabled_irqs, MATRIX_MAX_ROWS);
uint32_t last_key_state[MATRIX_MAX_COLS];
struct delayed_work work;
@@ -86,28 +87,18 @@ static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
static void enable_row_irqs(struct matrix_keypad *keypad)
{
- const struct matrix_keypad_platform_data *pdata = keypad->pdata;
int i;
- if (pdata->clustered_irq > 0)
- enable_irq(pdata->clustered_irq);
- else {
- for (i = 0; i < pdata->num_row_gpios; i++)
- enable_irq(keypad->row_irqs[i]);
- }
+ for (i = 0; i < keypad->num_row_irqs; i++)
+ enable_irq(keypad->row_irqs[i]);
}
static void disable_row_irqs(struct matrix_keypad *keypad)
{
- const struct matrix_keypad_platform_data *pdata = keypad->pdata;
int i;
- if (pdata->clustered_irq > 0)
- disable_irq_nosync(pdata->clustered_irq);
- else {
- for (i = 0; i < pdata->num_row_gpios; i++)
- disable_irq_nosync(keypad->row_irqs[i]);
- }
+ for (i = 0; i < keypad->num_row_irqs; i++)
+ disable_irq_nosync(keypad->row_irqs[i]);
}
/*
@@ -233,35 +224,20 @@ static void matrix_keypad_stop(struct input_dev *dev)
static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
{
- const struct matrix_keypad_platform_data *pdata = keypad->pdata;
int i;
- if (pdata->clustered_irq > 0) {
- if (enable_irq_wake(pdata->clustered_irq) == 0)
- keypad->gpio_all_disabled = true;
- } else {
-
- for (i = 0; i < pdata->num_row_gpios; i++)
- if (!test_bit(i, keypad->disabled_gpios))
- if (enable_irq_wake(keypad->row_irqs[i]) == 0)
- __set_bit(i, keypad->disabled_gpios);
- }
+ for_each_clear_bit(i, keypad->wakeup_enabled_irqs, keypad->num_row_irqs)
+ if (enable_irq_wake(keypad->row_irqs[i]) == 0)
+ __set_bit(i, keypad->wakeup_enabled_irqs);
}
static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
{
- const struct matrix_keypad_platform_data *pdata = keypad->pdata;
int i;
- if (pdata->clustered_irq > 0) {
- if (keypad->gpio_all_disabled) {
- disable_irq_wake(pdata->clustered_irq);
- keypad->gpio_all_disabled = false;
- }
- } else {
- for (i = 0; i < pdata->num_row_gpios; i++)
- if (test_and_clear_bit(i, keypad->disabled_gpios))
- disable_irq_wake(keypad->row_irqs[i]);
+ for_each_set_bit(i, keypad->wakeup_enabled_irqs, keypad->num_row_irqs) {
+ disable_irq_wake(keypad->row_irqs[i]);
+ __clear_bit(i, keypad->wakeup_enabled_irqs);
}
}
@@ -335,6 +311,9 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
"Unable to acquire clustered interrupt\n");
goto err_free_rows;
}
+
+ keypad->row_irqs[0] = pdata->clustered_irq;
+ keypad->num_row_irqs = 1;
} else {
for (i = 0; i < pdata->num_row_gpios; i++) {
irq = gpio_to_irq(pdata->row_gpios[i]);
@@ -360,6 +339,8 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
keypad->row_irqs[i] = irq;
}
+
+ keypad->num_row_irqs = pdata->num_row_gpios;
}
/* initialized as disabled - enabled by input->open */
@@ -386,12 +367,8 @@ static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
const struct matrix_keypad_platform_data *pdata = keypad->pdata;
int i;
- if (pdata->clustered_irq > 0) {
- free_irq(pdata->clustered_irq, keypad);
- } else {
- for (i = 0; i < pdata->num_row_gpios; i++)
- free_irq(keypad->row_irqs[i], keypad);
- }
+ for (i = 0; i < keypad->num_row_irqs; i++)
+ free_irq(keypad->row_irqs[i], keypad);
for (i = 0; i < pdata->num_row_gpios; i++)
gpio_free(pdata->row_gpios[i]);
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 4/6] Input: matrix_keypad - switch to using managed resources
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 2/6] Input: matrix_keypad - avoid repeatedly converting GPIO to IRQ Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 3/6] Input: matrix_keypad - consolidate handling of clustered interrupt Sasha Levin
@ 2026-11-11 2:03 ` Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 5/6] Input: matrix_keypad - remove support for clustered interrupt Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 6/6] Revert "Input: matrix_keypad - force switch rows to input mode" Sasha Levin
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2026-11-11 2:03 UTC (permalink / raw)
To: stable; +Cc: Dmitry Torokhov, Sasha Levin
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ Upstream commit 7d0f351da46098b3bbb147f886f059473b84ff48 ]
Switch the drivers to use managed resources (devm) to simplify error
handling and remove the need to have remove() implementation.
Link: https://lore.kernel.org/r/20240121053232.276968-3-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Stable-dep-of: 1527451f87df ("Revert "Input: matrix_keypad - force switch rows to input mode"")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/matrix_keypad.c | 89 +++++++-------------------
1 file changed, 24 insertions(+), 65 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 44ef600b8f191..695c03e075b56 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -278,38 +278,41 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
/* initialized strobe lines as outputs, activated */
for (i = 0; i < pdata->num_col_gpios; i++) {
- err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col");
+ err = devm_gpio_request(&pdev->dev,
+ pdata->col_gpios[i], "matrix_kbd_col");
if (err) {
dev_err(&pdev->dev,
"failed to request GPIO%d for COL%d\n",
pdata->col_gpios[i], i);
- goto err_free_cols;
+ return err;
}
gpio_direction_output(pdata->col_gpios[i], !pdata->active_low);
}
for (i = 0; i < pdata->num_row_gpios; i++) {
- err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row");
+ err = devm_gpio_request(&pdev->dev,
+ pdata->row_gpios[i], "matrix_kbd_row");
if (err) {
dev_err(&pdev->dev,
"failed to request GPIO%d for ROW%d\n",
pdata->row_gpios[i], i);
- goto err_free_rows;
+ return err;
}
gpio_direction_input(pdata->row_gpios[i]);
}
if (pdata->clustered_irq > 0) {
- err = request_any_context_irq(pdata->clustered_irq,
+ err = devm_request_any_context_irq(&pdev->dev,
+ pdata->clustered_irq,
matrix_keypad_interrupt,
pdata->clustered_irq_flags,
"matrix-keypad", keypad);
if (err < 0) {
dev_err(&pdev->dev,
"Unable to acquire clustered interrupt\n");
- goto err_free_rows;
+ return err;
}
keypad->row_irqs[0] = pdata->clustered_irq;
@@ -322,10 +325,11 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
dev_err(&pdev->dev,
"Unable to convert GPIO line %i to irq: %d\n",
pdata->row_gpios[i], err);
- goto err_free_irqs;
+ return err;
}
- err = request_any_context_irq(irq,
+ err = devm_request_any_context_irq(&pdev->dev,
+ irq,
matrix_keypad_interrupt,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
@@ -334,7 +338,7 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
dev_err(&pdev->dev,
"Unable to acquire interrupt for GPIO line %i\n",
pdata->row_gpios[i]);
- goto err_free_irqs;
+ return err;
}
keypad->row_irqs[i] = irq;
@@ -345,36 +349,8 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
/* initialized as disabled - enabled by input->open */
disable_row_irqs(keypad);
- return 0;
-
-err_free_irqs:
- while (--i >= 0)
- free_irq(keypad->row_irqs[i], keypad);
- i = pdata->num_row_gpios;
-err_free_rows:
- while (--i >= 0)
- gpio_free(pdata->row_gpios[i]);
- i = pdata->num_col_gpios;
-err_free_cols:
- while (--i >= 0)
- gpio_free(pdata->col_gpios[i]);
-
- return err;
-}
-
-static void matrix_keypad_free_gpio(struct matrix_keypad *keypad)
-{
- const struct matrix_keypad_platform_data *pdata = keypad->pdata;
- int i;
-
- for (i = 0; i < keypad->num_row_irqs; i++)
- free_irq(keypad->row_irqs[i], keypad);
-
- for (i = 0; i < pdata->num_row_gpios; i++)
- gpio_free(pdata->row_gpios[i]);
- for (i = 0; i < pdata->num_col_gpios; i++)
- gpio_free(pdata->col_gpios[i]);
+ return 0;
}
#ifdef CONFIG_OF
@@ -473,12 +449,13 @@ static int matrix_keypad_probe(struct platform_device *pdev)
return -EINVAL;
}
- keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!keypad || !input_dev) {
- err = -ENOMEM;
- goto err_free_mem;
- }
+ keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+ if (!keypad)
+ return -ENOMEM;
+
+ input_dev = devm_input_allocate_device(&pdev->dev);
+ if (!input_dev)
+ return -ENOMEM;
keypad->input_dev = input_dev;
keypad->pdata = pdata;
@@ -489,7 +466,6 @@ static int matrix_keypad_probe(struct platform_device *pdev)
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
- input_dev->dev.parent = &pdev->dev;
input_dev->open = matrix_keypad_start;
input_dev->close = matrix_keypad_stop;
@@ -499,7 +475,7 @@ static int matrix_keypad_probe(struct platform_device *pdev)
NULL, input_dev);
if (err) {
dev_err(&pdev->dev, "failed to build keymap\n");
- goto err_free_mem;
+ return -ENOMEM;
}
if (!pdata->no_autorepeat)
@@ -509,32 +485,16 @@ static int matrix_keypad_probe(struct platform_device *pdev)
err = matrix_keypad_init_gpio(pdev, keypad);
if (err)
- goto err_free_mem;
+ return err;
err = input_register_device(keypad->input_dev);
if (err)
- goto err_free_gpio;
+ return err;
device_init_wakeup(&pdev->dev, pdata->wakeup);
platform_set_drvdata(pdev, keypad);
return 0;
-
-err_free_gpio:
- matrix_keypad_free_gpio(keypad);
-err_free_mem:
- input_free_device(input_dev);
- kfree(keypad);
- return err;
-}
-
-static void matrix_keypad_remove(struct platform_device *pdev)
-{
- struct matrix_keypad *keypad = platform_get_drvdata(pdev);
-
- matrix_keypad_free_gpio(keypad);
- input_unregister_device(keypad->input_dev);
- kfree(keypad);
}
#ifdef CONFIG_OF
@@ -547,7 +507,6 @@ MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match);
static struct platform_driver matrix_keypad_driver = {
.probe = matrix_keypad_probe,
- .remove_new = matrix_keypad_remove,
.driver = {
.name = "matrix-keypad",
.pm = pm_sleep_ptr(&matrix_keypad_pm_ops),
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 5/6] Input: matrix_keypad - remove support for clustered interrupt
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
` (2 preceding siblings ...)
2026-11-11 2:03 ` [PATCH 6.6.y 4/6] Input: matrix_keypad - switch to using managed resources Sasha Levin
@ 2026-11-11 2:03 ` Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 6/6] Revert "Input: matrix_keypad - force switch rows to input mode" Sasha Levin
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2026-11-11 2:03 UTC (permalink / raw)
To: stable; +Cc: Dmitry Torokhov, Arnd Bergmann, Linus Walleij, Sasha Levin
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ Upstream commit 5080f62adb126e28d316298505272efea0aed81a ]
There are no users of this functionality in the mainline kernel (it was
only available to boards using platform data and not device tree).
Remove it to simplify the code.
Acked-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20240805014710.1961677-2-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Stable-dep-of: 1527451f87df ("Revert "Input: matrix_keypad - force switch rows to input mode"")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/matrix_keypad.c | 61 ++++++++++----------------
1 file changed, 22 insertions(+), 39 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 695c03e075b56..9e6837217f441 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -29,7 +29,6 @@ struct matrix_keypad {
unsigned int row_shift;
unsigned int row_irqs[MATRIX_MAX_ROWS];
- unsigned int num_row_irqs;
DECLARE_BITMAP(wakeup_enabled_irqs, MATRIX_MAX_ROWS);
uint32_t last_key_state[MATRIX_MAX_COLS];
@@ -89,7 +88,7 @@ static void enable_row_irqs(struct matrix_keypad *keypad)
{
int i;
- for (i = 0; i < keypad->num_row_irqs; i++)
+ for (i = 0; i < keypad->pdata->num_row_gpios; i++)
enable_irq(keypad->row_irqs[i]);
}
@@ -97,7 +96,7 @@ static void disable_row_irqs(struct matrix_keypad *keypad)
{
int i;
- for (i = 0; i < keypad->num_row_irqs; i++)
+ for (i = 0; i < keypad->pdata->num_row_gpios; i++)
disable_irq_nosync(keypad->row_irqs[i]);
}
@@ -226,7 +225,8 @@ static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
{
int i;
- for_each_clear_bit(i, keypad->wakeup_enabled_irqs, keypad->num_row_irqs)
+ for_each_clear_bit(i, keypad->wakeup_enabled_irqs,
+ keypad->pdata->num_row_gpios)
if (enable_irq_wake(keypad->row_irqs[i]) == 0)
__set_bit(i, keypad->wakeup_enabled_irqs);
}
@@ -235,7 +235,8 @@ static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
{
int i;
- for_each_set_bit(i, keypad->wakeup_enabled_irqs, keypad->num_row_irqs) {
+ for_each_set_bit(i, keypad->wakeup_enabled_irqs,
+ keypad->pdata->num_row_gpios) {
disable_irq_wake(keypad->row_irqs[i]);
__clear_bit(i, keypad->wakeup_enabled_irqs);
}
@@ -303,48 +304,30 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
gpio_direction_input(pdata->row_gpios[i]);
}
- if (pdata->clustered_irq > 0) {
+ for (i = 0; i < pdata->num_row_gpios; i++) {
+ irq = gpio_to_irq(pdata->row_gpios[i]);
+ if (irq < 0) {
+ err = irq;
+ dev_err(&pdev->dev,
+ "Unable to convert GPIO line %i to irq: %d\n",
+ pdata->row_gpios[i], err);
+ return err;
+ }
+
err = devm_request_any_context_irq(&pdev->dev,
- pdata->clustered_irq,
+ irq,
matrix_keypad_interrupt,
- pdata->clustered_irq_flags,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
"matrix-keypad", keypad);
if (err < 0) {
dev_err(&pdev->dev,
- "Unable to acquire clustered interrupt\n");
+ "Unable to acquire interrupt for GPIO line %i\n",
+ pdata->row_gpios[i]);
return err;
}
- keypad->row_irqs[0] = pdata->clustered_irq;
- keypad->num_row_irqs = 1;
- } else {
- for (i = 0; i < pdata->num_row_gpios; i++) {
- irq = gpio_to_irq(pdata->row_gpios[i]);
- if (irq < 0) {
- err = irq;
- dev_err(&pdev->dev,
- "Unable to convert GPIO line %i to irq: %d\n",
- pdata->row_gpios[i], err);
- return err;
- }
-
- err = devm_request_any_context_irq(&pdev->dev,
- irq,
- matrix_keypad_interrupt,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
- "matrix-keypad", keypad);
- if (err < 0) {
- dev_err(&pdev->dev,
- "Unable to acquire interrupt for GPIO line %i\n",
- pdata->row_gpios[i]);
- return err;
- }
-
- keypad->row_irqs[i] = irq;
- }
-
- keypad->num_row_irqs = pdata->num_row_gpios;
+ keypad->row_irqs[i] = irq;
}
/* initialized as disabled - enabled by input->open */
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 6/6] Revert "Input: matrix_keypad - force switch rows to input mode"
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
` (3 preceding siblings ...)
2026-11-11 2:03 ` [PATCH 6.6.y 5/6] Input: matrix_keypad - remove support for clustered interrupt Sasha Levin
@ 2026-11-11 2:03 ` Sasha Levin
4 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2026-11-11 2:03 UTC (permalink / raw)
To: stable
Cc: Alexander Kochetkov, Siarhei Volkau, Paul Cercueil,
Dmitry Torokhov, Sasha Levin
From: Alexander Kochetkov <al.kochet@gmail.com>
[ Upstream commit 1527451f87dfe368b8ddeeb501c24ac9bde6b589 ]
This reverts commit 01c84b03d80aab9f04c4e3e1f9085f4202ff7c29.
The commit makes every scan call gpiod_direction_input() on the row
GPIOs. On pin controllers where GPIO input and interrupt are separate
pinmux functions this switches the row pins out of interrupt mode, and
enable_row_irqs() does not switch them back: it only unmasks the
interrupts. Row interrupts then never arrive and the keypad stops
working. Seen with a matrix keypad on an Allwinner A64 board (PINE
A64-LTS); it works again with the commit reverted.
The workaround is not needed on Ingenic either: the author of the
reverted commit re-tested all available JZ47xx SoCs and they all report
the live pin state in interrupt mode, see the thread in Link.
Fixes: 01c84b03d80a ("Input: matrix_keypad - force switch rows to input mode")
Link: https://lore.kernel.org/all/4130C026-2A83-408B-836A-ECA044491C47@gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
Acked-by: Siarhei Volkau <lis8215@gmail.com>
Acked-by: Paul Cercueil <paul@crapouillou.net>
Link: https://patch.msgid.link/20261002100935.449473-1-al.kochet@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ sashal: Adapted the loop removal from gpiod_direction_input() with keypad fields to gpio_direction_input() with pdata fields. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/keyboard/matrix_keypad.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 9e6837217f441..d0787a568058d 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -118,9 +118,6 @@ static void matrix_keypad_scan(struct work_struct *work)
memset(new_state, 0, sizeof(new_state));
- for (row = 0; row < pdata->num_row_gpios; row++)
- gpio_direction_input(pdata->row_gpios[row]);
-
/* assert each column and read the row status out */
for (col = 0; col < pdata->num_col_gpios; col++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-11 2:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-07 10:36 FAILED: patch "[PATCH] Revert "Input: matrix_keypad - force switch rows to input mode"" failed to apply to 6.6-stable tree Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 1/6] Input: matrix_keypad - convert to platform remove callback returning void Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 2/6] Input: matrix_keypad - avoid repeatedly converting GPIO to IRQ Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 3/6] Input: matrix_keypad - consolidate handling of clustered interrupt Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 4/6] Input: matrix_keypad - switch to using managed resources Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 5/6] Input: matrix_keypad - remove support for clustered interrupt Sasha Levin
2026-11-11 2:03 ` [PATCH 6.6.y 6/6] Revert "Input: matrix_keypad - force switch rows to input mode" Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox