* Re: [PATCH v4 03/11] HID: spi-hid: add transport driver skeleton for HID over SPI bus
From: Jingyuan Liang @ 2026-06-24 22:41 UTC (permalink / raw)
To: sashiko-reviews; +Cc: robh, conor+dt, devicetree, dmitry.torokhov, linux-input
In-Reply-To: <20260609045604.44FE71F00893@smtp.kernel.org>
On Mon, Jun 8, 2026 at 9:56 PM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Embedded arrays `read_approval_header` and `read_approval_body` are used for SPI DMA transfers without cacheline alignment, risking memory corruption.
> - [Medium] Unchecked return values of reset operations in `spi_hid_dev_init` and `spi_hid_resume`
> --
>
> commit ea35a3a23739acaca367a8d250ef25c96d22df36
> Author: Angela Czubak <acz@semihalf.com>
>
> HID: spi-hid: add transport driver skeleton for HID over SPI bus
>
> Create spi-hid folder and add Kconfig and Makefile for spi-hid driver.
> Add basic device structure, definitions, and probe/remove functions.
>
> > diff --git a/drivers/hid/spi-hid/spi-hid-core.c b/drivers/hid/spi-hid/spi-hid-core.c
> > new file mode 100644
> > index 0000000000000..02a7608c4b882
> > --- /dev/null
> > +++ b/drivers/hid/spi-hid/spi-hid-core.c
> > @@ -0,0 +1,213 @@
>
> [ ... ]
>
> > +/* Driver context */
> > +struct spi_hid {
> > + struct spi_device *spi; /* spi device. */
> > + struct hid_device *hid; /* pointer to corresponding HID dev. */
> > +
> > + struct spihid_ops *ops;
> > + struct spi_hid_conf *conf;
> > +
> > + enum hidspi_power_state power_state;
> > +
> > + u32 regulator_error_count;
> > + int regulator_last_error;
> > + u32 bus_error_count;
> > + int bus_last_error;
> > + u32 dir_count; /* device initiated reset count. */
> > +};
>
> [Severity: High]
> Does embedding the read_approval_header and read_approval_body arrays directly
> in this struct for SPI DMA transfers risk memory corruption?
>
> When these buffers are passed as tx_buf to spi_sync() (e.g. in
> spi_hid_input_sync()), they lack the ____cacheline_aligned directive. On
> architectures with non-coherent DMA, cache maintenance operations could
> encompass adjacent struct members.
>
> Concurrent CPU writes to those adjacent members during the DMA mapping window
> will be destroyed, leading to memory corruption.
>
> Should these buffers be cacheline aligned, or dynamically allocated?
read_approval_header and read_approval_body arrays are not in this patch.
>
> [ ... ]
>
> > +int spi_hid_core_probe(struct spi_device *spi, struct spihid_ops *ops,
> > + struct spi_hid_conf *conf)
> > +{
>
> [ ... ]
>
> > + /*
> > + * At the end of probe we initialize the device:
> > + * 0) assert reset, bias the interrupt line
> > + * 1) sleep minimal reset delay
> > + * 2) request IRQ
> > + * 3) power up the device
> > + * 4) deassert reset (high)
> > + * After this we expect an IRQ with a reset response.
> > + */
> > +
> > + shid->ops->assert_reset(shid->ops);
> > +
> > + shid->ops->sleep_minimal_reset_delay(shid->ops);
>
> [ ... ]
>
> > + error = shid->ops->power_up(shid->ops);
> > + if (error) {
> > + dev_err(dev, "%s: could not power up\n", __func__);
> > + return error;
> > + }
> > +
> > + shid->ops->deassert_reset(shid->ops);
>
> [Severity: Medium]
> Can hardware reset failures be masked here?
>
> The assert_reset and deassert_reset callbacks return integer error codes.
> However, their return values are ignored in spi_hid_core_probe() (as well as
> resume paths).
>
> If deassert_reset() fails, the device may remain in reset, causing the driver
> to hang waiting for a reset response IRQ that will never arrive.
>
> Should these return values be checked and handled?
>
> > +
> > + dev_dbg(dev, "%s: d3 -> %s\n", __func__,
> > + spi_hid_power_mode_string(shid->power_state));
> > +
> > + return 0;
> > +}
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260609-send-upstream-v4-0-b843d5e6ced3@chromium.org?part=3
^ permalink raw reply
* Re: [git pull] Input updates for v7.2-rc0
From: pr-tracker-bot @ 2026-06-24 22:16 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Linus Torvalds, linux-kernel, linux-input
In-Reply-To: <ajs_Hmo3Zo4aEFZ7@google.com>
The pull request you sent on Tue, 23 Jun 2026 19:21:25 -0700:
> git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v7.2-rc0
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e1611017870fa1582b5ff9ec0edc09542318daa6
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH v2] HID: multitouch: Fix stale MT slots when contact count drops to zero
From: Dave Carey @ 2026-06-24 19:19 UTC (permalink / raw)
To: linux-input; +Cc: jikos, benjamin.tissoires, Dave Carey
In-Reply-To: <20260522111527.69428-1-carvsdriver@gmail.com>
Gentle ping on this one — it's been about five weeks since the v2
submission with no feedback.
For context: the INPUT_PROP_BUTTONPAD misclassification fix for the same
device (hid-multitouch) was merged to mainline 2026-05-28, and the ghost
contacts fix (MT_QUIRK_CONTACT_CNT_ACCURATE) was applied to hid/for-next
2026-06-10 by Jiri. This stale-slots fix is the remaining hid-multitouch
patch for the Yoga Book 9 14IAH10.
Happy to rebase, respin, or address any concerns.
Thanks,
Dave
^ permalink raw reply
* [PATCH v6] HID: i2c-hid: Refactor _DSM helper and add i2c-hid-acpi-prp0001 driver
From: 谢致邦 (XIE Zhibang) @ 2026-06-24 17:46 UTC (permalink / raw)
To: linux-input, hansg, dmitry.torokhov, bentiss, yeking
Cc: dianders, jikos, linux-kernel, sashiko-bot, sashiko-reviews,
superm1, 谢致邦 (XIE Zhibang)
In-Reply-To: <tencent_8AE8ED913FEC8151B4BA3D85D6BB7F3ACF08@qq.com>
Move the _DSM call that gets the HID descriptor address from
i2c-hid-acpi.c into i2c-hid-acpi.h as a static inline so both the ACPI
and the new PRP0001 driver can use it. While refactoring, move the
blacklist check and the _DSM call to the top of probe() to avoid a
pointless alloc when the device is blacklisted or does not implement the
_DSM.
Some devices, for example the Lenovo KaiTian N60d and Inspur CP300L3,
are declared with _HID "PRP0001" and _DSD compatible "hid-over-i2c" but
lack "hid-descr-addr" from the _DSD and provide the HID descriptor
address only through an ACPI _DSM. The OF driver fails to probe them
because it requires hid-descr-addr. Add a new driver that handles these
devices by calling the shared _DSM helper.
Fixes: b33752c30023 ("HID: i2c-hid: Reorganize so ACPI and OF are separate modules")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
---
v2: Name the unused parameter and document why
acpi_device_fix_up_power() is skipped.
v3: Add a dev_warn() asking users to contact vendors for firmware
updates, and use existing locals in devm_kzalloc() and
acpi_device_fix_up_power().
v4: Double the power-up delay from 250ms to 500ms.
v5: Document why of_match_ptr() on the of_match_table is safe when
CONFIG_OF=n.
v6: Increase power-up delay from 500ms to 750ms. During cold boot on low
battery, 500ms causes non-fatal I2C transfer errors (-ENXIO). 750ms
fixes them.
drivers/hid/i2c-hid/Kconfig | 18 ++++
drivers/hid/i2c-hid/Makefile | 1 +
drivers/hid/i2c-hid/i2c-hid-acpi-prp0001.c | 104 +++++++++++++++++++++
drivers/hid/i2c-hid/i2c-hid-acpi.c | 52 +++--------
drivers/hid/i2c-hid/i2c-hid-acpi.h | 32 +++++++
5 files changed, 169 insertions(+), 38 deletions(-)
create mode 100644 drivers/hid/i2c-hid/i2c-hid-acpi-prp0001.c
create mode 100644 drivers/hid/i2c-hid/i2c-hid-acpi.h
diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
index e8d51f410cc1..7db8b2abff78 100644
--- a/drivers/hid/i2c-hid/Kconfig
+++ b/drivers/hid/i2c-hid/Kconfig
@@ -22,6 +22,24 @@ config I2C_HID_ACPI
will be called i2c-hid-acpi. It will also build/depend on the
module i2c-hid.
+config I2C_HID_ACPI_PRP0001
+ tristate "Driver for PRP0001 devices missing hid-descr-addr"
+ depends on ACPI
+ depends on DRM || !DRM
+ select I2C_HID_CORE
+ help
+ Say Y here if you want support for I2C HID touchpads that
+ are declared with _HID "PRP0001" and _DSD compatible
+ "hid-over-i2c" but lack the "hid-descr-addr" property from
+ the _DSD. The HID descriptor address is instead provided
+ through an ACPI _DSM. Known affected devices include the
+ Lenovo KaiTian N60d and Inspur CP300L3.
+
+ If unsure, say N.
+
+ This support is also available as a module. If so, the
+ module will be called i2c-hid-acpi-prp0001.
+
config I2C_HID_OF
tristate "HID over I2C transport layer Open Firmware driver"
# No "depends on OF" because this can also be used for manually
diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile
index 55bd5e0f35af..da420c1a8ec6 100644
--- a/drivers/hid/i2c-hid/Makefile
+++ b/drivers/hid/i2c-hid/Makefile
@@ -9,6 +9,7 @@ i2c-hid-objs = i2c-hid-core.o
i2c-hid-$(CONFIG_DMI) += i2c-hid-dmi-quirks.o
obj-$(CONFIG_I2C_HID_ACPI) += i2c-hid-acpi.o
+obj-$(CONFIG_I2C_HID_ACPI_PRP0001) += i2c-hid-acpi-prp0001.o
obj-$(CONFIG_I2C_HID_OF) += i2c-hid-of.o
obj-$(CONFIG_I2C_HID_OF_ELAN) += i2c-hid-of-elan.o
obj-$(CONFIG_I2C_HID_OF_GOODIX) += i2c-hid-of-goodix.o
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi-prp0001.c b/drivers/hid/i2c-hid/i2c-hid-acpi-prp0001.c
new file mode 100644
index 000000000000..d2cf4714ae7f
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi-prp0001.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * HID over I2C driver for PRP0001 devices missing hid-descr-addr
+ *
+ * Some devices, for example the Lenovo KaiTian N60d and Inspur CP300L3, use
+ * _HID "PRP0001" with _DSD compatible "hid-over-i2c" but lack "hid-descr-addr"
+ * from the _DSD. The HID descriptor address is provided only through an ACPI
+ * _DSM. The TPD0 node in the DSDT shows _DSM Function 1 returning 0x20.
+ *
+ * Copyright (C) 2026 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include "i2c-hid.h"
+#include "i2c-hid-acpi.h"
+
+static int i2c_hid_acpi_prp0001_power_up(struct i2chid_ops *ops)
+{
+ /* give the device time to power up */
+ msleep(750);
+ return 0;
+}
+
+static struct i2chid_ops i2c_hid_acpi_prp0001_ops = {
+ .power_up = i2c_hid_acpi_prp0001_power_up,
+ /*
+ * No .restore_sequence needed: the _DSM on these devices returns a
+ * constant (0x20) with no side effects, unlike some PNP0C50 _DSM
+ * implementations that switch the hardware between PS/2 and I2C modes.
+ */
+};
+
+static int i2c_hid_acpi_prp0001_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct acpi_device *adev;
+ u16 hid_descriptor_address;
+ int ret;
+
+ /* If hid-descr-addr is present, let i2c-hid-of handle it */
+ if (device_property_present(dev, "hid-descr-addr"))
+ return -ENODEV;
+
+ adev = ACPI_COMPANION(dev);
+ if (!adev)
+ return -ENODEV;
+
+ ret = i2c_hid_acpi_get_descriptor(adev);
+ if (ret < 0)
+ return ret;
+ dev_warn(dev,
+ "hid-descr-addr device property NOT found, using ACPI _DSM fallback. Contact vendor for firmware update!\n");
+ hid_descriptor_address = ret;
+
+ /*
+ * No acpi_device_fix_up_power() needed: TPD0 has no _PS0, _PS3, _PSC
+ * or _PRx methods and follows I2C bus power.
+ */
+ return i2c_hid_core_probe(client, &i2c_hid_acpi_prp0001_ops,
+ hid_descriptor_address, 0);
+}
+
+static const struct of_device_id i2c_hid_acpi_prp0001_of_match[] = {
+ { .compatible = "hid-over-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, i2c_hid_acpi_prp0001_of_match);
+
+static const struct i2c_device_id i2c_hid_acpi_prp0001_id[] = {
+ { .name = "hid-over-i2c" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, i2c_hid_acpi_prp0001_id);
+
+static struct i2c_driver i2c_hid_acpi_prp0001_driver = {
+ .driver = {
+ .name = "i2c_hid_acpi_prp0001",
+ .pm = &i2c_hid_core_pm,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ /*
+ * of_match_ptr() makes this NULL when CONFIG_OF=n, but that's
+ * fine: the I2C id_table with "hid-over-i2c" handles matching
+ * via client->name (set by acpi_set_modalias() from the _DSD
+ * compatible property).
+ */
+ .of_match_table = of_match_ptr(i2c_hid_acpi_prp0001_of_match),
+ },
+
+ .probe = i2c_hid_acpi_prp0001_probe,
+ .remove = i2c_hid_core_remove,
+ .shutdown = i2c_hid_core_shutdown,
+ .id_table = i2c_hid_acpi_prp0001_id,
+};
+
+module_i2c_driver(i2c_hid_acpi_prp0001_driver);
+
+MODULE_DESCRIPTION("HID over I2C driver for PRP0001 devices missing hid-descr-addr");
+MODULE_AUTHOR("谢致邦 (XIE Zhibang) <Yeking@Red54.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
index abd700a101f4..13f977d6aab6 100644
--- a/drivers/hid/i2c-hid/i2c-hid-acpi.c
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
@@ -25,9 +25,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm.h>
-#include <linux/uuid.h>
#include "i2c-hid.h"
+#include "i2c-hid-acpi.h"
struct i2c_hid_acpi {
struct i2chid_ops ops;
@@ -48,39 +48,11 @@ static const struct acpi_device_id i2c_hid_acpi_blacklist[] = {
{ }
};
-/* HID I²C Device: 3cdff6f7-4267-4555-ad05-b30a3d8938de */
-static guid_t i2c_hid_guid =
- GUID_INIT(0x3CDFF6F7, 0x4267, 0x4555,
- 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE);
-
-static int i2c_hid_acpi_get_descriptor(struct i2c_hid_acpi *ihid_acpi)
-{
- struct acpi_device *adev = ihid_acpi->adev;
- acpi_handle handle = acpi_device_handle(adev);
- union acpi_object *obj;
- u16 hid_descriptor_address;
-
- if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0)
- return -ENODEV;
-
- obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL,
- ACPI_TYPE_INTEGER);
- if (!obj) {
- acpi_handle_err(handle, "Error _DSM call to get HID descriptor address failed\n");
- return -ENODEV;
- }
-
- hid_descriptor_address = obj->integer.value;
- ACPI_FREE(obj);
-
- return hid_descriptor_address;
-}
-
static void i2c_hid_acpi_restore_sequence(struct i2chid_ops *ops)
{
struct i2c_hid_acpi *ihid_acpi = container_of(ops, struct i2c_hid_acpi, ops);
- i2c_hid_acpi_get_descriptor(ihid_acpi);
+ i2c_hid_acpi_get_descriptor(ihid_acpi->adev);
}
static void i2c_hid_acpi_shutdown_tail(struct i2chid_ops *ops)
@@ -93,24 +65,28 @@ static void i2c_hid_acpi_shutdown_tail(struct i2chid_ops *ops)
static int i2c_hid_acpi_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct i2c_hid_acpi *ihid_acpi;
u16 hid_descriptor_address;
int ret;
- ihid_acpi = devm_kzalloc(&client->dev, sizeof(*ihid_acpi), GFP_KERNEL);
+ if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0)
+ return -ENODEV;
+
+ ret = i2c_hid_acpi_get_descriptor(adev);
+ if (ret < 0)
+ return ret;
+ hid_descriptor_address = ret;
+
+ ihid_acpi = devm_kzalloc(dev, sizeof(*ihid_acpi), GFP_KERNEL);
if (!ihid_acpi)
return -ENOMEM;
- ihid_acpi->adev = ACPI_COMPANION(dev);
+ ihid_acpi->adev = adev;
ihid_acpi->ops.shutdown_tail = i2c_hid_acpi_shutdown_tail;
ihid_acpi->ops.restore_sequence = i2c_hid_acpi_restore_sequence;
- ret = i2c_hid_acpi_get_descriptor(ihid_acpi);
- if (ret < 0)
- return ret;
- hid_descriptor_address = ret;
-
- acpi_device_fix_up_power(ihid_acpi->adev);
+ acpi_device_fix_up_power(adev);
return i2c_hid_core_probe(client, &ihid_acpi->ops,
hid_descriptor_address, 0);
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.h b/drivers/hid/i2c-hid/i2c-hid-acpi.h
new file mode 100644
index 000000000000..8cebbeebcc23
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _I2C_HID_ACPI_H
+#define _I2C_HID_ACPI_H
+
+#include <linux/acpi.h>
+#include <linux/uuid.h>
+
+static inline int i2c_hid_acpi_get_descriptor(struct acpi_device *adev)
+{
+ /* HID I²C Device: 3cdff6f7-4267-4555-ad05-b30a3d8938de */
+ static const guid_t i2c_hid_guid =
+ GUID_INIT(0x3CDFF6F7, 0x4267, 0x4555,
+ 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE);
+
+ acpi_handle handle = acpi_device_handle(adev);
+ union acpi_object *obj;
+ u16 addr;
+
+ obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid,
+ 1, 1, NULL, ACPI_TYPE_INTEGER);
+ if (!obj) {
+ acpi_handle_err(handle, "Error _DSM call to get HID descriptor address failed\n");
+ return -ENODEV;
+ }
+
+ addr = obj->integer.value;
+ ACPI_FREE(obj);
+ return addr;
+}
+
+#endif
--
2.52.0
^ permalink raw reply related
* Re: [PATCH] HID: amd_sfh: return an error when response wait times out
From: sashiko-bot @ 2026-06-24 14:52 UTC (permalink / raw)
To: Pengpeng Hou; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260624143558.39306-1-pengpeng@iscas.ac.cn>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] The timeout error codes returned by the patch are silently discarded, rendering the fix ineffective.
Pre-existing issues:
- [High] Data race on the shared cli_data->cur_hid_dev variable causes spurious timeouts and missed wakeups.
- [High] A timeout in amdtp_wait_for_response leaves a stalled request in the queue, permanently desynchronizing the state machine.
--
commit e8a7b9fc56953c32e53def387e9ca9eac4750f78
Author: Pengpeng Hou <pengpeng@iscas.ac.cn>
HID: amd_sfh: return an error when response wait times out
amdtp_wait_for_response() waits for request_done before completing a
report request. wait_event_interruptible_timeout() returns 0 when the
wait expires, but the current code treats only negative values as errors
and returns success on timeout. This commit returns -ETIMEDOUT when the
response wait expires.
> diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
> index b04f675d49b0d..8f88f965fbd55 100644
> --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
> +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
> @@ -87,16 +87,17 @@ static int amdtp_wait_for_response(struct hid_device *hid)
> break;
> }
>
> - if (!cli_data->request_done[i])
> + if (!cli_data->request_done[i]) {
> ret = wait_event_interruptible_timeout(hid_data->hid_wait,
> cli_data->request_done[i],
> msecs_to_jiffies(AMD_SFH_RESPONSE_TIMEOUT));
> - if (ret == -ERESTARTSYS)
> - return -ERESTARTSYS;
> - else if (ret < 0)
> - return -ETIMEDOUT;
> - else
> - return 0;
> + if (ret == -ERESTARTSYS)
> + return -ERESTARTSYS;
> + if (ret <= 0)
> + return -ETIMEDOUT;
[Severity: High]
The patch returns -ETIMEDOUT here, but amdtp_wait_for_response() is registered
as the .wait callback in struct hid_ll_driver.
When called via the wrapper hid_hw_wait(), the return value is discarded:
include/linux/hid.h:hid_hw_wait()
static inline void hid_hw_wait(struct hid_device *hdev)
{
if (hdev->ll_driver->wait)
hdev->ll_driver->wait(hdev);
}
Does this mean the caller (HID core) never sees the error code and proceeds as
if the wait succeeded?
[Severity: High]
This isn't a bug introduced by this patch, but if this times out, does it
leave a stalled request in the queue?
In amd_sfh_get_report(), requests are queued to cli_data->req_list. If we
exit here, the request node isn't removed. Later, amd_sfh_work() pops and
processes it:
drivers/hid/amd-sfh-hid/amd_sfh_client.c:amd_sfh_work()
req_node = list_last_entry(&req_list->list, struct request_list, list);
list_del(&req_node->list);
Will this cause the background worker to process timed-out requests and
prematurely wake up future requests with stale data, permanently
desynchronizing the request queue?
> + }
> +
> + return 0;
> }
>
> void amdtp_hid_wakeup(struct hid_device *hid)
> {
> struct amdtp_hid_data *hid_data;
> struct amdtp_cl_data *cli_data;
>
> if (hid) {
> hid_data = hid->driver_data;
> cli_data = hid_data->cli_data;
> cli_data->request_done[cli_data->cur_hid_dev] = true;
[Severity: High]
This is a pre-existing issue, but is there a data race on
cli_data->cur_hid_dev?
amd_sfh_set_report() updates cur_hid_dev locklessly:
drivers/hid/amd-sfh-hid/amd_sfh_client.c:amd_sfh_set_report()
cli_data->cur_hid_dev = i;
If a SET_REPORT request is issued concurrently with a GET_REPORT worker, could
cur_hid_dev be overwritten, causing amdtp_hid_wakeup() to set request_done for
the wrong device index and leaving the original device's waiter to permanently
time out?
> wake_up_interruptible(&hid_data->hid_wait);
> }
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260624143558.39306-1-pengpeng@iscas.ac.cn?part=1
^ permalink raw reply
* Re: [PATCH v2 2/2] arm64: dts: qcom: sdm845-oneplus: Update compatible to include model
From: David Heidelberg @ 2026-06-24 14:37 UTC (permalink / raw)
To: Dmitry Torokhov, Krzysztof Kozlowski, Konrad Dybcio
Cc: Rob Herring, Conor Dooley, Jason A. Donenfeld, Matthias Schiffer,
Vincent Huang, Bjorn Andersson, Konrad Dybcio, linux-input,
devicetree, linux-kernel, linux-arm-msm, phone-devel,
Krzysztof Kozlowski
In-Reply-To: <ajtaUb4YmyZTDLmQ@google.com>
On 24/06/2026 06:28, Dmitry Torokhov wrote:
> Hi David,
>
> On Sun, Jun 21, 2026 at 07:11:45PM +0200, David Heidelberg wrote:
>> On 28/05/2026 00:13, David Heidelberg wrote:
>>> On 27/05/2026 23:56, Dmitry Torokhov wrote:
>>>> Hi David,
>>>>
>>>> On Sat, May 23, 2026 at 11:45:35AM +0200, David Heidelberg via B4 Relay wrote:
>>>>> From: David Heidelberg <david@ixit.cz>
>>>>>
>>>>> We know the driver is reporting s3706b, introduce the compatible so we
>>>>> can more easily introduce quirks for weird touchscreen replacements in
>>>>> followup series.
>>>>>
>>>>> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>>>> Signed-off-by: David Heidelberg <david@ixit.cz>
>>>>> ---
>>>>> arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 2 +-
>>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
>>>>> b/arch/ arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
>>>>> index 6b7378cf4d493..148164d456a5a 100644
>>>>> --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
>>>>> +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
>>>>> @@ -475,17 +475,17 @@ bq27441_fg: bq27441-battery@55 {
>>>>> };
>>>>> };
>>>>> &i2c12 {
>>>>> status = "okay";
>>>>> clock-frequency = <400000>;
>>>>> synaptics-rmi4-i2c@20 {
>>>>> - compatible = "syna,rmi4-i2c";
>>>>> + compatible = "syna,rmi4-s3706b", "syna,rmi4-i2c";
>>>>
>>>> So I believe we established that this device (s3706b) does not in fact
>>>> implement rmi4 protocol properly. Why do we have "syna,rmi4-i2c" as a
>>>> fallback? Shouldn't it be just "syna,rmi4-s3706b"?
>>>
>>> The vendor supplies s3706b which does implement the RMI4 properly.
>>>
>>> The 3rd party replacement impersonating original parts may not implement
>>> it properly, but I don't address this issue in this initial submission.
>>>
>>> With this compatible we know which original part is used by the vendor
>>> and installed in the phones, so later we can deduct specific sequences
>>> for the replacement aftermarket parts to keep phone touchscreen working
>>> same as they do on Android without affecting other devices.
>>
>> Hello Dmitry.
>>
>> May I ask what is currently preventing this series from moving forward?
>>
>> The first version was posted in 2023 [1]. I picked it up again in 2025 [2]
>> and am now on the 9th iteration (this patchset). At this point, the series
>> has been under discussion for well over a year, with relatively little
>> feedback and increasingly long gaps between review rounds.
>>
>> The current approach is based on the guidance I have received so far,
>> including suggestions from the device-tree maintainers. When concerns were
>> raised, I tried to address them and rework the series accordingly.
>>
>> What I am struggling with is understanding what specific issue still needs
>> to be resolved before these patches can be accepted. If there are remaining
>> requirements, objections to the approach, or technical concerns that I have
>> not addressed, I would appreciate having them stated explicitly so I can
>> work on them.
>>
>> I also split out the straightforward, self-contained changes in the hope
>> that at least those could progress independently while I continued working
>> on any follow-up requirements. However, even those patches do not appear to
>> be moving forward.
>>
>> Could you please clarify what outcome you would like to see from this
>> series, and what concrete changes would be required to get it accepted?
>
> I am still confused about how you want to differentiate between the full
> RMI4 support vs the OnePlus flavor. The "syna,rmi4-s3706b", as you
> mentioned, implements RMI4 protocol properly, so we do not need to
> actually have it documented neither in binding nor in DTS.
--- part 1 ---
This series addresses identification within device-tree. It's normal recommended
practice.
If we know, the device ships specific, but **compliant** variant, we just put it
as compatible = "more-specific", "less-specific"; in this case
"syna,rmi4-s3706b", "syna,rmi4-i2c"
This approach is used everywhere. This has nothing to do with after-market parts.
--- part 2 (irrelevant for this series) ---
>
> The issue you have with after-market parts that are not compliant and we
> need to figure out how to deal with them. Inside the driver I
As was suggested by device-tree folks, this is the first step, there isn't
better one available. If there is, please suggest one, and I'll apply it.
> essentially need a"incomplete protocol" flag that we can use to
> implement additional checks or skip known to be not implemented
> functions/queries. In DT we could introduce something like
> "oneplus,rmi4-i2c" that is decidedly not compatible with "syna,rmi4-i2c"
> and neither one should be a fallback for the other.
>
> This of course needs buy-in from DT maintainers.
As you can see, this still holds Acked-by and Reviewed-by from the relevant
people - Krzysztof and Konrad.
>
> Does this make sense?
For the scope we're discussing it doesn't seems so.
This discussion should be associated with the last revision of the full series I
sent 3 months ago. We're in very unflattering state, where:
2018 - these aftermarket touchscreen worked on Android well enough for people
to have working touch (let's say with slightly worse experience then the original).
2026 in the mainline, we cannot even more forward and report to user-space
there is aftermarket non-compliant piece of hardware installed.
Actionable steps I suggest after this series lands:
1. don't do any changes, but since we know what 3rd party touchscreen do
incorrectly deviating from the standard, REPORT it to the userspace, so USER
know, their device (phone/tablet) doesn't have original part.
2. then figure out, IF we can reasonably well workaround it and HOW to do it
These two steps present some progress which could be discussed and could lead us
somewhere, what do you think?
David
>
> Thanks.
>
^ permalink raw reply
* [PATCH] HID: amd_sfh: return an error when response wait times out
From: Pengpeng Hou @ 2026-06-24 14:35 UTC (permalink / raw)
To: Basavaraj Natikar, Jiri Kosina, Benjamin Tissoires
Cc: Pengpeng Hou, linux-input, linux-kernel
amdtp_wait_for_response() waits for request_done before completing a
report request. wait_event_interruptible_timeout() returns 0 when the
wait expires, but the current code treats only negative values as errors
and returns success on timeout.
Return -ETIMEDOUT when the response wait expires while preserving the
existing success path when the response has already been observed.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
index b04f675d4..8f88f965f 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
@@ -87,16 +87,17 @@ static int amdtp_wait_for_response(struct hid_device *hid)
break;
}
- if (!cli_data->request_done[i])
+ if (!cli_data->request_done[i]) {
ret = wait_event_interruptible_timeout(hid_data->hid_wait,
cli_data->request_done[i],
msecs_to_jiffies(AMD_SFH_RESPONSE_TIMEOUT));
- if (ret == -ERESTARTSYS)
- return -ERESTARTSYS;
- else if (ret < 0)
- return -ETIMEDOUT;
- else
- return 0;
+ if (ret == -ERESTARTSYS)
+ return -ERESTARTSYS;
+ if (ret <= 0)
+ return -ETIMEDOUT;
+ }
+
+ return 0;
}
void amdtp_hid_wakeup(struct hid_device *hid)
--
2.50.1 (Apple Git-155)
^ permalink raw reply related
* Re: [PATCH v2 0/8] HID: iio: Avoid race between callback setup and device exposure
From: Andy Shevchenko @ 2026-06-24 11:18 UTC (permalink / raw)
To: Sanjay Chitroda
Cc: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan,
linux-input, linux-iio, linux-kernel, srinivas pandruvada
In-Reply-To: <7288DEE7-91CD-4823-959B-229AEF1CAD97@gmail.com>
On Wed, Jun 24, 2026 at 07:13:12AM +0530, Sanjay Chitroda wrote:
> On 23 June 2026 4:00:27 pm IST, Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> >On Mon, Jun 22, 2026 at 10:59:56AM +0530, Sanjay Chitroda wrote:
> >>
> >> This series avoid a race condition in HID IIO drivers related to the
> >> ordering between callback registration and device exposure.
> >>
> >> Currently, several HID IIO drivers register the IIO device (making it
> >> visible to userspace and other kernel consumers) before all required
> >> callbacks and resources are fully initialized, or rely on devm-based
> >> cleanup in a way that does not guarantee correct teardown ordering.
> >> This creates a window where the device can be accessed while it is
> >
> >There is a difference between "this creates" and "this might create".
> >I believe Srinivas and others were asking for the proof. So, what path
> >in the code makes this happen or possible to happen?
> >
> iio_device_register() exposes the IIO device to user space, while
> sensor_hub_register_callback() registers callbacks for buffered IIO(streaming
> mode).
>
> This might create window where from userspace buffer mode is enabled and
> callbacks are not registered which would result into loss of samples until
> callback registration completes, although no explicit failure. In teardown
> path which can resulting in stale/no data.
>
> This was discussed in the v1 thread and v2 was posted based on discussion and
> agreement:
> https://lore.kernel.org/all/3FED088A-651B-4E8B-840B-1B92CB4DF6F4@gmail.com/
>
> >> not fully initialized or is being torn down, potentially leading to
> >> sample drop or stale/no data.
> >>
> >> To handle this, the series ensures that:
> >> - All required callbacks and resources are set up before the device
> >> is registered with the IIO core
> >> - Resource cleanup is performed explicitly where ordering matters
> >>
> >> PS: This is prepratory series to convert all HID IIO driver to devm.
> >>
> >> Testing:
> >> - Compiled with W=1 for each patch in series
> >>
> >> ---
> >> Changes in v2:
> >> - Drop fixes tag and rectify commit message with reference to that
> >
> >You also dropped my tag. Why?
> >
> Thank you for the review and tag on v1.
>
> While code changes are intact in v2, the rational and commit message were
> updated substantially. Since commit message is as important as change which
> will be permanent in history for future reference, I chose to drop the tag to
> request a fresh review.
Now it's clear, thanks.
This version with changed commit messages seems good to me.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> I shall highlight the same in change log. I'll make sure to note in future revision.
Yes, please.
>
> >> - Link to v1: https://patch.msgid.link/20260606-5-june-hid-iio-race-fixes-v1-0-27a848c5758f@gmail.com
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 0/4] input: misc: Add an initial driver for haptics inside Qcom PMIH010x PMIC
From: Krzysztof Kozlowski @ 2026-06-24 10:05 UTC (permalink / raw)
To: Fenglin Wu
Cc: linux-arm-msm, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lee Jones, Stephen Boyd, Bjorn Andersson,
Konrad Dybcio, David Collins, Subbaraman Narayanamurthy,
Kamal Wadhwa, kernel, linux-input, devicetree, linux-kernel
In-Reply-To: <be2b54a5-ce9d-49a2-80e1-60da874350d9@oss.qualcomm.com>
On 24/06/2026 09:20, Fenglin Wu wrote:
>
> On 6/17/2026 6:42 PM, Krzysztof Kozlowski wrote:
>> On Tue, Jun 16, 2026 at 03:08:23AM -0700, Fenglin Wu wrote:
>>
>> Here - the first sentence - is where you mention merging
>> constraints/strategy/dependencies. Your MFD patch depends on ealier
>> ones.
>>
> Did you mean that these 2 MFD binding changes should be listed as the
> dependency of the MFD patch?
No. Act as maintainer. Clone Linus tree, apply the patch and see if
everything works. My claim is that nothing works and maintainer tree is
broken.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH] Input: gscps2 - advance receive buffer write index
From: sashiko-bot @ 2026-06-24 9:59 UTC (permalink / raw)
To: raoxu; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <460B5655BA580C60+20260624094739.850306-1-raoxu@uniontech.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
Pre-existing issues:
- [High] Lockless access to the ring buffer consumer index causes a data race and buffer corruption.
- [High] Lockless modifications and traversals of the global `ps2port_list` lead to list corruption and use-after-free.
- [High] Registering the shared IRQ before adding the device to the port list creates a window for an unhandled interrupt storm.
- [High] Unbounded hardware polling loops can hang the CPU if the device enters a faulty state.
- [High] The shared interrupt handler unconditionally returns `IRQ_HANDLED`, defeating the kernel's spurious interrupt detector.
--
commit b6fd4271cba05f59b05437ee042428ed8db2fb92
Author: Xu Rao <raoxu@uniontech.com>
Input: gscps2 - advance receive buffer write index
Commit 44f920069911 moved the receive loop into gscps2_read_data() and
gscps2_report_data(), but omitted the producer index update. This patch
restores the omitted index update so data reaches the serio core.
> diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
> index 22b2f57fd91f5..bf9b993f57330 100644
> --- a/drivers/input/serio/gscps2.c
> +++ b/drivers/input/serio/gscps2.c
> @@ -219,6 +219,7 @@ static void gscps2_read_data(struct gscps2port *ps2port)
> ps2port->buffer[ps2port->append].str = status;
> ps2port->buffer[ps2port->append].data =
> gscps2_readb_input(ps2port->addr);
> + ps2port->append = (ps2port->append + 1) & BUFFER_SIZE;
> } while (true);
> }
[Severity: High]
This is a pre-existing issue, but can this unbounded loop hang the CPU?
If the hardware enters a faulty state or is hot-unplugged, reading the status
register might continually return 0xFF. The loop condition earlier in this
function:
if (!(status & GSC_STAT_RBNE))
break;
would remain true forever (0xFF & 0x01). Similar unbounded polling exists in
gscps2_flush() and gscps2_writeb_output(). Should there be a timeout or retry
limit here?
[Severity: High]
This isn't a bug introduced by this patch, but does the lockless access to
ps2port->act cause a data race?
In gscps2_report_data(), ps2port->act is evaluated and advanced without
holding ps2port->lock:
gscps2_report_data() {
...
while (ps2port->act != ps2port->append) {
...
ps2port->act = (ps2port->act + 1) & BUFFER_SIZE;
}
}
Since gscps2_interrupt() can be called synchronously from process context
(like in gscps2_writeb_output() with gscps2_interrupt(0, NULL)) while local
interrupts are enabled, a hardware IRQ could fire concurrently on another CPU.
Could both CPUs execute gscps2_report_data() simultaneously and corrupt the
buffer?
[Severity: High]
This isn't a bug introduced by this patch, but is it safe to iterate
ps2port_list without locks?
gscps2_probe() and gscps2_remove() modify the global ps2port_list locklessly:
gscps2_probe() {
...
list_add_tail(&ps2port->node, &ps2port_list);
}
Meanwhile, gscps2_interrupt() iterates this list without any locks:
gscps2_interrupt() {
...
list_for_each_entry(ps2port, &ps2port_list, node) {
}
Since gscps2_interrupt() can be invoked at any time by a shared hardware IRQ
or manually via gscps2_writeb_output(), could this traversal race with a
concurrent probe or remove operation on a different CPU and lead to a
use-after-free?
[Severity: High]
This isn't a bug introduced by this patch, but does registering the shared
IRQ before adding the device to the port list create an interrupt storm
window?
In gscps2_probe(), the IRQ is requested before the device is added to the
list:
gscps2_probe() {
...
if (request_irq(dev->irq, gscps2_interrupt, IRQF_SHARED, ...))
...
list_add_tail(&ps2port->node, &ps2port_list);
}
If an interrupt fires immediately after registration, gscps2_interrupt() will
iterate the list, find nothing, and return IRQ_HANDLED without clearing the
hardware interrupt condition. For a level-triggered IRQ, could this
immediately re-fire and hang the CPU?
[Severity: High]
This isn't a bug introduced by this patch, but does the interrupt handler
always return IRQ_HANDLED?
gscps2_interrupt() is registered with IRQF_SHARED, but exits unconditionally
claiming it handled the interrupt:
gscps2_interrupt() {
...
return IRQ_HANDLED;
}
If a different device sharing the same IRQ line continuously asserts the
interrupt due to a fault, the kernel relies on handlers returning IRQ_NONE
to detect the spurious storm and safely disable the IRQ line.
By always returning IRQ_HANDLED, does this prevent the kernel from detecting
spurious interrupts from neighboring devices?
--
Sashiko AI review · https://sashiko.dev/#/patchset/460B5655BA580C60+20260624094739.850306-1-raoxu@uniontech.com?part=1
^ permalink raw reply
* [PATCH] Input: gscps2 - advance receive buffer write index
From: raoxu @ 2026-06-24 9:47 UTC (permalink / raw)
To: James.Bottomley
Cc: deller, dmitry.torokhov, linux-parisc, linux-input, linux-kernel,
raoxu, stable
From: Xu Rao <raoxu@uniontech.com>
Commit 44f920069911 ("Input: gscps2 - use guard notation when
acquiring spinlock") moved the receive loop into gscps2_read_data()
and gscps2_report_data().
While moving the code, it preserved the writes to
buffer[ps2port->append], but omitted the following producer index
update from the original loop:
ps2port->append = (ps2port->append + 1) & BUFFER_SIZE;
As a result, append never advances. Since gscps2_report_data() only
reports bytes while act != append, the receive buffer always appears
empty and no keyboard or mouse data reaches the serio core.
Restore the omitted index update.
Fixes: 44f920069911 ("Input: gscps2 - use guard notation when acquiring spinlock")
Cc: stable@vger.kernel.org # 6.13+
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/input/serio/gscps2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 22b2f57..bf9b993 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -219,6 +219,7 @@ static void gscps2_read_data(struct gscps2port *ps2port)
ps2port->buffer[ps2port->append].str = status;
ps2port->buffer[ps2port->append].data =
gscps2_readb_input(ps2port->addr);
+ ps2port->append = (ps2port->append + 1) & BUFFER_SIZE;
} while (true);
}
--
2.47.3
^ permalink raw reply related
* Re: [PATCH 0/4] input: misc: Add an initial driver for haptics inside Qcom PMIH010x PMIC
From: Fenglin Wu @ 2026-06-24 7:20 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: linux-arm-msm, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lee Jones, Stephen Boyd, Bjorn Andersson,
Konrad Dybcio, David Collins, Subbaraman Narayanamurthy,
Kamal Wadhwa, kernel, linux-input, devicetree, linux-kernel
In-Reply-To: <20260617-spry-greedy-chital-1276e0@quoll>
On 6/17/2026 6:42 PM, Krzysztof Kozlowski wrote:
> On Tue, Jun 16, 2026 at 03:08:23AM -0700, Fenglin Wu wrote:
>
> Here - the first sentence - is where you mention merging
> constraints/strategy/dependencies. Your MFD patch depends on ealier
> ones.
>
Did you mean that these 2 MFD binding changes should be listed as the
dependency of the MFD patch?
https://lore.kernel.org/linux-arm-msm/20260609-pmg1110-v1-1-6604d0adc907@oss.qualcomm.com/
https://lore.kernel.org/linux-arm-msm/20260610124119.253456-2-krzysztof.kozlowski@oss.qualcomm.com/
>> Qualcomm PMIH010x PMIC has a haptics module inside and it could drive
>> a LRA actuator with several play modes, including: DIRECT_PLAY, FIFO,
>> PAT_MEM, SWR, etc. Add an initial driver to support two of the play
>> modes using the input force-feedback framework:
>>
> Best regards,
> Krzysztof
>
^ permalink raw reply
* Re: [PATCH v5 4/6] dt-bindings: input: sun4i-lradc-keys: Add A100/A133 compatible
From: Krzysztof Kozlowski @ 2026-06-24 6:51 UTC (permalink / raw)
To: Alexander Sverdlin
Cc: linux-arm-kernel, linux-sunxi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Hans de Goede, Dmitry Torokhov, Andre Przywara, Jun Yan,
Lukas Schmid, J. Neuschäfer, Eric Biggers, Michal Simek,
Luca Weiss, Sven Peter, Maxime Ripard, devicetree, linux-kernel,
linux-input
In-Reply-To: <20260623204824.691832-5-alexander.sverdlin@gmail.com>
On Tue, Jun 23, 2026 at 10:48:16PM +0200, Alexander Sverdlin wrote:
> The Allwinner A100/A133 SoCs have an LRADC which is compatible with the
> versions in existing SoCs. Add a compatible string for A100, with the R329
> fallback.
>
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> ---
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 4/4] Input: ensure device is ready before delivering events
From: sashiko-bot @ 2026-06-24 6:02 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260624055008.2494980-4-dmitry.torokhov@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Missing physical feedback teardown in input_close_device causes LEDs/sounds to remain stuck ON indefinitely.
--
commit 75d930ba0fffcfc837221baa51848c81d0ba0c9e
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Input: ensure device is ready before delivering events
This commit introduces a ready flag in the input_dev structure to prevent
events from being delivered to the hardware before the driver's open() method
successfully completes. It ensures logical state is replayed upon opening,
and synchronizes physical feedback teardown during inhibition.
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 0a95cbdc467ed..724cc146fc093 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
[ ... ]
> @@ -661,6 +708,10 @@ void input_close_device(struct input_handle *handle)
> if (!--dev->users && !dev->inhibited) {
> if (dev->poller)
> input_dev_poller_stop(dev->poller);
> +
> + scoped_guard(spinlock_irq, &dev->event_lock)
> + dev->ready = false;
[Severity: Medium]
Will this leave LEDs and sounds permanently stuck on when a device is closed?
In input_inhibit_device(), there is a call to input_dev_toggle(dev, false)
right before setting dev->ready to false.
However, in input_close_device(), dev->ready is cleared without first
toggling the state off.
Since the suspend and poweroff handlers rely on dev->ready to issue events,
could omitting input_dev_toggle() here prevent them from turning off physical
feedback, resulting in a persistent power drain?
> +
> if (dev->close)
> dev->close(dev);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260624055008.2494980-1-dmitry.torokhov@gmail.com?part=4
^ permalink raw reply
* Re: [PATCH 1/4] Input: fix poller start order on uninhibit
From: sashiko-bot @ 2026-06-24 6:00 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260624055008.2494980-1-dmitry.torokhov@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Initial events from `dev->open()` are dropped during device uninhibit
--
commit f4fc68b8f579c449b7f9056431e51975c324c92e
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Input: fix poller start order on uninhibit
This commit resolves an issue where initial events generated by the poller
are dropped during a device uninhibit operation. It defers starting the
poller until after the device is fully marked as uninhibited.
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index cf6fecea79b82..d99dfe69e12d8 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1793,8 +1793,6 @@ static int input_uninhibit_device(struct input_dev *dev)
> if (error)
> return error;
> }
[Severity: High]
This isn't a bug introduced by this patch, but it appears the exact same
logic flaw exists for dev->open() which is called just above this snippet
in input_uninhibit_device():
if (dev->open) {
error = dev->open(dev);
if (error)
return error;
}
Since dev->inhibited is still true when dev->open() is called, if a driver
generates initial synchronous events during its open routine (for example,
gpio_keys_report_state() called by gpio_keys_open()), won't those events
also be silently filtered out by input_get_disposition() returning
INPUT_IGNORE_EVENT?
Since this patch addresses this state mismatch for the poller, should the
dev->open() call also be deferred until after dev->inhibited is set to false?
> - if (dev->poller)
> - input_dev_poller_start(dev->poller);
> }
>
> dev->inhibited = false;
> @@ -1802,6 +1800,9 @@ static int input_uninhibit_device(struct input_dev *dev)
> scoped_guard(spinlock_irq, &dev->event_lock)
> input_dev_toggle(dev, true);
>
> + if (dev->users && dev->poller)
> + input_dev_poller_start(dev->poller);
> +
> return 0;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260624055008.2494980-1-dmitry.torokhov@gmail.com?part=1
^ permalink raw reply
* [PATCH 4/4] Input: ensure device is ready before delivering events
From: Dmitry Torokhov @ 2026-06-24 5:50 UTC (permalink / raw)
To: linux-input, Jiri Kosina, Benjamin Tissoires; +Cc: linux-kernel
In-Reply-To: <20260624055008.2494980-1-dmitry.torokhov@gmail.com>
When a device is opened via input_open_device(), the driver's open()
callback is invoked. Some drivers, like cm109, submit URBs or perform
other hardware initialization in their open() callbacks.
However, the input core does not prevent dev->event() from being called
concurrently during the driver's open() execution. For instance, if a
console beep occurs, the kbd handler might inject an EV_SND event. This
can lead to double list_add BUGs if the driver submits the same URB in
both open() and event() paths without adequate synchronization.
To fix this, introduce a ready flag in the input_dev structure.
For complex devices (where dev->open is defined), this flag is set to true
only after the driver's open() method successfully completes. The core now
checks ready in input_event_dispose() and input_dev_toggle()
to prevent events from reaching the hardware before it is fully prepared.
For simple devices (no open callback), events are delivered immediately.
We also replay the logical state in input_open_device() by calling
input_dev_toggle() right after marking the device ready, ensuring no
events are permanently lost.
In the inhibit path, we ensure that physical feedback (LEDs/sounds) is
turned off before the device is closed, and we synchronize the inhibited
state transition under the event lock to prevent races with incoming events.
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/input.c | 107 ++++++++++++++++++++++++++----------------
include/linux/input.h | 12 +++--
2 files changed, 75 insertions(+), 44 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 0a95cbdc467e..724cc146fc09 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -318,7 +318,7 @@ static int input_get_disposition(struct input_dev *dev,
static void input_event_dispose(struct input_dev *dev, int disposition,
unsigned int type, unsigned int code, int value)
{
- if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
+ if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event && dev->ready)
dev->event(dev, type, code, value);
if (disposition & INPUT_PASS_TO_HANDLERS) {
@@ -568,6 +568,48 @@ void input_release_device(struct input_handle *handle)
}
EXPORT_SYMBOL(input_release_device);
+#define INPUT_DO_TOGGLE(dev, type, bits, on) \
+ do { \
+ int i; \
+ bool active; \
+ \
+ if (!test_bit(EV_##type, dev->evbit)) \
+ break; \
+ \
+ for_each_set_bit(i, dev->bits##bit, type##_CNT) { \
+ active = test_bit(i, dev->bits); \
+ if (!active && !on) \
+ continue; \
+ \
+ dev->event(dev, EV_##type, i, on ? active : 0); \
+ } \
+ } while (0)
+
+/*
+ * Iterate through the logical state of the input device (LEDs, sounds,
+ * auto-repeat) and explicitly push that state down to the hardware
+ * via dev->event() to match the current logical state (if activate is true),
+ * or forcibly turn off all feedback like LEDs and sounds during teardown
+ * or suspend (if activate is false).
+ *
+ * Primarily used as a state-replay mechanism after a device is opened
+ * or uninhibited, as events might have been dropped by the core while the
+ * hardware was not marked as ready.
+ */
+static void input_dev_toggle(struct input_dev *dev, bool activate)
+{
+ if (!dev->event || !dev->ready)
+ return;
+
+ INPUT_DO_TOGGLE(dev, LED, led, activate);
+ INPUT_DO_TOGGLE(dev, SND, snd, activate);
+
+ if (activate && test_bit(EV_REP, dev->evbit)) {
+ dev->event(dev, EV_REP, REP_PERIOD, dev->rep[REP_PERIOD]);
+ dev->event(dev, EV_REP, REP_DELAY, dev->rep[REP_DELAY]);
+ }
+}
+
static int input_start_device(struct input_dev *dev)
{
int error;
@@ -583,6 +625,11 @@ static int input_start_device(struct input_dev *dev)
}
}
+ scoped_guard(spinlock_irq, &dev->event_lock) {
+ dev->ready = true;
+ input_dev_toggle(dev, true);
+ }
+
if (dev->poller)
input_dev_poller_start(dev->poller);
}
@@ -661,6 +708,10 @@ void input_close_device(struct input_handle *handle)
if (!--dev->users && !dev->inhibited) {
if (dev->poller)
input_dev_poller_stop(dev->poller);
+
+ scoped_guard(spinlock_irq, &dev->event_lock)
+ dev->ready = false;
+
if (dev->close)
dev->close(dev);
}
@@ -1712,37 +1763,6 @@ static int input_dev_uevent(const struct device *device, struct kobj_uevent_env
return 0;
}
-#define INPUT_DO_TOGGLE(dev, type, bits, on) \
- do { \
- int i; \
- bool active; \
- \
- if (!test_bit(EV_##type, dev->evbit)) \
- break; \
- \
- for_each_set_bit(i, dev->bits##bit, type##_CNT) { \
- active = test_bit(i, dev->bits); \
- if (!active && !on) \
- continue; \
- \
- dev->event(dev, EV_##type, i, on ? active : 0); \
- } \
- } while (0)
-
-static void input_dev_toggle(struct input_dev *dev, bool activate)
-{
- if (!dev->event)
- return;
-
- INPUT_DO_TOGGLE(dev, LED, led, activate);
- INPUT_DO_TOGGLE(dev, SND, snd, activate);
-
- if (activate && test_bit(EV_REP, dev->evbit)) {
- dev->event(dev, EV_REP, REP_PERIOD, dev->rep[REP_PERIOD]);
- dev->event(dev, EV_REP, REP_DELAY, dev->rep[REP_DELAY]);
- }
-}
-
/**
* input_reset_device() - reset/restore the state of input device
* @dev: input device whose state needs to be reset
@@ -1770,21 +1790,25 @@ static int input_inhibit_device(struct input_dev *dev)
return 0;
if (dev->users) {
- if (dev->close)
- dev->close(dev);
if (dev->poller)
input_dev_poller_stop(dev->poller);
+
+ scoped_guard(spinlock_irq, &dev->event_lock) {
+ input_dev_toggle(dev, false);
+ dev->ready = false;
+ }
+
+ if (dev->close)
+ dev->close(dev);
}
scoped_guard(spinlock_irq, &dev->event_lock) {
input_mt_release_slots(dev);
input_dev_release_keys(dev);
input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
- input_dev_toggle(dev, false);
+ dev->inhibited = true;
}
- dev->inhibited = true;
-
return 0;
}
@@ -1804,12 +1828,15 @@ static int input_uninhibit_device(struct input_dev *dev)
if (error)
return error;
}
- }
- dev->inhibited = false;
+ guard(spinlock_irq)(&dev->event_lock);
+ dev->ready = true;
+ }
- scoped_guard(spinlock_irq, &dev->event_lock)
+ scoped_guard(spinlock_irq, &dev->event_lock) {
+ dev->inhibited = false;
input_dev_toggle(dev, true);
+ }
if (dev->users && dev->poller)
input_dev_poller_start(dev->poller);
diff --git a/include/linux/input.h b/include/linux/input.h
index f7a2cfad5448..a307a3f6d5e2 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -128,11 +128,14 @@ enum input_clock_type {
* @devres_managed: indicates that devices is managed with devres framework
* and needs not be explicitly unregistered or freed.
* @timestamp: storage for a timestamp set by input_set_timestamp called
- * by a driver
+ * by a driver
* @inhibited: indicates that the input device is inhibited. If that is
- * the case then input core ignores any events generated by the device.
- * Device's close() is called when it is being inhibited and its open()
- * is called when it is being uninhibited.
+ * the case then input core ignores any events generated by the device.
+ * Device's close() is called when it is being inhibited and its open()
+ * is called when it is being uninhibited.
+ * @ready: indicates that the device has been successfully opened and is
+ * prepared to process events (like LEDs or sounds) sent from the
+ * input core.
*/
struct input_dev {
const char *name;
@@ -209,6 +212,7 @@ struct input_dev {
ktime_t timestamp[INPUT_CLK_MAX];
bool inhibited;
+ bool ready;
};
#define to_input_dev(d) container_of(d, struct input_dev, dev)
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH 3/4] Input: defer handler's start() until device is opened
From: Dmitry Torokhov @ 2026-06-24 5:50 UTC (permalink / raw)
To: linux-input, Jiri Kosina, Benjamin Tissoires; +Cc: linux-kernel
In-Reply-To: <20260624055008.2494980-1-dmitry.torokhov@gmail.com>
When registering an input handle, handler->start() is currently called
immediately. However, the input device might not be fully opened or
ready to process events at this stage, meaning any state synchronization
events (like setting LED states) injected by the handler's start method
might be dropped.
Move the handler->start() invocation to input_open_device(). If it is
the first handle opening the device, start() is called after the driver's
open() method has successfully completed and the device is fully prepared.
To facilitate this, factor out the device startup logic (calling driver's
open and starting polling) into input_start_device().
For passive observer handlers, their start() method is also deferred
until the handle is opened. Since opening a passive observer handle does
not start the underlying hardware device, their start() method is called
immediately upon opening, regardless of whether the device is active.
Fixes: c7e8dc6ee6d5 ("Input: add start() method to input handlers")
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/input.c | 45 +++++++++++++++++++++++++------------------
include/linux/input.h | 5 +++--
2 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c2a038d31beb..0a95cbdc467e 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -568,6 +568,28 @@ void input_release_device(struct input_handle *handle)
}
EXPORT_SYMBOL(input_release_device);
+static int input_start_device(struct input_dev *dev)
+{
+ int error;
+
+ lockdep_assert_held(&dev->mutex);
+
+ if (dev->users++ == 0 && !dev->inhibited) {
+ if (dev->open) {
+ error = dev->open(dev);
+ if (error) {
+ dev->users--;
+ return error;
+ }
+ }
+
+ if (dev->poller)
+ input_dev_poller_start(dev->poller);
+ }
+
+ return 0;
+}
+
/**
* input_open_device - open input device
* @handle: handle through which device is being accessed
@@ -586,21 +608,9 @@ int input_open_device(struct input_handle *handle)
handle->open++;
- if (handle->handler->passive_observer)
- return 0;
-
- if (dev->users++ || dev->inhibited) {
- /*
- * Device is already opened and/or inhibited,
- * so we can exit immediately and report success.
- */
- return 0;
- }
-
- if (dev->open) {
- error = dev->open(dev);
+ if (!handle->handler->passive_observer) {
+ error = input_start_device(dev);
if (error) {
- dev->users--;
handle->open--;
/*
* Make sure we are not delivering any more
@@ -611,8 +621,8 @@ int input_open_device(struct input_handle *handle)
}
}
- if (dev->poller)
- input_dev_poller_start(dev->poller);
+ if (handle->open == 1 && handle->handler->start)
+ handle->handler->start(handle);
}
return 0;
@@ -2662,9 +2672,6 @@ int input_register_handle(struct input_handle *handle)
*/
list_add_tail_rcu(&handle->h_node, &handler->h_list);
- if (handler->start)
- handler->start(handle);
-
return 0;
}
EXPORT_SYMBOL(input_register_handle);
diff --git a/include/linux/input.h b/include/linux/input.h
index 3022bb730898..f7a2cfad5448 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -284,8 +284,9 @@ struct input_handle;
* @connect: called when attaching a handler to an input device
* @disconnect: disconnects a handler from input device
* @start: starts handler for given handle. This function is called by
- * input core right after connect() method and also when a process
- * that "grabbed" a device releases it
+ * input core when device is open and ready to process events,
+ * and also when device is uninhibited or when a process that "grabbed"
+ * a device releases it
* @passive_observer: set to %true by drivers only interested in observing
* data stream from devices if there are other users present. Such
* drivers will not result in starting underlying hardware device
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH 2/4] Input: call handler->start() when uninhibiting device
From: Dmitry Torokhov @ 2026-06-24 5:50 UTC (permalink / raw)
To: linux-input, Jiri Kosina, Benjamin Tissoires; +Cc: linux-kernel
In-Reply-To: <20260624055008.2494980-1-dmitry.torokhov@gmail.com>
When an input device is inhibited via input_inhibit_device(), the driver
is closed and physical feedback (like LEDs and sounds) is toggled off.
However, from the input core's perspective, the handles remain open.
When the device is later uninhibited, the driver is re-opened. While the
core restores simple LED states via input_dev_toggle(), complex handlers
(such as vt/keyboard) may need to re-synchronize their broader logical
state with the hardware.
Fixes: a181616487db ("Input: Add "inhibited" property")
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/input.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index d99dfe69e12d..c2a038d31beb 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1780,6 +1780,7 @@ static int input_inhibit_device(struct input_dev *dev)
static int input_uninhibit_device(struct input_dev *dev)
{
+ struct input_handle *handle;
int error;
guard(mutex)(&dev->mutex);
@@ -1803,6 +1804,11 @@ static int input_uninhibit_device(struct input_dev *dev)
if (dev->users && dev->poller)
input_dev_poller_start(dev->poller);
+ list_for_each_entry(handle, &dev->h_list, d_node) {
+ if (handle->open && handle->handler->start)
+ handle->handler->start(handle);
+ }
+
return 0;
}
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH 1/4] Input: fix poller start order on uninhibit
From: Dmitry Torokhov @ 2026-06-24 5:50 UTC (permalink / raw)
To: linux-input, Jiri Kosina, Benjamin Tissoires; +Cc: linux-kernel
When uninhibiting a device, we start the poller before marking the
device as uninhibited (setting dev->inhibited = false). Since the
poller immediately polls the device and reports events via input_event(),
these initial events are dropped because dev->inhibited is still true.
Fix this by starting the poller only after the device is fully uninhibited
and its state is replayed.
Fixes: a181616487db ("Input: Add "inhibited" property")
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/input.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index cf6fecea79b8..d99dfe69e12d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1793,8 +1793,6 @@ static int input_uninhibit_device(struct input_dev *dev)
if (error)
return error;
}
- if (dev->poller)
- input_dev_poller_start(dev->poller);
}
dev->inhibited = false;
@@ -1802,6 +1800,9 @@ static int input_uninhibit_device(struct input_dev *dev)
scoped_guard(spinlock_irq, &dev->event_lock)
input_dev_toggle(dev, true);
+ if (dev->users && dev->poller)
+ input_dev_poller_start(dev->poller);
+
return 0;
}
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [dtor-input:next] BUILD SUCCESS 0c9245c455e809c8111cb60284328c79064df050
From: kernel test robot @ 2026-06-24 4:40 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
branch HEAD: 0c9245c455e809c8111cb60284328c79064df050 Input: cap11xx - add support for CAP1114
elapsed time: 722m
configs tested: 259
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc allyesconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc randconfig-001-20260624 gcc-15.2.0
arc randconfig-001-20260624 gcc-9.5.0
arc randconfig-002-20260624 gcc-15.2.0
arm allnoconfig clang-23
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm allyesconfig gcc-16.1.0
arm defconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001-20260624 clang-19
arm randconfig-001-20260624 gcc-15.2.0
arm randconfig-002-20260624 gcc-15.2.0
arm randconfig-002-20260624 gcc-8.5.0
arm randconfig-003-20260624 gcc-15.2.0
arm randconfig-004-20260624 clang-16
arm randconfig-004-20260624 gcc-15.2.0
arm sama5_defconfig gcc-16.1.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260624 clang-21
arm64 randconfig-002-20260624 clang-21
arm64 randconfig-003-20260624 clang-21
arm64 randconfig-004-20260624 clang-21
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260624 clang-21
csky randconfig-002-20260624 clang-21
hexagon allmodconfig clang-23
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-16.1.0
hexagon defconfig clang-23
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260624 clang-20
hexagon randconfig-001-20260624 gcc-11.5.0
hexagon randconfig-001-20260624 gcc-9.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260624 clang-23
hexagon randconfig-002-20260624 gcc-11.5.0
hexagon randconfig-002-20260624 gcc-9.5.0
i386 allmodconfig clang-22
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 allyesconfig gcc-14
i386 buildonly-randconfig-001-20260624 gcc-12
i386 buildonly-randconfig-001-20260624 gcc-14
i386 buildonly-randconfig-002-20260624 gcc-12
i386 buildonly-randconfig-002-20260624 gcc-14
i386 buildonly-randconfig-003-20260624 gcc-12
i386 buildonly-randconfig-004-20260624 gcc-12
i386 buildonly-randconfig-004-20260624 gcc-14
i386 buildonly-randconfig-005-20260624 gcc-12
i386 buildonly-randconfig-005-20260624 gcc-14
i386 buildonly-randconfig-006-20260624 gcc-12
i386 buildonly-randconfig-006-20260624 gcc-14
i386 defconfig clang-22
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260624 clang-22
i386 randconfig-002-20260624 clang-22
i386 randconfig-003-20260624 clang-22
i386 randconfig-004-20260624 clang-22
i386 randconfig-005-20260624 clang-22
i386 randconfig-006-20260624 clang-22
i386 randconfig-007-20260624 clang-22
i386 randconfig-011-20260624 clang-22
i386 randconfig-012-20260624 clang-22
i386 randconfig-012-20260624 gcc-14
i386 randconfig-013-20260624 clang-22
i386 randconfig-014-20260624 clang-22
i386 randconfig-015-20260624 clang-22
i386 randconfig-015-20260624 gcc-14
i386 randconfig-016-20260624 clang-22
i386 randconfig-017-20260624 clang-22
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-20
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260624 gcc-11.5.0
loongarch randconfig-001-20260624 gcc-16.1.0
loongarch randconfig-001-20260624 gcc-9.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260624 gcc-11.5.0
loongarch randconfig-002-20260624 gcc-15.2.0
loongarch randconfig-002-20260624 gcc-9.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k allyesconfig gcc-16.1.0
m68k defconfig clang-23
m68k stmark2_defconfig gcc-16.1.0
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260624 gcc-11.5.0
nios2 randconfig-001-20260624 gcc-9.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260624 gcc-11.5.0
nios2 randconfig-002-20260624 gcc-9.5.0
openrisc allmodconfig clang-20
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-16.1.0
parisc allyesconfig clang-17
parisc allyesconfig gcc-16.1.0
parisc defconfig gcc-16.1.0
parisc randconfig-001-20260624 gcc-16.1.0
parisc randconfig-002-20260624 gcc-14.3.0
parisc randconfig-002-20260624 gcc-16.1.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-16.1.0
powerpc asp8347_defconfig clang-23
powerpc fsp2_defconfig gcc-16.1.0
powerpc randconfig-001-20260624 clang-23
powerpc randconfig-001-20260624 gcc-16.1.0
powerpc randconfig-002-20260624 gcc-16.1.0
powerpc randconfig-002-20260624 gcc-8.5.0
powerpc64 randconfig-001-20260624 gcc-16.1.0
powerpc64 randconfig-001-20260624 gcc-8.5.0
powerpc64 randconfig-002-20260624 gcc-11.5.0
powerpc64 randconfig-002-20260624 gcc-16.1.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001 clang-18
riscv randconfig-001-20260624 clang-18
riscv randconfig-002 clang-18
riscv randconfig-002-20260624 clang-18
s390 allmodconfig clang-17
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig clang-18
s390 defconfig gcc-16.1.0
s390 randconfig-001 clang-18
s390 randconfig-001-20260624 clang-18
s390 randconfig-002 clang-18
s390 randconfig-002-20260624 clang-18
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allnoconfig gcc-16.1.0
sh allyesconfig clang-17
sh allyesconfig gcc-16.1.0
sh defconfig gcc-14
sh randconfig-001 clang-18
sh randconfig-001-20260624 clang-18
sh randconfig-002 clang-18
sh randconfig-002-20260624 clang-18
sparc allnoconfig clang-23
sparc allnoconfig gcc-16.1.0
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260624 gcc-14.3.0
sparc randconfig-001-20260624 gcc-8.5.0
sparc randconfig-002-20260624 gcc-14.3.0
sparc randconfig-002-20260624 gcc-8.5.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260624 clang-20
sparc64 randconfig-001-20260624 gcc-14.3.0
sparc64 randconfig-002-20260624 clang-20
sparc64 randconfig-002-20260624 gcc-14.3.0
um allmodconfig clang-17
um allmodconfig clang-23
um allnoconfig clang-16
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260624 clang-23
um randconfig-001-20260624 gcc-14.3.0
um randconfig-002-20260624 clang-16
um randconfig-002-20260624 gcc-14.3.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001-20260624 clang-22
x86_64 buildonly-randconfig-002-20260624 clang-22
x86_64 buildonly-randconfig-003-20260624 clang-22
x86_64 buildonly-randconfig-004-20260624 clang-22
x86_64 buildonly-randconfig-005-20260624 clang-22
x86_64 buildonly-randconfig-006-20260624 clang-22
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001 clang-22
x86_64 randconfig-001-20260624 clang-22
x86_64 randconfig-002 clang-22
x86_64 randconfig-002-20260624 clang-22
x86_64 randconfig-003 clang-22
x86_64 randconfig-003-20260624 clang-22
x86_64 randconfig-004 clang-22
x86_64 randconfig-004-20260624 clang-22
x86_64 randconfig-005 clang-22
x86_64 randconfig-005-20260624 clang-22
x86_64 randconfig-006 clang-22
x86_64 randconfig-006-20260624 clang-22
x86_64 randconfig-011-20260624 gcc-14
x86_64 randconfig-012-20260624 gcc-14
x86_64 randconfig-013-20260624 gcc-14
x86_64 randconfig-014-20260624 gcc-14
x86_64 randconfig-015-20260624 gcc-14
x86_64 randconfig-016-20260624 gcc-14
x86_64 randconfig-071-20260624 gcc-14
x86_64 randconfig-072-20260624 clang-22
x86_64 randconfig-072-20260624 gcc-14
x86_64 randconfig-073-20260624 gcc-14
x86_64 randconfig-074-20260624 clang-22
x86_64 randconfig-074-20260624 gcc-14
x86_64 randconfig-075-20260624 gcc-14
x86_64 randconfig-076-20260624 clang-22
x86_64 randconfig-076-20260624 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig clang-20
xtensa randconfig-001-20260624 gcc-14.3.0
xtensa randconfig-002-20260624 gcc-14.3.0
xtensa randconfig-002-20260624 gcc-16.1.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [dtor-input:for-linus] BUILD SUCCESS 7a0e692a0381254b2f77c54dec100cd3325a6fdf
From: kernel test robot @ 2026-06-24 4:40 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
branch HEAD: 7a0e692a0381254b2f77c54dec100cd3325a6fdf Merge branch 'next' into for-linus
elapsed time: 722m
configs tested: 195
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc defconfig gcc-16.1.0
arc randconfig-001-20260624 gcc-15.2.0
arc randconfig-002-20260624 gcc-15.2.0
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001-20260624 gcc-15.2.0
arm randconfig-002-20260624 gcc-15.2.0
arm randconfig-003-20260624 gcc-15.2.0
arm randconfig-004-20260624 gcc-15.2.0
arm sama5_defconfig gcc-16.1.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260624 clang-21
arm64 randconfig-002-20260624 clang-21
arm64 randconfig-003-20260624 clang-21
arm64 randconfig-004-20260624 clang-21
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260624 clang-21
csky randconfig-002-20260624 clang-21
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260624 gcc-11.5.0
hexagon randconfig-001-20260624 gcc-9.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260624 gcc-11.5.0
hexagon randconfig-002-20260624 gcc-9.5.0
i386 allmodconfig clang-22
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260624 gcc-12
i386 buildonly-randconfig-002-20260624 gcc-12
i386 buildonly-randconfig-003-20260624 gcc-12
i386 buildonly-randconfig-004-20260624 gcc-12
i386 buildonly-randconfig-005-20260624 gcc-12
i386 buildonly-randconfig-006-20260624 gcc-12
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260624 clang-22
i386 randconfig-002-20260624 clang-22
i386 randconfig-003-20260624 clang-22
i386 randconfig-004-20260624 clang-22
i386 randconfig-005-20260624 clang-22
i386 randconfig-006-20260624 clang-22
i386 randconfig-007-20260624 clang-22
i386 randconfig-011-20260624 clang-22
i386 randconfig-012-20260624 clang-22
i386 randconfig-013-20260624 clang-22
i386 randconfig-014-20260624 clang-22
i386 randconfig-015-20260624 clang-22
i386 randconfig-016-20260624 clang-22
i386 randconfig-017-20260624 clang-22
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260624 gcc-11.5.0
loongarch randconfig-001-20260624 gcc-9.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260624 gcc-11.5.0
loongarch randconfig-002-20260624 gcc-9.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k defconfig clang-23
m68k stmark2_defconfig gcc-16.1.0
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allnoconfig clang-23
nios2 defconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260624 gcc-11.5.0
nios2 randconfig-001-20260624 gcc-9.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260624 gcc-11.5.0
nios2 randconfig-002-20260624 gcc-9.5.0
openrisc allmodconfig clang-20
openrisc allnoconfig clang-23
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allyesconfig clang-17
parisc defconfig gcc-16.1.0
parisc randconfig-001-20260624 gcc-16.1.0
parisc randconfig-002-20260624 gcc-16.1.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc asp8347_defconfig clang-23
powerpc fsp2_defconfig gcc-16.1.0
powerpc randconfig-001-20260624 gcc-16.1.0
powerpc randconfig-002-20260624 gcc-16.1.0
powerpc64 randconfig-001-20260624 gcc-16.1.0
powerpc64 randconfig-002-20260624 gcc-16.1.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001 clang-18
riscv randconfig-001-20260624 clang-18
riscv randconfig-002 clang-18
riscv randconfig-002-20260624 clang-18
s390 allmodconfig clang-17
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001 clang-18
s390 randconfig-001-20260624 clang-18
s390 randconfig-002 clang-18
s390 randconfig-002-20260624 clang-18
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allyesconfig clang-17
sh defconfig gcc-14
sh randconfig-001 clang-18
sh randconfig-001-20260624 clang-18
sh randconfig-002 clang-18
sh randconfig-002-20260624 clang-18
sparc allnoconfig clang-23
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260624 gcc-14.3.0
sparc randconfig-002-20260624 gcc-14.3.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260624 gcc-14.3.0
sparc64 randconfig-002-20260624 gcc-14.3.0
um allmodconfig clang-17
um allnoconfig clang-23
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260624 gcc-14.3.0
um randconfig-002-20260624 gcc-14.3.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001-20260624 clang-22
x86_64 buildonly-randconfig-002-20260624 clang-22
x86_64 buildonly-randconfig-003-20260624 clang-22
x86_64 buildonly-randconfig-004-20260624 clang-22
x86_64 buildonly-randconfig-005-20260624 clang-22
x86_64 buildonly-randconfig-006-20260624 clang-22
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001 clang-22
x86_64 randconfig-001-20260624 clang-22
x86_64 randconfig-002 clang-22
x86_64 randconfig-002-20260624 clang-22
x86_64 randconfig-003 clang-22
x86_64 randconfig-003-20260624 clang-22
x86_64 randconfig-004 clang-22
x86_64 randconfig-004-20260624 clang-22
x86_64 randconfig-005 clang-22
x86_64 randconfig-005-20260624 clang-22
x86_64 randconfig-006 clang-22
x86_64 randconfig-006-20260624 clang-22
x86_64 randconfig-011-20260624 gcc-14
x86_64 randconfig-012-20260624 gcc-14
x86_64 randconfig-013-20260624 gcc-14
x86_64 randconfig-014-20260624 gcc-14
x86_64 randconfig-015-20260624 gcc-14
x86_64 randconfig-016-20260624 gcc-14
x86_64 randconfig-071-20260624 gcc-14
x86_64 randconfig-072-20260624 gcc-14
x86_64 randconfig-073-20260624 gcc-14
x86_64 randconfig-074-20260624 gcc-14
x86_64 randconfig-075-20260624 gcc-14
x86_64 randconfig-076-20260624 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allyesconfig clang-20
xtensa randconfig-001-20260624 gcc-14.3.0
xtensa randconfig-002-20260624 gcc-14.3.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v2 2/2] arm64: dts: qcom: sdm845-oneplus: Update compatible to include model
From: Dmitry Torokhov @ 2026-06-24 4:28 UTC (permalink / raw)
To: David Heidelberg
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jason A. Donenfeld, Matthias Schiffer, Vincent Huang,
Bjorn Andersson, Konrad Dybcio, linux-input, devicetree,
linux-kernel, linux-arm-msm, phone-devel, Krzysztof Kozlowski,
Konrad Dybcio
In-Reply-To: <742c7a13-9465-40e8-8990-e679712e9784@ixit.cz>
Hi David,
On Sun, Jun 21, 2026 at 07:11:45PM +0200, David Heidelberg wrote:
> On 28/05/2026 00:13, David Heidelberg wrote:
> > On 27/05/2026 23:56, Dmitry Torokhov wrote:
> > > Hi David,
> > >
> > > On Sat, May 23, 2026 at 11:45:35AM +0200, David Heidelberg via B4 Relay wrote:
> > > > From: David Heidelberg <david@ixit.cz>
> > > >
> > > > We know the driver is reporting s3706b, introduce the compatible so we
> > > > can more easily introduce quirks for weird touchscreen replacements in
> > > > followup series.
> > > >
> > > > Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> > > > Signed-off-by: David Heidelberg <david@ixit.cz>
> > > > ---
> > > > arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 2 +-
> > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > b/arch/ arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > index 6b7378cf4d493..148164d456a5a 100644
> > > > --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > @@ -475,17 +475,17 @@ bq27441_fg: bq27441-battery@55 {
> > > > };
> > > > };
> > > > &i2c12 {
> > > > status = "okay";
> > > > clock-frequency = <400000>;
> > > > synaptics-rmi4-i2c@20 {
> > > > - compatible = "syna,rmi4-i2c";
> > > > + compatible = "syna,rmi4-s3706b", "syna,rmi4-i2c";
> > >
> > > So I believe we established that this device (s3706b) does not in fact
> > > implement rmi4 protocol properly. Why do we have "syna,rmi4-i2c" as a
> > > fallback? Shouldn't it be just "syna,rmi4-s3706b"?
> >
> > The vendor supplies s3706b which does implement the RMI4 properly.
> >
> > The 3rd party replacement impersonating original parts may not implement
> > it properly, but I don't address this issue in this initial submission.
> >
> > With this compatible we know which original part is used by the vendor
> > and installed in the phones, so later we can deduct specific sequences
> > for the replacement aftermarket parts to keep phone touchscreen working
> > same as they do on Android without affecting other devices.
>
> Hello Dmitry.
>
> May I ask what is currently preventing this series from moving forward?
>
> The first version was posted in 2023 [1]. I picked it up again in 2025 [2]
> and am now on the 9th iteration (this patchset). At this point, the series
> has been under discussion for well over a year, with relatively little
> feedback and increasingly long gaps between review rounds.
>
> The current approach is based on the guidance I have received so far,
> including suggestions from the device-tree maintainers. When concerns were
> raised, I tried to address them and rework the series accordingly.
>
> What I am struggling with is understanding what specific issue still needs
> to be resolved before these patches can be accepted. If there are remaining
> requirements, objections to the approach, or technical concerns that I have
> not addressed, I would appreciate having them stated explicitly so I can
> work on them.
>
> I also split out the straightforward, self-contained changes in the hope
> that at least those could progress independently while I continued working
> on any follow-up requirements. However, even those patches do not appear to
> be moving forward.
>
> Could you please clarify what outcome you would like to see from this
> series, and what concrete changes would be required to get it accepted?
I am still confused about how you want to differentiate between the full
RMI4 support vs the OnePlus flavor. The "syna,rmi4-s3706b", as you
mentioned, implements RMI4 protocol properly, so we do not need to
actually have it documented neither in binding nor in DTS.
The issue you have with after-market parts that are not compliant and we
need to figure out how to deal with them. Inside the driver I
essentially need a"incomplete protocol" flag that we can use to
implement additional checks or skip known to be not implemented
functions/queries. In DT we could introduce something like
"oneplus,rmi4-i2c" that is decidedly not compatible with "syna,rmi4-i2c"
and neither one should be a fallback for the other.
This of course needs buy-in from DT maintainers.
Does this make sense?
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: mtk-pmic-keys: Count available keys during probe instead of pre-counting
From: Dmitry Torokhov @ 2026-06-24 4:14 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-input, Matthias Brugger, AngeloGioacchino Del Regno,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
In-Reply-To: <20260528235600.312045-1-rosenp@gmail.com>
Hi Rosen,
On Thu, May 28, 2026 at 04:56:00PM -0700, Rosen Penev wrote:
> Replace the separate of_get_available_child_count() pre-count and
> validation step with a single pass through for_each_child_of_node_scoped().
> Skip unavailable child nodes and bail out if more than
> MTK_PMIC_MAX_KEY_COUNT available keys are found. Set nkeys after the
> loop so suspend/resume iterate only over initialized entries.
>
> Also use a key variable in the loop for clarity.
>
> Use of_device_get_match_data() to fetch the PMIC key register data directly
> instead of open-coding an of_match_device() lookup.
Please split this out into a separate patch.
>
> This also lets the driver drop the of_device.h include.
>
> Assisted-by: OpenCode:BigPickle
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/input/keyboard/mtk-pmic-keys.c | 53 ++++++++++++--------------
> 1 file changed, 24 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
> index c78d9f6d97c4..e34856693ee2 100644
> --- a/drivers/input/keyboard/mtk-pmic-keys.c
> +++ b/drivers/input/keyboard/mtk-pmic-keys.c
> @@ -16,7 +16,6 @@
> #include <linux/mfd/mt6397/core.h>
> #include <linux/mfd/mt6397/registers.h>
> #include <linux/module.h>
> -#include <linux/of_device.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/regmap.h>
> @@ -147,6 +146,7 @@ struct mtk_pmic_keys {
> struct input_dev *input_dev;
> struct device *dev;
> struct regmap *regmap;
> + unsigned int nkeys;
> struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT];
> };
>
> @@ -267,7 +267,7 @@ static int mtk_pmic_keys_suspend(struct device *dev)
> struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
> int index;
>
> - for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
> + for (index = 0; index < keys->nkeys; index++) {
> if (keys->keys[index].wakeup) {
> enable_irq_wake(keys->keys[index].irq);
> if (keys->keys[index].irq_r > 0)
> @@ -283,7 +283,7 @@ static int mtk_pmic_keys_resume(struct device *dev)
> struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
> int index;
>
> - for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
> + for (index = 0; index < keys->nkeys; index++) {
> if (keys->keys[index].wakeup) {
> disable_irq_wake(keys->keys[index].irq);
> if (keys->keys[index].irq_r > 0)
> @@ -325,24 +325,23 @@ MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl);
> static int mtk_pmic_keys_probe(struct platform_device *pdev)
> {
> int error, index = 0;
> - unsigned int keycount;
> struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
> struct device_node *node = pdev->dev.of_node;
> static const char *const irqnames[] = { "powerkey", "homekey" };
> static const char *const irqnames_r[] = { "powerkey_r", "homekey_r" };
> struct mtk_pmic_keys *keys;
> const struct mtk_pmic_regs *mtk_pmic_regs;
> + struct mtk_pmic_keys_info *key;
> struct input_dev *input_dev;
> - const struct of_device_id *of_id =
> - of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev);
>
> keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL);
> if (!keys)
> return -ENOMEM;
> -
> keys->dev = &pdev->dev;
> keys->regmap = pmic_chip->regmap;
> - mtk_pmic_regs = of_id->data;
> + mtk_pmic_regs = of_device_get_match_data(&pdev->dev);
> + if (!mtk_pmic_regs)
> + return -EINVAL;
>
> keys->input_dev = input_dev = devm_input_allocate_device(keys->dev);
> if (!input_dev) {
> @@ -356,31 +355,26 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
> input_dev->id.product = 0x0001;
> input_dev->id.version = 0x0001;
>
> - keycount = of_get_available_child_count(node);
> - if (keycount > MTK_PMIC_MAX_KEY_COUNT ||
> - keycount > ARRAY_SIZE(irqnames)) {
> - dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
> - return -EINVAL;
> - }
> + for_each_available_child_of_node_scoped(node, child) {
Let's keep using for_each_child_of_node_scoped() and check
of_device_is_available() inside the loop. This will allow marking a key
as disabled without shifting it's meaning (power key vs home key).
In the rest of the driver we should be able to determine if key is set
up checking for key->irq > 0.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] HID: core: Expose id attributes in sysfs
From: Vicki Pfau @ 2026-06-24 2:36 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau
udev rules for handling input devices generally match on idVendor and
idProduct for USB hidraw or id/vendor and id/product for evdev nodes.
However, hidraw nodes that aren't created by the USB subsystem will only
expose this information to udev via the kernel path itself. This leads to
doing substring matching, which can be error-prone or overzealous. Instead,
since the HID subsystem already has this information, we can expose it
directly in the same format that evdev exposes it.
Signed-off-by: Vicki Pfau <vi@endrift.com>
---
drivers/hid/hid-core.c | 45 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 41a79e43c82b..397de63297c6 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2900,6 +2900,45 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
}
static DEVICE_ATTR_RO(modalias);
+/*
+ * Expose this as bustype instead of bus as
+ * that's the name the input subsystem uses
+ */
+static ssize_t bustype_show(struct device *dev, struct device_attribute *a,
+ char *buf)
+{
+ struct hid_device *hdev = to_hid_device(dev);
+
+ return sysfs_emit(buf, "%04x\n", hdev->bus);
+}
+static DEVICE_ATTR_RO(bustype);
+
+#define HID_DEV_ID_ATTR(name) \
+static ssize_t name##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct hid_device *hdev = to_hid_device(dev); \
+ \
+ return sysfs_emit(buf, "%04x\n", hdev->name); \
+} \
+static DEVICE_ATTR_RO(name)
+
+HID_DEV_ID_ATTR(vendor);
+HID_DEV_ID_ATTR(product);
+HID_DEV_ID_ATTR(version);
+
+static struct attribute *hid_dev_id_attrs[] = {
+ &dev_attr_bustype.attr,
+ &dev_attr_vendor.attr,
+ &dev_attr_product.attr,
+ &dev_attr_version.attr,
+ NULL
+};
+static const struct attribute_group hid_dev_id_attr_group = {
+ .name = "id",
+ .attrs = hid_dev_id_attrs,
+};
static struct attribute *hid_dev_attrs[] = {
&dev_attr_modalias.attr,
NULL,
@@ -2912,7 +2951,11 @@ static const struct attribute_group hid_dev_group = {
.attrs = hid_dev_attrs,
.bin_attrs = hid_dev_bin_attrs,
};
-__ATTRIBUTE_GROUPS(hid_dev);
+static const struct attribute_group *hid_dev_groups[] = {
+ &hid_dev_group,
+ &hid_dev_id_attr_group,
+ NULL
+};
static int hid_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
--
2.54.0
^ permalink raw reply related
* [git pull] Input updates for v7.2-rc0
From: Dmitry Torokhov @ 2026-06-24 2:21 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, linux-input
Hi Linus,
Please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v7.2-rc0
to receive updates for the input subsystem. You will get:
- A new driver for Wacom W9000-series penabled touchscreens
- Updates to STM FTS driver adding support for reset line and preparing
the driver for STMFTS5 support
- Updates to RMI4 and IMS PCU drivers hardening the code
- Support for half-duplex mode restored in ADS7846 driver
- Updates to driver's device_id tables to use named initializers
- Removal of no longer used PCAP keys and touchscreen drivers (support
for the ezx series of phones was removed in 2022)
- Removal of xilinx_ps2 driver which is no longer used either
- Updates to userio to allow setting up additional serio port
characteristics (such as id, extra and proto)
- Assorted hardening and cleanup fixes for other drivers.
Changelog:
---------
Aaro Koskinen (1):
Input: ads7846 - restore half-duplex support
Arnd Bergmann (2):
Input: pcap_keys - remove unused driver
Input: pcap_ts - remove unused driver
Bryam Vargas (4):
Input: touchwin - reset the packet index on every complete packet
Input: mms114 - reject an oversized device packet size
Input: goodix - clamp the device-reported contact count
Input: iforce - bound the device-reported force-feedback effect index
Colin Ian King (1):
Input: lm8323 - remove space before newline
David Heidelberg (6):
Input: stmfts - fix the MODULE_LICENSE() string
Input: stmfts - use dev struct directly
Input: stmfts - switch to devm_regulator_bulk_get_const
Input: stmfts - abstract reading information from the firmware
Input: stmfts - disable regulators and disable irq when power on fails
dt-bindings: input: touchscreen: st,stmfts: Introduce reset GPIO
Dmitry Torokhov (40):
Input: stmfts - fix formatting issues
Input: atmel_mxt_ts - use __free() for obuf in mxt_object_show
Input: atlas_btns - modernize the driver
Input: ims-pcu - only expose sysfs attributes on control interface
Input: ims-pcu - fix logic error in packet reset
Input: ims-pcu - release data interface on disconnect
Input: ims-pcu - fix use-after-free and double-free in disconnect
Input: ims-pcu - fix type confusion in CDC union descriptor parsing
Input: ims-pcu - fix firmware leak in async update
Input: ims-pcu - fix race condition in reset_device sysfs callback
Input: ims-pcu - validate control endpoint type
Input: ims-pcu - fix out-of-bounds read in ims_pcu_irq() debug logging
Input: ims-pcu - fix DMA mapping violation in line setup
Input: ims-pcu - add response length checks
Input: ims-pcu - fix potential infinite loop in CDC union descriptor parsing
Input: ipaq-micro-keys - fix potential deadlock
Input: ipaq-micro-keys - add length check in micro_key_receive
Input: rmi4 - fix register descriptor address calculation
Input: rmi4 - refactor register descriptor parsing
Input: rmi4 - fix type overflow in register counts
Input: rmi4 - fix num_subpackets overflow in register descriptor
Input: rmi4 - initialize attn_fifo properly
Input: rmi4 - fix memory leak in rmi_set_attn_data()
Input: rmi4 - iterative IRQ handler
Input: rmi4 - fix bit count in bitmap_copy()
Input: rmi4 - fix limit in rmi_register_desc_has_subpacket()
Input: rmi4 - use local presence map in rmi_read_register_desc()
Input: rmi4 - refactor function allocation and registration
Input: rmi4 - use kzalloc_flex() for struct rmi_function
Input: rmi4 - refactor F12 probe function
Input: rmi4 - change reg_size type to u32
Input: rmi4 - use unaligned access helpers in F12
Input: rmi4 - use flexible array member for IRQ masks in F12
Input: rmi4 - use devm_kmalloc for F12 data packet buffer
Input: rmi4 - use sizeof(*ptr) and idiomatic checks in f12 allocators
Input: rmi4 - simplify size calculations in F12
Input: rmi4 - propagate proper error code in F12 sensor tuning
Input: rmi4 - update formatting in F12
Input: stop force-feedback timer when unregistering input devices
Input: mms114 - fix touch indexing for MMS134S and MMS136
Elliot Tester (1):
Input: remove changelogs
Haoxiang Li (1):
Input: synaptics-rmi4 - unregister function handlers on physical driver registration failure
Hendrik Noack (2):
dt-bindings: Input: Add Wacom W9000-series penabled touchscreens
Input: Add support for Wacom W9000-series penabled touchscreens
Kris Bahnsen (1):
Input: ads7846 - don't use scratch for tx_buf when clearing register
Petr Hodina (2):
Input: stmfts - use client to make future code cleaner
Input: stmfts - add optional reset GPIO support
Ranjan Kumar (1):
Input: elan_i2c - prevent division by zero and arithmetic underflow
Ricardo Ribalda (1):
Input: atmel_mxt_ts - set byte_offset as signed
Rosen Penev (3):
Input: xilinx_ps2 - remove driver
Input: apbps2 - simplify resource mapping and IRQ retrieval
Input: ipaq-micro-keys - simplify allocation
Uwe Kleine-König (The Capable Hub) (3):
Input: Use named initializers for arrays of i2c_device_data
Input: iqs5xx - drop unused i2c driver_data
Input: Drop unused assignments from pnp_device_id arrays
Vicki Pfau (2):
Input: userio - update maintainer name
Input: userio - allow setting other id values
Yuki Horii (1):
Input: tsc2007 - reduce I2C transactions for Z2 read
Diffstat:
--------
.../bindings/input/touchscreen/st,stmfts.yaml | 4 +
.../input/touchscreen/wacom,w9007a-lt03.yaml | 73 ++++
Documentation/input/userio.rst | 25 +-
MAINTAINERS | 2 +-
drivers/input/ff-memless.c | 27 +-
drivers/input/gameport/ns558.c | 46 +--
drivers/input/input.c | 3 +
drivers/input/joystick/adafruit-seesaw.c | 2 +-
drivers/input/joystick/as5011.c | 2 +-
drivers/input/joystick/iforce/iforce-packets.c | 18 +-
drivers/input/joystick/qwiic-joystick.c | 2 +-
drivers/input/keyboard/adp5588-keys.c | 4 +-
drivers/input/keyboard/cap11xx.c | 14 +-
drivers/input/keyboard/cypress-sf.c | 2 +-
drivers/input/keyboard/dlink-dir685-touchkeys.c | 2 +-
drivers/input/keyboard/ipaq-micro-keys.c | 24 +-
drivers/input/keyboard/lm8323.c | 4 +-
drivers/input/keyboard/lm8333.c | 2 +-
drivers/input/keyboard/max7359_keypad.c | 2 +-
drivers/input/keyboard/mpr121_touchkey.c | 2 +-
drivers/input/keyboard/qt1070.c | 2 +-
drivers/input/keyboard/qt2160.c | 2 +-
drivers/input/keyboard/tca8418_keypad.c | 2 +-
drivers/input/keyboard/tm2-touchkey.c | 2 +-
drivers/input/misc/Kconfig | 10 -
drivers/input/misc/Makefile | 1 -
drivers/input/misc/ad714x-i2c.c | 10 +-
drivers/input/misc/adxl34x-i2c.c | 2 +-
drivers/input/misc/apanel.c | 2 +-
drivers/input/misc/atlas_btns.c | 109 ++---
drivers/input/misc/atmel_captouch.c | 2 +-
drivers/input/misc/bma150.c | 6 +-
drivers/input/misc/cma3000_d0x_i2c.c | 2 +-
drivers/input/misc/da7280.c | 2 +-
drivers/input/misc/drv260x.c | 8 +-
drivers/input/misc/drv2665.c | 2 +-
drivers/input/misc/drv2667.c | 2 +-
drivers/input/misc/ims-pcu.c | 131 +++++-
drivers/input/misc/kxtj9.c | 2 +-
drivers/input/misc/mma8450.c | 2 +-
drivers/input/misc/pcap_keys.c | 125 ------
drivers/input/misc/pcf8574_keypad.c | 2 +-
drivers/input/misc/yealink.c | 9 -
drivers/input/mouse/cyapa.c | 2 +-
drivers/input/mouse/elan_i2c_core.c | 38 +-
drivers/input/mouse/synaptics_i2c.c | 2 +-
drivers/input/rmi4/rmi_2d_sensor.h | 4 +-
drivers/input/rmi4/rmi_bus.c | 34 +-
drivers/input/rmi4/rmi_bus.h | 1 +
drivers/input/rmi4/rmi_driver.c | 204 ++++++----
drivers/input/rmi4/rmi_driver.h | 13 +-
drivers/input/rmi4/rmi_f11.c | 2 +-
drivers/input/rmi4/rmi_f12.c | 415 +++++++++----------
drivers/input/rmi4/rmi_i2c.c | 2 +-
drivers/input/rmi4/rmi_smbus.c | 2 +-
drivers/input/serio/Kconfig | 10 -
drivers/input/serio/Makefile | 1 -
drivers/input/serio/apbps2.c | 7 +-
drivers/input/serio/i8042-acpipnpio.h | 56 +--
drivers/input/serio/userio.c | 34 +-
drivers/input/serio/xilinx_ps2.c | 363 -----------------
drivers/input/tablet/aiptek.c | 31 --
drivers/input/touchscreen/Kconfig | 22 +-
drivers/input/touchscreen/Makefile | 2 +-
drivers/input/touchscreen/ad7879-i2c.c | 4 +-
drivers/input/touchscreen/ads7846.c | 173 +++++++-
drivers/input/touchscreen/ar1021_i2c.c | 2 +-
drivers/input/touchscreen/atmel_mxt_ts.c | 23 +-
drivers/input/touchscreen/auo-pixcir-ts.c | 2 +-
drivers/input/touchscreen/bu21013_ts.c | 2 +-
drivers/input/touchscreen/bu21029_ts.c | 2 +-
drivers/input/touchscreen/cy8ctma140.c | 2 +-
drivers/input/touchscreen/cy8ctmg110_ts.c | 2 +-
drivers/input/touchscreen/cyttsp5.c | 2 +-
drivers/input/touchscreen/cyttsp_i2c.c | 2 +-
drivers/input/touchscreen/eeti_ts.c | 2 +-
drivers/input/touchscreen/egalax_ts.c | 2 +-
drivers/input/touchscreen/elants_i2c.c | 6 +-
drivers/input/touchscreen/exc3000.c | 8 +-
drivers/input/touchscreen/goodix.c | 5 +-
drivers/input/touchscreen/hideep.c | 2 +-
drivers/input/touchscreen/himax_hx83112b.c | 4 +-
drivers/input/touchscreen/hynitron-cst816x.c | 2 +-
drivers/input/touchscreen/ili210x.c | 8 +-
drivers/input/touchscreen/ilitek_ts_i2c.c | 2 +-
drivers/input/touchscreen/iqs5xx.c | 6 +-
drivers/input/touchscreen/max11801_ts.c | 2 +-
drivers/input/touchscreen/melfas_mip4.c | 2 +-
drivers/input/touchscreen/migor_ts.c | 2 +-
drivers/input/touchscreen/mms114.c | 26 +-
drivers/input/touchscreen/novatek-nvt-ts.c | 4 +-
drivers/input/touchscreen/pcap_ts.c | 252 ------------
drivers/input/touchscreen/pixcir_i2c_ts.c | 4 +-
drivers/input/touchscreen/raydium_i2c_ts.c | 4 +-
drivers/input/touchscreen/rohm_bu21023.c | 2 +-
drivers/input/touchscreen/s6sy761.c | 2 +-
drivers/input/touchscreen/silead.c | 12 +-
drivers/input/touchscreen/sis_i2c.c | 4 +-
drivers/input/touchscreen/st1232.c | 4 +-
drivers/input/touchscreen/stmfts.c | 162 +++++---
drivers/input/touchscreen/touchwin.c | 15 +-
drivers/input/touchscreen/tsc2004.c | 2 +-
drivers/input/touchscreen/tsc2007_core.c | 8 +-
drivers/input/touchscreen/wacom_i2c.c | 2 +-
drivers/input/touchscreen/wacom_w9000.c | 444 +++++++++++++++++++++
drivers/input/touchscreen/wdt87xx_i2c.c | 2 +-
drivers/input/touchscreen/zet6223.c | 2 +-
drivers/input/touchscreen/zforce_ts.c | 2 +-
include/linux/input.h | 3 +
include/uapi/linux/userio.h | 7 +-
110 files changed, 1673 insertions(+), 1501 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/touchscreen/wacom,w9007a-lt03.yaml
delete mode 100644 drivers/input/misc/pcap_keys.c
delete mode 100644 drivers/input/serio/xilinx_ps2.c
delete mode 100644 drivers/input/touchscreen/pcap_ts.c
create mode 100644 drivers/input/touchscreen/wacom_w9000.c
Thanks.
--
Dmitry
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox