* Re: [PATCH v3 1/2] Input: atmel_mxt_ts: Fix async config use-after-free
From: sashiko-bot @ 2026-05-28 8:48 UTC (permalink / raw)
To: Hendrik Noack; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260528074317.9604-1-hendrik-noack@gmx.de>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Low] The `shutting_down` flag and `complete_all()` logic introduced to serialize shutdown are completely unreachable dead code and contain misleading logging.
Pre-existing issues:
- [High] Concurrent sysfs operations lack synchronization, leading to severe use-after-free and double-free vulnerabilities.
- [High] The `wait_for_completion(&data->config_completion)` in `mxt_initialize()` is placed too late, failing to protect against concurrent execution with the firmware callback when triggered via sysfs.
- [High] Accessing the `update_fw` sysfs attribute before probe completes leads to a NULL pointer dereference.
--
commit f95104521ff6a213450d681f2eb88830307206ae
Author: Hendrik Noack <hendrik-noack@gmx.de>
Input: atmel_mxt_ts: Fix async config use-after-free
The driver starts asynchronous config loading from probe and sysfs. If the
driver is removed while a request is pending, devres frees mxt_data, leading
to a use-after-free in the callback. The patch introduces a completion to
serialize request_firmware_nowait() and remove().
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index a9e86ad7ed5ef..a88dc7e6827c7 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
[ ... ]
> @@ -2271,12 +2278,26 @@ static int mxt_initialize(struct mxt_data *data)
> if (error)
> return error;
>
> + wait_for_completion(&data->config_completion);
[Severity: High]
This is a pre-existing issue, but does wait_for_completion() happen too late
here to protect against concurrent execution with the firmware callback when
triggered via sysfs?
When mxt_update_fw_store() is invoked, it first calls mxt_load_fw(), which
clears data->info via mxt_free_object_table(), before mxt_initialize() is
even called.
It then calls mxt_initialize(), which waits for the completion. However, if
a previously initiated mxt_config_cb() is executing concurrently, it uses
data->info inside mxt_configure_objects().
Since mxt_load_fw() frees and clears this pointer without waiting for the
async callback to finish, mxt_config_cb() will suffer a null pointer
dereference or use-after-free. The wait seems placed too late to prevent
this sysfs race.
[Severity: High]
This is a pre-existing issue, but do concurrent sysfs operations lack
synchronization?
The driver exposes sysfs attributes like update_fw without internal
serialization. The sysfs framework permits multiple threads to write to the
same attribute concurrently.
mxt_update_fw_store() directly invokes mxt_load_fw(), which destructively
modifies device state by calling mxt_free_object_table().
Without a mutex protecting this path, concurrent writes to update_fw will
cause multiple threads to enter these teardown functions simultaneously,
leading to a double free of data->raw_info_block and data->msg_buf.
> +
> + if (data->shutting_down) {
> + /* complete() only signals one waiter, signal all waiters once during shutdown */
> + if (!completion_done(&data->config_completion)) {
> + complete_all(&data->config_completion);
> + dev_info(&client->dev, "Shutting down, not loading new config: %d\n",
> + error);
[Severity: Low]
Is this block actually reachable? mxt_initialize() is only invoked by
mxt_probe() and the sysfs attribute mxt_update_fw_store().
The driver core strictly serializes mxt_probe() and mxt_remove() via the
device lock. For the sysfs path, the driver core drains active sysfs
operations via device_remove_groups() before invoking the bus remove()
callback (which calls mxt_remove()).
Because of this, it seems mxt_initialize() and mxt_remove() can never run
concurrently.
Also, error here is mathematically guaranteed to be 0 since we just passed
if (error) return error, making the log message semantically misleading.
> + }
> +
> + return -EBUSY;
> + }
> +
[ ... ]
> @@ -3237,6 +3258,9 @@ static int mxt_probe(struct i2c_client *client)
> init_completion(&data->bl_completion);
> init_completion(&data->reset_completion);
> init_completion(&data->crc_completion);
> + init_completion(&data->config_completion);
> + complete(&data->config_completion);
> + data->shutting_down = false;
[Severity: High]
This is a pre-existing issue, but could accessing the update_fw sysfs
attribute before probe completes lead to a null pointer dereference?
Sysfs attributes defined via mxt_driver.driver.dev_groups are registered by
the driver core (device_add_groups()) before the driver's probe function is
called.
An early write to update_fw during this window executes
mxt_update_fw_store() before i2c_set_clientdata() is called in mxt_probe().
In this scenario, dev_get_drvdata(dev) returns a null pointer, which is then
immediately dereferenced in mxt_load_fw():
drivers/input/touchscreen/atmel_mxt_ts.c:mxt_load_fw() {
...
if (!data->in_bootloader) {
...
}
Would this cause a kernel panic?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528074317.9604-1-hendrik-noack@gmx.de?part=1
^ permalink raw reply
* Re: [PATCH v8 7/7] power: supply: Add charger driver for Asus Transformers
From: sashiko-bot @ 2026-05-28 8:58 UTC (permalink / raw)
To: Svyatoslav Ryhel; +Cc: robh, dmitry.torokhov, conor+dt, linux-input, devicetree
In-Reply-To: <20260528053203.9339-8-clamor95@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Strict equality check on `action` bitmask may cause dropped events.
--
commit 55ed27a4bfa91a64727ac41721ebdb9163ebef2a
Author: Michał Mirosław <mirq-linux@rere.qmqm.pl>
power: supply: Add charger driver for Asus Transformers
This commit adds a new driver to support charger detection capabilities
provided by the embedded controller on ASUS Transformer devices. It
reports properties like USB type, charging behaviour, and online status.
> diff --git a/drivers/power/supply/asus-transformer-ec-charger.c b/drivers/power/supply/asus-transformer-ec-charger.c
> new file mode 100644
> index 0000000000000..c7a6bd2ba533f
> --- /dev/null
> +++ b/drivers/power/supply/asus-transformer-ec-charger.c
[ ... ]
> +static int asus_ec_charger_notify(struct notifier_block *nb,
> + unsigned long action, void *data)
> +{
> + struct asus_ec_charger_data *priv =
> + container_of(nb, struct asus_ec_charger_data, nb);
> +
> + switch (action) {
> + case ASUSEC_SMI_ACTION(POWER_NOTIFY):
> + case ASUSEC_SMI_ACTION(ADAPTER_EVENT):
[Severity: Medium]
Will this strict equality check cause charger events to be dropped if multiple
interrupt flags are set simultaneously?
The action parameter appears to be constructed by the parent MFD driver by
taking the raw ASUSEC_IRQ_STATUS byte and OR'ing it with the SMI code shifted
by 8 bits. Since ASUSEC_IRQ_STATUS is a bitmask, if an SMI event occurs
concurrently with another event (such as a keyboard press), the action bitmask
will contain additional bits.
Could this strict switch check be replaced by checking the ASUSEC_SMI_MASK with
a bitwise AND operation, and then evaluating the SMI code separately?
> + power_supply_changed(priv->psy);
> + break;
> + }
> +
> + return NOTIFY_DONE;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528053203.9339-1-clamor95@gmail.com?part=7
^ permalink raw reply
* Re: [PATCH v8 2/2] Input: Add support for Wacom W9000-series penabled touchscreens
From: sashiko-bot @ 2026-05-28 9:01 UTC (permalink / raw)
To: Hendrik Noack; +Cc: robh, conor+dt, devicetree, dmitry.torokhov, linux-input
In-Reply-To: <20260528074818.12151-3-hendrik-noack@gmx.de>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The driver uses stack-allocated buffers for I2C transfers, which violates the DMA API and can cause panics or memory corruption.
--
commit 5c60cba7d031762dd1ed0e3769ce031bf93c9b48
Author: Hendrik Noack <hendrik-noack@gmx.de>
Input: Add support for Wacom W9000-series penabled touchscreens
This commit adds a new input driver for the Wacom W9000-series penabled
touchscreens, supporting passive Wacom pens over an I2C interface.
> diff --git a/drivers/input/touchscreen/wacom_w9000.c b/drivers/input/touchscreen/wacom_w9000.c
> new file mode 100644
> index 0000000000000..7795508f93b29
> --- /dev/null
> +++ b/drivers/input/touchscreen/wacom_w9000.c
[ ... ]
> +static int wacom_w9000_read(struct i2c_client *client, u8 command, u8 len, u8 *data)
> +{
> + int error, res;
> + struct i2c_msg msg[] = {
> + {
> + .addr = client->addr,
> + .flags = 0,
> + .buf = &command,
> + .len = sizeof(command),
[Severity: High]
Is it safe to pass a stack-allocated variable (&command) as an I2C transfer
buffer?
If the underlying I2C adapter uses DMA, transferring from a stack address
can lead to kernel panics or silent memory corruption. This happens because
stack memory is often virtually mapped (when CONFIG_VMAP_STACK is enabled)
and is not guaranteed to be safely cacheline aligned.
Would it be better to allocate these buffers dynamically or embed a
DMA-safe buffer inside the wacom_w9000_data structure?
> + }, {
> + .addr = client->addr,
> + .flags = I2C_M_RD,
> + .buf = data,
> + .len = len,
> + }
> + };
> +
> + res = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
> + if (res != ARRAY_SIZE(msg)) {
> + error = res < 0 ? res : -EIO;
> + dev_err(&client->dev, "%s: i2c transfer failed: %d (%d)\n", __func__, error, res);
> + return error;
> + }
> +
> + return 0;
> +}
> +
> +static int wacom_w9000_query(struct wacom_w9000_data *wacom_data)
> +{
> + struct i2c_client *client = wacom_data->client;
> + struct device *dev = &wacom_data->client->dev;
> + int error;
> + int retry = 0;
> + u8 data[CMD_QUERY_NUM_MAX];
[Severity: High]
Similarly, does passing this stack-allocated array down to wacom_w9000_read()
violate the DMA API requirements for the same reasons?
> +
> + for (; retry < CMD_QUERY_RETRIES; retry++) {
> + error = wacom_w9000_read(client, CMD_QUERY, wacom_data->variant->cmd_query_num,
> + data);
[ ... ]
> +static void wacom_w9000_coord(struct wacom_w9000_data *wacom_data)
> +{
> + struct i2c_client *client = wacom_data->client;
> + struct device *dev = &wacom_data->client->dev;
> + int error;
> + u8 data[MSG_COORD_NUM_MAX];
> + bool touch, rubber, side_button;
> + u16 x, y, pressure;
> + u8 distance = 0;
> +
> + error = i2c_master_recv(client, data, wacom_data->variant->msg_coord_num);
[Severity: High]
Can this call to i2c_master_recv() corrupt memory by DMAing into the
stack-allocated data array? Using a dedicated buffer allocated with kzalloc
or similar might prevent this issue on the coordinate data path.
> + if (error != wacom_data->variant->msg_coord_num) {
> + if (error >= 0)
> + error = -EIO;
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528074818.12151-1-hendrik-noack@gmx.de?part=2
^ permalink raw reply
* Re: [PATCH v3 2/2] Input: atmel_mxt_ts: Allow per-machine config via DT compatible
From: sashiko-bot @ 2026-05-28 9:28 UTC (permalink / raw)
To: Hendrik Noack; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260528074317.9604-2-hendrik-noack@gmx.de>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Concurrent execution of 'mxt_load_fw' via the 'update_fw' sysfs attribute lacks locking, leading to double-free of the input device, TOCTOU races, and interleaved I2C commands.
--
commit eb7b8b6b98800084b750dc1b902ad664e878e3d8
Author: Hendrik Noack <hendrik-noack@gmx.de>
Input: atmel_mxt_ts: Allow per-machine config via DT compatible
The Atmel maXTouch config is machine-dependent, different panels and
layouts require different configs even when the same controller and
firmware is used.
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index a88dc7e6827c7..5ac123d4ed036 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
[ ... ]
> @@ -2291,12 +2351,9 @@ static int mxt_initialize(struct mxt_data *data)
> return -EBUSY;
> }
>
> - error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
> - &client->dev, GFP_KERNEL, data,
> - mxt_config_cb);
> + error = mxt_invoke_config_loader(data, true);
> if (error) {
> - dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
> - error);
> + dev_err(&client->dev, "Failed to invoke config loader: %d\n", error);
> complete(&data->config_completion);
> return error;
> }
[Severity: High]
This is a pre-existing issue, but I noticed that mxt_update_fw_store()
invokes mxt_load_fw() without any locking to serialize concurrent execution.
Since sysfs write operations don't hold a global lock like device_lock,
could multiple threads concurrently writing to the update_fw attribute race
when checking and setting data->in_bootloader?
If so, could both threads concurrently execute mxt_free_input_device(),
observe a non-null data->input_dev, and invoke input_unregister_device() on
the same pointer before it is set to NULL?
This seems like it might lead to a double-free or use-after-free since
input_unregister_device() drops the reference count.
Could this also race with PM callbacks like mxt_suspend() attempting to
acquire input_dev->mutex, operating on freed memory if
mxt_free_input_device() is executed concurrently?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528074317.9604-1-hendrik-noack@gmx.de?part=2
^ permalink raw reply
* Re: [PATCH v2 3/7] platform/surface: SAM: Add support for Surface Pro 12in
From: Ilpo Järvinen @ 2026-05-28 12:42 UTC (permalink / raw)
To: Harrison Vanderbyl
Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, Herbert Xu,
davem, neil.armstrong, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, jikos, bentiss, luzmaximilian, Hans de Goede,
Douglas Anderson, Jessica Zhang, linux-arm-msm, devicetree, LKML,
linux-crypto, dri-devel, linux-input, platform-driver-x86
In-Reply-To: <ab458aadea651396d9ea7629419a32dc7510c593.1778822464.git.harrison.vanderbyl@gmail.com>
On Fri, 15 May 2026, Harrison Vanderbyl wrote:
> Add a SAM client device node group and registry entry for the
> Microsoft Surface Pro, 12-inch with Snapdragon.
>
> This set enables the use of the following devices.
> 1: cover keyboard
> 2: cover touchpad
> 3: pen stash events.
>
> The battery info and charger info devices have been
> purposefully omitted as they are also reported by
> other drivers and cause conflicts.
>
> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl@gmail.com>
> ---
> .../surface/surface_aggregator_registry.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
> index 0599d5adf02e..884049961415 100644
> --- a/drivers/platform/surface/surface_aggregator_registry.c
> +++ b/drivers/platform/surface/surface_aggregator_registry.c
> @@ -422,6 +422,19 @@ static const struct software_node *ssam_node_group_sp11[] = {
> NULL,
> };
>
> +/* Devices for Surface Pro 12" first edition (ARM/QCOM) */
> +static const struct software_node *ssam_node_group_sp12in[] = {
> + &ssam_node_root,
> + &ssam_node_hub_kip,
> + &ssam_node_tmp_sensors,
> + &ssam_node_hid_kip_keyboard,
> + &ssam_node_hid_sam_penstash,
Hi,
Could you please confirm this penstash is correct (sam vs kip)?
Sashiko suggested it might be wrong but take it's report with a grain of
salt, it's AI after all and sometimes seems to extrapolate about HW to a
sibling HW without any real knowledge:
https://sashiko.dev/#/patchset/cover.1778822464.git.harrison.vanderbyl%40gmail.com
--
i.
> + &ssam_node_hid_kip_touchpad,
> + &ssam_node_hid_kip_fwupd,
> + &ssam_node_pos_tablet_switch,
> + NULL,
> +};
> +
> /* -- SSAM platform/meta-hub driver. ---------------------------------------- */
>
> static const struct acpi_device_id ssam_platform_hub_acpi_match[] = {
> @@ -500,6 +513,8 @@ static const struct of_device_id ssam_platform_hub_of_match[] __maybe_unused = {
> { .compatible = "microsoft,arcata", (void *)ssam_node_group_sp9_5g },
> /* Surface Pro 11 (ARM/QCOM) */
> { .compatible = "microsoft,denali", (void *)ssam_node_group_sp11 },
> + /* Surface Pro 12in First Edition (ARM/QCOM) */
> + { .compatible = "microsoft,surface-pro-12in", (void *)ssam_node_group_sp12in },
> /* Surface Laptop 7 */
> { .compatible = "microsoft,romulus13", (void *)ssam_node_group_sl7 },
> { .compatible = "microsoft,romulus15", (void *)ssam_node_group_sl7 },
^ permalink raw reply
* Re: [PATCH v2 7/7] arm64: dts: qcom: Add Microsoft Surface Pro 12in
From: Dmitry Baryshkov @ 2026-05-28 13:19 UTC (permalink / raw)
To: Harrison Vanderbyl
Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, Herbert Xu,
davem, neil.armstrong, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, jikos, bentiss, luzmaximilian, hansg,
ilpo.jarvinen, Douglas Anderson, Jessica Zhang, linux-arm-msm,
devicetree, linux-kernel, linux-crypto, dri-devel, linux-input,
platform-driver-x86
In-Reply-To: <8ac29ee38ba80a3fbde8bfe43b74b9b936b31cb1.1778822464.git.harrison.vanderbyl@gmail.com>
On Fri, May 15, 2026 at 03:41:52PM +1000, Harrison Vanderbyl wrote:
> Initial device tree for Microsoft Surface Pro 12in
>
> Currently supported:
> - UFS
> - Touchscreen
> - Pen
> - USB 3.2 x2 (DP Alt Mode)
> - Audio
> - Wifi
> - Bluetooth
> - CDSP
> - ADSP
> - GPU
>
> Not currently supported:
> - Accelerometer
> - Front, Back and IR cameras
> - IRIS video decoder
>
> Tested on Surface_Pro_12in_1st_Ed_with_Snapdragon_2110
>
> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl@gmail.com>
> ---
> arch/arm64/boot/dts/qcom/Makefile | 2 +
> .../dts/qcom/x1p42100-microsoft-sp12in.dts | 1201 +++++++++++++++++
> 2 files changed, 1203 insertions(+)
> create mode 100644 arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v2 3/7] platform/surface: SAM: Add support for Surface Pro 12in
From: Harrison Vanderbyl @ 2026-05-28 13:33 UTC (permalink / raw)
To: ilpo.jarvinen
Cc: airlied, andersson, bentiss, conor+dt, davem, devicetree,
dianders, dri-devel, hansg, herbert, jesszhan0024, jikos,
konradybcio, krzk+dt, linux-arm-msm, linux-crypto, linux-input,
linux-kernel, luzmaximilian, maarten.lankhorst, mripard,
neil.armstrong, platform-driver-x86, robh, simona, tzimmermann
In-Reply-To: <6808166a-423c-c801-497a-ed95cccc8d0c@linux.intel.com>
On Thu, 28 May 2026, Ilpo Järvinen wrote:
> Could you please confirm this penstash is correct (sam vs kip)?
>
> Sashiko suggested it might be wrong but take it's report with a grain of
> salt, it's AI after all and sometimes seems to extrapolate about HW to a
> sibling HW without any real knowledge:
Sam is correct here, unlike the surface pro 11,
The pen stash is on the reverse of the screen,
not on the detachable keyboard.
An image of the pen stash in use is available here:
https://cdn-dynmedia-1.microsoft.com/is/image/microsoftcorp/B04-Surface-Pro-12-inch-1Ed-Family-Rear?wid=1200&hei=900&qlt=90&bgc=F2F2F2F2&fmt=jpg
When using the above config,
pen stash events can be seen with evtest.
Thanks,
Harrison
^ permalink raw reply
* Re: [PATCH v2 3/7] platform/surface: SAM: Add support for Surface Pro 12in
From: Ilpo Järvinen @ 2026-05-28 13:43 UTC (permalink / raw)
To: Harrison Vanderbyl
Cc: airlied, andersson, bentiss, conor+dt, davem, devicetree,
dianders, dri-devel, Hans de Goede, herbert, jesszhan0024, jikos,
konradybcio, krzk+dt, linux-arm-msm, linux-crypto, linux-input,
LKML, luzmaximilian, maarten.lankhorst, mripard, neil.armstrong,
platform-driver-x86, robh, simona, tzimmermann
In-Reply-To: <20260528133353.33312-1-harrison.vanderbyl@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1021 bytes --]
On Thu, 28 May 2026, Harrison Vanderbyl wrote:
> On Thu, 28 May 2026, Ilpo Järvinen wrote:
> > Could you please confirm this penstash is correct (sam vs kip)?
> >
> > Sashiko suggested it might be wrong but take it's report with a grain of
> > salt, it's AI after all and sometimes seems to extrapolate about HW to a
> > sibling HW without any real knowledge:
>
> Sam is correct here, unlike the surface pro 11,
> The pen stash is on the reverse of the screen,
> not on the detachable keyboard.
>
> An image of the pen stash in use is available here:
> https://cdn-dynmedia-1.microsoft.com/is/image/microsoftcorp/B04-Surface-Pro-12-inch-1Ed-Family-Rear?wid=1200&hei=900&qlt=90&bgc=F2F2F2F2&fmt=jpg
>
> When using the above config,
> pen stash events can be seen with evtest.
Thanks for confirming (not a big surprise AI couldn't know the spec but
it was worth checking if it would have been because of copy-paste).
I've applied this patch 3 now to the review-ilpo-next branch.
--
i.
^ permalink raw reply
* Re: [PATCH 00/11] HID: storing pointers in 'hid_device_id::driver_data'
From: Benjamin Tissoires @ 2026-05-28 16:00 UTC (permalink / raw)
To: Pawel Zalewski
Cc: Jiri Kosina, Ping Cheng, Jason Gerecke, linux-kernel, linux-input,
Christian A. Ehrhardt, Christian A. Ehrhardt
In-Reply-To: <ahBgYbMWR4VwFAy3@commodore64>
On May 22 2026, Pawel Zalewski wrote:
> > I would agree with sashiko that the series introduces an anti-pattern by
> > allowing .driver_data to be an arbitrary pointer. The reason is that we
> > can dynamically set driver_data through the kernel command line, and
> > when it's used as a pointer, bad things will happen.
>
> I have not considered the command line override ! This indeed would not
> be a good case for having a pointer at all in there - in the current
> form of the codebase.
>
> The series does not introduce this anti-pattern - this is already the
> current status quo in the codebase and�the problem predates the patch
> series itself. The series makes the problem more visible and validates
> the existing status quo - agreed on this.
Oh, yes sure. But the series makes the anti-pattern official, which
would encourage people to use it. (we are saying the same thing).
>
> > I would think we should fix the 2 offenders to enforce not using a
> > direct pointer but an offset in a table of pointers.
> >
> > How does that sound for you?
>
> That could work, probably via a named enum (so that the idx is bounded
> and validated to avoid out of bounds memory access) with its items mapped
> into a table of const pointers. That way the command line override still
> works as before and my goals set out in the series are met as well.
>
> Perhaps an alternative solution would be to sanitize the user-input instead in
> the 'hid-core::new_id_store' function, such that only 'driver_data' values
> that match an existing entry in the driver's 'id_table' are accepted, this
> is how it is done currently in the PCI subsystem in 'pci-driver::new_id_store',
> so it would be consistent as well.
>
> The bonus here is that all other drivers in the HID subsystem benefit from
> this aproach as opposed to just the two current offenders, as providing
> 'driver_data' from the command line is now mandatory and must match the
> existing table entry - which is what we want ?
>
> So something among the lines of:
>
> @hid-core::new_id_store
>
> ```
> struct hid_driver *hdrv = to_hid_driver(drv);
> const struct hid_device_id *ids = hdrv->id_table;
>
> (...)
>
> /* Only accept driver_data values that match an existing id_table
> entry */
> if (ids) {
> ret = -EINVAL;
> while (ids->vendor || ids->product) {
> if (driver_data == ids->driver_data) {
> ret = 0;
> break;
> }
> ids++;
> }
> if (ret) /* No match */
> return ret;
> }
> ```
>
> Would that approach work for you ?
Yes, sanityzing the input seems like a good idea.
> Do help in what is the correct
> termination for the while loop - for this demo I went with 'ids->vendor'
> and 'ids->product' fields as common-sense would indicate that quirks need
> to be device-specific by definition but that was without any actual research.
hid-core.c does:
const struct hid_device_id *hid_match_id(const struct hid_device *hdev,
const struct hid_device_id *id)
{
for (; id->bus; id++)
if (hid_match_one_id(hdev, id))
return id;
return NULL;
}
So I guess you can simply rely on id-bus being set.
>
> The downside is that 'new_id' drivers that actually use a pointer for the
> 'driver_data' will be rejected - which would be actually covered by the
> solution that you have proposed in the first place. To think of it the
> input sanitizer could work additionaly in tandem with the enum-based
> solution if this fact is an issue, so it might not be an alternative
> actually but a complement for it.
Agree, we need both.
>
> In the meantime I think that patches 1-8 can be reviewed regardless
> without any changes (as they predate patch 9 that adds the union and the
> commit messages does not mention anything about it).
I'd drop patches 1-4. I don't see the point of just rewriting the list
of hid_device_id if we ensure we have just one type.
I need to have a closer look at 5-8 TBH.
Cheers,
Benjamin
>
> Best regards,
> Pawel
>
>
^ permalink raw reply
* Re: [RESEND 1/1] HID: wacom: Fix OOB write in wacom_hid_set_device_mode()
From: Benjamin Tissoires @ 2026-05-28 16:01 UTC (permalink / raw)
To: Ping Cheng, Jason Gerecke, Jiri Kosina, linux-input, linux-kernel,
Lee Jones
Cc: stable
In-Reply-To: <20260527160528.847928-1-lee@kernel.org>
On Wed, 27 May 2026 17:05:26 +0100, Lee Jones wrote:
> wacom_hid_set_device_mode() currently assumes that the HID_DG_INPUTMODE
> usage is always located in the first field (field[0]) of the feature report.
> However, a device can specify HID_DG_INPUTMODE in a different field.
>
> If HID_DG_INPUTMODE is in a field other than the first one and the first
> field has a report_count smaller than the usage_index of HID_DG_INPUTMODE,
> this leads to an out-of-bounds write to r->field[0]->value.
>
> [...]
Applied to https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git (for-7.1/upstream-fixes), thanks!
[1/1] HID: wacom: Fix OOB write in wacom_hid_set_device_mode()
https://git.kernel.org/hid/hid/c/c0a8899e02dd
Cheers,
--
Benjamin Tissoires <bentiss@kernel.org>
^ permalink raw reply
* Re: [PATCH v8 1/2] dt-bindings: Input: Add Wacom W9000-series penabled touchscreens
From: Conor Dooley @ 2026-05-28 17:10 UTC (permalink / raw)
To: sashiko-reviews
Cc: Hendrik Noack, robh, dmitry.torokhov, conor+dt, devicetree,
linux-input
In-Reply-To: <20260528083225.3A5101F00A3A@smtp.kernel.org>
[-- Attachment #1: Type: text/plain, Size: 2377 bytes --]
On Thu, May 28, 2026 at 08:32:24AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [Low] Vendor-specific property 'flash-mode-gpios' is missing the vendor prefix.
> - [Low] Node name 'digitizer@56' in the example should be a standard generic name such as 'touchscreen@56'.
> - [Low] The binding file is named after a specific variant ('wacom,w9007a-lt03.yaml') rather than the first compatible string ('wacom,w9002.yaml').
> --
>
> commit d38ecd0efb12cc8efc9000f9c78e8a14387d40c6
> Author: Hendrik Noack <hendrik-noack@gmx.de>
> Subject: dt-bindings: Input: Add Wacom W9000-series penabled touchscreens
>
> This commit adds bindings for the Wacom W9002, W9007A LT03, and W9007A V1
> touchscreen controllers. These controllers differ slightly in their return
> message formats.
>
> > diff --git a/Documentation/devicetree/bindings/input/touchscreen/wacom,w9007a-lt03.yaml b/Documentation/devicetree/bindings/input/touchscreen/wacom,w9007a-lt03.yaml
> > new file mode 100644
> > index 0000000000000..6d1da6a435d39
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/touchscreen/wacom,w9007a-lt03.yaml
>
> [Severity: Low]
> Should this file be named wacom,w9002.yaml after the first compatible string,
> rather than being named after a specific variant?
This doesn't matter, w9002 is as much of a "variant" as the others.
>
> > @@ -0,0 +1,73 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
>
> [ ... ]
>
> > + vdd-supply: true
> > +
> > + flash-mode-gpios:
> > + maxItems: 1
>
> [Severity: Low]
> Does this property need a vendor prefix (wacom,flash-mode-gpios) since it is
> hardware-specific?
No, cos it is a gpios property. Just like how supplies don't have
prefixes.
>
> [ ... ]
>
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + digitizer@56 {
>
> [Severity: Low]
> Should this node name be changed to a generic class name such as
> touchscreen@56?
"digitiser" is generic enough for this not to matter IMO.
>
> > + compatible = "wacom,w9007a-lt03";
> > + reg = <0x56>;
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260528074818.12151-1-hendrik-noack@gmx.de?part=1
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH v2] HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert
From: Jinmo Yang @ 2026-05-28 17:59 UTC (permalink / raw)
To: linux-input, dmitry.torokhov
Cc: jikos, benjamin.tissoires, stable, Jinmo Yang
In-Reply-To: <20260524135203.1996265-1-jinmo44.yang@gmail.com>
wacom_wac_queue_insert() calls kfifo_skip() in a loop when the kfifo
doesn't have enough space for the incoming report. If the kfifo is
empty, kfifo_skip() reads stale data left in the kmalloc'd buffer
via __kfifo_peek_n() and interprets it as a record length, advancing
fifo->out by that garbage value. This corrupts the internal kfifo
state, causing kfifo_unused() to return a value much larger than the
actual buffer size, which bypasses __kfifo_in_r()'s guard:
if (len + recsize > kfifo_unused(fifo))
return 0;
kfifo_copy_in() then performs an out-of-bounds memcpy, writing up to
3842 bytes past the 256-byte buffer.
Add a !kfifo_is_empty() condition to the while loop so kfifo_skip()
is never called on an empty fifo, and check the return value of
kfifo_in() to reject reports that are too large for the fifo.
Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Fixes: 5e013ad20689 ("HID: wacom: Remove static WACOM_PKGLEN_MAX limit")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
Changes in v2:
- Instead of a size check at the top, add !kfifo_is_empty() to the
while loop condition to prevent kfifo_skip() on an empty fifo
(Suggested by Dmitry Torokhov)
- Check kfifo_in() return value to reject oversized reports instead
of a separate guard
drivers/hid/wacom_sys.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index a32320b35..489ca68f1 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -54,7 +54,7 @@ static void wacom_wac_queue_insert(struct hid_device *hdev,
{
bool warned = false;
- while (kfifo_avail(fifo) < size) {
+ while (kfifo_avail(fifo) < size && !kfifo_is_empty(fifo)) {
if (!warned)
hid_warn(hdev, "%s: kfifo has filled, starting to drop events\n", __func__);
warned = true;
@@ -62,7 +62,9 @@ static void wacom_wac_queue_insert(struct hid_device *hdev,
kfifo_skip(fifo);
}
- kfifo_in(fifo, raw_data, size);
+ if (!kfifo_in(fifo, raw_data, size))
+ hid_warn_ratelimited(hdev, "%s: report is too large (%d)\n",
+ __func__, size);
}
static void wacom_wac_queue_flush(struct hid_device *hdev,
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2] HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert
From: sashiko-bot @ 2026-05-28 18:42 UTC (permalink / raw)
To: Jinmo Yang; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260528175945.2987781-1-jinmo44.yang@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] wacom_wac_queue_flush() allocates memory with GFP_KERNEL while executing in an atomic context, leading to a 'scheduling while atomic' panic.
--
commit 70e9615b93de485ba1816f95e27e25b054df4b6a
Author: Jinmo Yang <jinmo44.yang@gmail.com>
HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert
This commit fixes a slab-out-of-bounds write in wacom_wac_queue_insert().
It prevents kfifo_skip() from operating on an empty fifo and validates
the return value of kfifo_in().
> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index a32320b351e3e..489ca68f1560f 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
[ ... ]
> @@ -62,7 +62,9 @@ static void wacom_wac_queue_insert(struct hid_device *hdev,
> kfifo_skip(fifo);
> }
>
> - kfifo_in(fifo, raw_data, size);
> + if (!kfifo_in(fifo, raw_data, size))
> + hid_warn_ratelimited(hdev, "%s: report is too large (%d)\n",
> + __func__, size);
> }
>
> static void wacom_wac_queue_flush(struct hid_device *hdev,
> struct kfifo_rec_ptr_2 *fifo)
> {
> while (!kfifo_is_empty(fifo)) {
> int size = kfifo_peek_len(fifo);
> u8 *buf;
> unsigned int count;
> int err;
>
> buf = kzalloc(size, GFP_KERNEL);
[Severity: High]
This is a pre-existing issue, but is it safe to use GFP_KERNEL here?
Looking at the call chain, wacom_wac_queue_flush() is invoked via
wacom_wac_pen_serial_enforce() from the driver's .raw_event callback,
wacom_raw_event().
For USB HID devices, this callback is typically triggered by hid_irq_in(),
which is an URB completion handler that runs in an atomic context.
Since using GFP_KERNEL allows the allocator to sleep, could this lead to a
scheduling while atomic panic? Would it be better to use GFP_ATOMIC instead?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528175945.2987781-1-jinmo44.yang@gmail.com?part=1
^ permalink raw reply
* [PATCH] Input: mtk-pmic-keys: Count available keys during probe instead of pre-counting
From: Rosen Penev @ 2026-05-28 23:56 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Matthias Brugger, AngeloGioacchino Del Regno,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
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.
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) {
+ if (index >= MTK_PMIC_MAX_KEY_COUNT) {
+ dev_err(&pdev->dev, "too many keys defined\n");
+ return -EINVAL;
+ }
- for_each_child_of_node_scoped(node, child) {
- keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
+ key = &keys->keys[index];
+ key->regs = &mtk_pmic_regs->keys_regs[index];
- keys->keys[index].irq =
- platform_get_irq_byname(pdev, irqnames[index]);
- if (keys->keys[index].irq < 0)
- return keys->keys[index].irq;
+ key->irq = platform_get_irq_byname(pdev, irqnames[index]);
+ if (key->irq < 0)
+ return key->irq;
if (mtk_pmic_regs->key_release_irq) {
- keys->keys[index].irq_r = platform_get_irq_byname(pdev,
- irqnames_r[index]);
-
- if (keys->keys[index].irq_r < 0)
- return keys->keys[index].irq_r;
+ key->irq_r = platform_get_irq_byname(pdev, irqnames_r[index]);
+ if (key->irq_r < 0)
+ return key->irq_r;
}
- error = of_property_read_u32(child,
- "linux,keycodes", &keys->keys[index].keycode);
+ error = of_property_read_u32(child, "linux,keycodes", &key->keycode);
if (error) {
dev_err(keys->dev,
"failed to read key:%d linux,keycode property: %d\n",
@@ -389,14 +383,15 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
}
if (of_property_read_bool(child, "wakeup-source"))
- keys->keys[index].wakeup = true;
+ key->wakeup = true;
- error = mtk_pmic_key_setup(keys, &keys->keys[index]);
+ error = mtk_pmic_key_setup(keys, key);
if (error)
return error;
index++;
}
+ keys->nkeys = index;
error = input_register_device(input_dev);
if (error) {
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] Input: mtk-pmic-keys: Count available keys during probe instead of pre-counting
From: sashiko-bot @ 2026-05-29 0:29 UTC (permalink / raw)
To: Rosen Penev; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260528235600.312045-1-rosenp@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Skipping unavailable device tree child nodes shifts the loop index, breaking the implicit hardware mapping and incorrectly assigning registers and IRQs.
--
commit ddd98727b5f1967e1232c34c0d42b4d0d314c947
Author: Rosen Penev <rosenp@gmail.com>
Input: mtk-pmic-keys: Count available keys during probe instead of pre-counting
This commit replaces the separate pre-count of available keys with a
single pass using for_each_available_child_of_node_scoped(). It skips
unavailable nodes and bails out if the key count exceeds the maximum.
The match data lookup is also updated to use of_device_get_match_data().
> diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
> index c78d9f6d97c4f..e34856693ee2c 100644
> --- a/drivers/input/keyboard/mtk-pmic-keys.c
> +++ b/drivers/input/keyboard/mtk-pmic-keys.c
[ ... ]
> @@ -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) {
> + if (index >= MTK_PMIC_MAX_KEY_COUNT) {
> + dev_err(&pdev->dev, "too many keys defined\n");
> + return -EINVAL;
> + }
>
> - for_each_child_of_node_scoped(node, child) {
> - keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
> + key = &keys->keys[index];
> + key->regs = &mtk_pmic_regs->keys_regs[index];
>
> - keys->keys[index].irq =
> - platform_get_irq_byname(pdev, irqnames[index]);
> - if (keys->keys[index].irq < 0)
> - return keys->keys[index].irq;
> + key->irq = platform_get_irq_byname(pdev, irqnames[index]);
[Severity: High]
Does switching to for_each_available_child_of_node_scoped() break the
strict index mapping for hardware registers and IRQs?
The original code iterated over all child nodes, preserving the device tree
order index (e.g., index 0 for powerkey, index 1 for homekey).
If a device tree has a disabled node first, skipping it will shift the index
for subsequent available nodes. For example, if the powerkey node is
disabled, the homekey node would be processed with index 0 instead of 1,
causing it to be incorrectly assigned the hardware IRQ and registers of the
powerkey.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260528235600.312045-1-rosenp@gmail.com?part=1
^ permalink raw reply
* [PATCH v3 0/2] Add support for Microsoft Surface Pro 12in
From: Harrison Vanderbyl @ 2026-05-29 1:16 UTC (permalink / raw)
To: linux-kernel, linux-input, linux-arm-msm, devicetree
Cc: jikos, bentiss, andersson, konradybcio, robh, krzk+dt, conor+dt,
dmitry.baryshkov, Harrison Vanderbyl
Changes in v3:
Rebase:
- Rebased on next-20260528
- Removed ice device tree changes
Device tree:
- Fixed C++ style comment in &i2c9 to use /* */ style
- Flattened mdss_dp3 port into &mdss_dp3_out directly
- Whitespace and formatting nits
Changes in v2:
Ice device tree:
- Updated to use 0x0 formatting
Panel:
- Add edid to commit message
Device tree:
- Fixed formatting and ordering nits
- Removed extra dmic audio declarations
- Added suspected devices on i2c busses
- Fixed incorrect usb regulator
- Describe panel pin regulator
- Added defaults for volume button GPIOs
Already applied:
- dt-bindings: arm: qcom: Add Microsoft Surface Pro 12in
(landed in linux-next)
- firmware: qcom: scm: Allow QSEECOM on Surface Pro 12in
(applied by Bjorn Andersson, commit 667d05a09db3)
- platform/surface: SAM: Add support for Surface Pro 12in
(applied to review-ilpo-next by Ilpo Järvinen)
- drm/panel-edp: Add panel for Surface Pro 12in
(pushed to drm-misc-next by Doug Anderson, commit 02f48ffdf96c)
Pending in this series:
- hid: Pen battery quirk for Surface Pro 12in
(acked by Jiri Kosina in v1, needs a tree)
- arm64: dts: qcom: Add Microsoft Surface Pro 12in
(reviewed by Dmitry Baryshkov in v2, minor style fixes applied)
Will be done in future patches:
- Camera support (pending purwa cams patchset)
- IRIS jpeg decoder support (pending purwa iris patchset)
- Accelerometer support via ADSP (probably userspace)
(Audioreach/ucm2 changes for audio)
https://github.com/linux-msm/audioreach-topology/pull/32
https://github.com/alsa-project/alsa-ucm-conf/blob/9577cd31121546b288759097901025376141177b/ucm2/Qualcomm/x1e80100/Surface12in-HiFi.conf
Link to v1:
https://lore.kernel.org/all/cover.1778498477.git.harrison.vanderbyl@gmail.com/
Link to v2:
https://lore.kernel.org/all/cover.1778822464.git.harrison.vanderbyl@gmail.com/
Harrison Vanderbyl (2):
hid: Pen battery quirk for Surface Pro 12in
arm64: dts: qcom: Add Microsoft Surface Pro 12in
arch/arm64/boot/dts/qcom/Makefile | 2 +
.../dts/qcom/x1p42100-microsoft-sp12in.dts | 1194 +++++++++++++++++
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-input.c | 2 +
4 files changed, 1199 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
base-commit: f7af91adc230aa99e23330ecf85bc9badd9780ad
--
2.53.0
^ permalink raw reply
* [PATCH v3 1/2] hid: Pen battery quirk for Surface Pro 12in
From: Harrison Vanderbyl @ 2026-05-29 1:16 UTC (permalink / raw)
To: linux-kernel, linux-input, linux-arm-msm, devicetree
Cc: jikos, bentiss, andersson, konradybcio, robh, krzk+dt, conor+dt,
dmitry.baryshkov, Harrison Vanderbyl, Jiri Kosina
In-Reply-To: <20260529011619.9586-1-harrison.vanderbyl@gmail.com>
The pen setup for this device uses bluetooth for
communicating battery levels and status instead of
reporting it over i2c.
Without this quirk, the device either reports an
extra, broken phantom battery, or hangs.
Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl@gmail.com>
Acked-by: Jiri Kosina <jkosina@suse.com>
---
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-input.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index a1cfa436344a..c383778e241c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -463,6 +463,7 @@
#define USB_DEVICE_ID_HP_X2 0x074d
#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
#define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM 0x2F81
+#define I2C_DEVICE_ID_SURFACE_PRO_12IN 0x4376
#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d73cfa2e73d3..61ecd840d0bd 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -395,6 +395,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
HID_BATTERY_QUIRK_AVOID_QUERY },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM),
HID_BATTERY_QUIRK_AVOID_QUERY },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_PRO_12IN),
+ HID_BATTERY_QUIRK_IGNORE },
/*
* Elan HID touchscreens seem to all report a non present battery,
* set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices.
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/2] arm64: dts: qcom: Add Microsoft Surface Pro 12in
From: Harrison Vanderbyl @ 2026-05-29 1:16 UTC (permalink / raw)
To: linux-kernel, linux-input, linux-arm-msm, devicetree
Cc: jikos, bentiss, andersson, konradybcio, robh, krzk+dt, conor+dt,
dmitry.baryshkov, Harrison Vanderbyl
In-Reply-To: <20260529011619.9586-1-harrison.vanderbyl@gmail.com>
Initial device tree for Microsoft Surface Pro 12in
Currently supported:
- UFS
- Touchscreen
- Pen
- USB 3.2 x2 (DP Alt Mode)
- Audio
- Wifi
- Bluetooth
- CDSP
- ADSP
- GPU
Not currently supported:
- Accelerometer
- Front, Back and IR cameras
- IRIS video decoder
Tested on Surface_Pro_12in_1st_Ed_with_Snapdragon_2110
Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 2 +
.../dts/qcom/x1p42100-microsoft-sp12in.dts | 1194 +++++++++++++++++
2 files changed, 1196 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 6f33c4e2f09c..ada494ecbc64 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -457,3 +457,5 @@ x1p42100-lenovo-thinkbook-16-el2-dtbs := x1p42100-lenovo-thinkbook-16.dtb x1-el2
dtb-$(CONFIG_ARCH_QCOM) += x1p42100-lenovo-thinkbook-16.dtb x1p42100-lenovo-thinkbook-16-el2.dtb
x1p64100-microsoft-denali-el2-dtbs := x1p64100-microsoft-denali.dtb x1-el2.dtbo
dtb-$(CONFIG_ARCH_QCOM) += x1p64100-microsoft-denali.dtb x1p64100-microsoft-denali-el2.dtb
+x1p42100-microsoft-sp12in-el2-dtbs := x1p42100-microsoft-sp12in.dtb x1-el2.dtbo
+dtb-$(CONFIG_ARCH_QCOM) += x1p42100-microsoft-sp12in.dtb x1p42100-microsoft-sp12in-el2.dtb
diff --git a/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
new file mode 100644
index 000000000000..983966e123e5
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
@@ -0,0 +1,1194 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited
+ * Copyright (c) 2025, Jens Glathe
+ * Copyright (c) 2025, Harrison Vanderbyl
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/clock/qcom,x1e80100-tcsr.h>
+
+#include "purwa.dtsi"
+#include "hamoa-pmics.dtsi"
+
+/delete-node/ &pmc8380_6;
+/delete-node/ &pmc8380_6_thermal;
+
+/ {
+ model = "Surface Pro 12in 1st Edition";
+ compatible = "microsoft,surface-pro-12in", "qcom,x1p42100";
+ chassis-type = "tablet";
+
+ aliases {
+ serial0 = &uart2;
+ serial1 = &uart14;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pmk8550_pwm 0 5000000>;
+
+ power-supply = <&vreg_edp_3p3>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&hall_int_n_default>, <&vol_up_n_default>, <&vol_down_n_default>;
+ pinctrl-names = "default";
+
+ switch-lid {
+ gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_LID>;
+ wakeup-source;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ };
+
+ key-vol-up {
+ gpios = <&pm8550_gpios 8 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+
+ key-vol-down {
+ gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <15>;
+ linux,can-disable;
+ wakeup-source;
+ };
+ };
+
+ pmic-glink {
+ compatible = "qcom,x1e80100-pmic-glink",
+ "qcom,sm8550-pmic-glink",
+ "qcom,pmic-glink";
+ orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>,
+ <&tlmm 123 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* Right-side upper port */
+ connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss0_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss0_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss0_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss0_sbu: endpoint {
+ remote-endpoint = <&usb_1_ss0_sbu_mux>;
+ };
+ };
+ };
+ };
+
+ /* Right-side lower port */
+ connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ power-role = "dual";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pmic_glink_ss1_hs_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pmic_glink_ss1_ss_in: endpoint {
+ remote-endpoint = <&usb_1_ss1_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_ss1_sbu: endpoint {
+ remote-endpoint = <&usb_1_ss1_sbu_mux>;
+ };
+ };
+ };
+ };
+ };
+
+ reserved-memory {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ size = <0x0 0x20000000>;
+ reusable;
+ linux,cma-default;
+ };
+ };
+
+ vreg_edp_3p3: regulator-edp-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_EDP_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&edp_reg_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ vin-supply = <&vreg_panel_en>;
+ };
+
+ vreg_panel_en: regulator-panel-en {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_PANEL_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 29 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ regulator-enable-ramp-delay = <150000>;
+
+ pinctrl-0 = <&panel_en>;
+ pinctrl-names = "default";
+
+ regulator-boot-on;
+ };
+
+ vph_pwr: regulator-vph-pwr {
+ compatible = "regulator-fixed";
+
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ };
+
+ vreg_wcn_0p95: regulator-wcn-0p95 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_WCN_0P95";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <950000>;
+
+ vin-supply = <&vreg_wcn_3p3>;
+ };
+
+ vreg_wcn_1p9: regulator-wcn-1p9 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_WCN_1P9";
+ regulator-min-microvolt = <1900000>;
+ regulator-max-microvolt = <1900000>;
+
+ vin-supply = <&vreg_wcn_3p3>;
+ };
+
+ vreg_wcn_3p3: regulator-wcn-3p3 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "VREG_WCN_3P3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 214 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&wcn_sw_en>;
+ pinctrl-names = "default";
+ };
+
+ sound {
+ compatible = "qcom,x1e80100-sndcard";
+ model = "X1P42100-Microsoft-Surface-Pro-12in";
+ audio-routing = "SpkrLeft IN", "WSA WSA_SPK1 OUT",
+ "SpkrRight IN", "WSA WSA_SPK2 OUT",
+ "VA DMIC0", "vdd-micb",
+ "VA DMIC1", "vdd-micb";
+
+ va-dai-link {
+ link-name = "VA Capture";
+
+ codec {
+ sound-dai = <&lpass_vamacro 0>;
+ };
+
+ cpu {
+ sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+
+ wsa-dai-link {
+ link-name = "WSA Playback";
+
+ codec {
+ sound-dai = <&left_spkr>, <&right_spkr>,
+ <&swr0 0>, <&lpass_wsamacro 0>;
+ };
+
+ cpu {
+ sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+ };
+
+ wcn7850-pmu {
+ compatible = "qcom,wcn7850-pmu";
+
+ vdd-supply = <&vreg_wcn_0p95>;
+ vddio-supply = <&vreg_l15b_1p8>;
+ vddaon-supply = <&vreg_wcn_0p95>;
+ vdddig-supply = <&vreg_wcn_0p95>;
+ vddrfa1p2-supply = <&vreg_wcn_1p9>;
+ vddrfa1p8-supply = <&vreg_wcn_1p9>;
+
+ wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>;
+ bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&wcn_wlan_bt_en>;
+ pinctrl-names = "default";
+
+ regulators {
+ vreg_pmu_rfa_cmn: ldo0 {
+ regulator-name = "vreg_pmu_rfa_cmn";
+ };
+
+ vreg_pmu_aon_0p59: ldo1 {
+ regulator-name = "vreg_pmu_aon_0p59";
+ };
+
+ vreg_pmu_wlcx_0p8: ldo2 {
+ regulator-name = "vreg_pmu_wlcx_0p8";
+ };
+
+ vreg_pmu_wlmx_0p85: ldo3 {
+ regulator-name = "vreg_pmu_wlmx_0p85";
+ };
+
+ vreg_pmu_btcmx_0p85: ldo4 {
+ regulator-name = "vreg_pmu_btcmx_0p85";
+ };
+
+ vreg_pmu_rfa_0p8: ldo5 {
+ regulator-name = "vreg_pmu_rfa_0p8";
+ };
+
+ vreg_pmu_rfa_1p2: ldo6 {
+ regulator-name = "vreg_pmu_rfa_1p2";
+ };
+
+ vreg_pmu_rfa_1p8: ldo7 {
+ regulator-name = "vreg_pmu_rfa_1p8";
+ };
+
+ vreg_pmu_pcie_0p9: ldo8 {
+ regulator-name = "vreg_pmu_pcie_0p9";
+ };
+
+ vreg_pmu_pcie_1p8: ldo9 {
+ regulator-name = "vreg_pmu_pcie_1p8";
+ };
+ };
+ };
+
+ usb-1-ss0-sbu-mux {
+ compatible = "onnn,fsusb42", "gpio-sbu-mux";
+
+ enable-gpios = <&tlmm 168 GPIO_ACTIVE_LOW>;
+ select-gpios = <&tlmm 167 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&usb_1_ss0_sbu_default>;
+ pinctrl-names = "default";
+
+ mode-switch;
+ orientation-switch;
+
+ port {
+ usb_1_ss0_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_ss0_sbu>;
+ };
+ };
+ };
+
+ usb-1-ss1-sbu-mux {
+ compatible = "onnn,fsusb42", "gpio-sbu-mux";
+
+ enable-gpios = <&tlmm 179 GPIO_ACTIVE_LOW>;
+ select-gpios = <&tlmm 178 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&usb_1_ss1_sbu_default>;
+ pinctrl-names = "default";
+
+ mode-switch;
+ orientation-switch;
+
+ port {
+ usb_1_ss1_sbu_mux: endpoint {
+ remote-endpoint = <&pmic_glink_ss1_sbu>;
+ };
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
+ vdd-l1-l4-l10-supply = <&vreg_s4c_1p8>;
+ vdd-l2-l13-l14-supply = <&vreg_bob1>;
+ vdd-l5-l16-supply = <&vreg_bob1>;
+ vdd-l6-l7-supply = <&vreg_bob2>;
+ vdd-l8-l9-supply = <&vreg_bob1>;
+ vdd-l12-supply = <&vreg_s5j_1p2>;
+ vdd-l15-supply = <&vreg_s4c_1p8>;
+ vdd-l17-supply = <&vreg_bob2>;
+
+ vreg_bob1: bob1 {
+ regulator-name = "vreg_bob1";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob2: bob2 {
+ regulator-name = "vreg_bob2";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1b_1p8: ldo1 {
+ regulator-name = "vreg_l1b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p0: ldo2 {
+ regulator-name = "vreg_l2b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4b_1p8: ldo4 {
+ regulator-name = "vreg_l4b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5b_3p0: ldo5 {
+ regulator-name = "vreg_l5b_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p8: ldo6 {
+ regulator-name = "vreg_l6b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_2p8: ldo7 {
+ regulator-name = "vreg_l7b_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-always-on;
+ };
+
+ vreg_l8b_3p0: ldo8 {
+ regulator-name = "vreg_l8b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_2p9: ldo9 {
+ regulator-name = "vreg_l9b_2p9";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10b_1p8: ldo10 {
+ regulator-name = "vreg_l10b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12b_1p2: ldo12 {
+ regulator-name = "vreg_l12b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13b_3p0: ldo13 {
+ regulator-name = "vreg_l13b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14b_3p0: ldo14 {
+ regulator-name = "vreg_l14b_3p0";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15b_1p8: ldo15 {
+ regulator-name = "vreg_l15b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16b_2p9: ldo16 {
+ regulator-name = "vreg_l16b_2p9";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17b_2p5: ldo17 {
+ regulator-name = "vreg_l17b_2p5";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-1 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-l1-supply = <&vreg_s5j_1p2>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ vreg_s4c_1p8: smps4 {
+ regulator-name = "vreg_s4c_1p8";
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1c_1p2: ldo1 {
+ regulator-name = "vreg_l1c_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c_0p8: ldo2 {
+ regulator-name = "vreg_l2c_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_0p8: ldo3 {
+ regulator-name = "vreg_l3c_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-2 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "d";
+
+ vdd-l3-supply = <&vreg_s4c_1p8>;
+ vdd-s1-supply = <&vph_pwr>;
+
+ vreg_l1d_0p8: ldo1 {
+ regulator-name = "vreg_l1d_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2d_0p9: ldo2 {
+ regulator-name = "vreg_l2d_0p9";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3d_1p8: ldo3 {
+ regulator-name = "vreg_l3d_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-3 {
+ compatible = "qcom,pmc8380-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vdd-l3-supply = <&vreg_s5j_1p2>;
+
+ vreg_l2e_0p8: ldo2 {
+ regulator-name = "vreg_l2e_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-6 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "i";
+
+ vdd-l1-supply = <&vreg_s4c_1p8>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+
+ vreg_s1i_0p9: smps1 {
+ regulator-name = "vreg_s1i_0p9";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s2i_1p0: smps2 {
+ regulator-name = "vreg_s2i_1p0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1i_1p8: ldo1 {
+ regulator-name = "vreg_l1i_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2i_1p2: ldo2 {
+ regulator-name = "vreg_l2i_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3i_0p8: ldo3 {
+ regulator-name = "vreg_l3i_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-7 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+ qcom,pmic-id = "j";
+
+ vdd-l2-supply = <&vreg_s5j_1p2>;
+ vdd-s5-supply = <&vph_pwr>;
+
+ vreg_s5j_1p2: smps5 {
+ regulator-name = "vreg_s5j_1p2";
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l1j_0p8: ldo1 {
+ regulator-name = "vreg_l1j_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2j_1p2: ldo2 {
+ regulator-name = "vreg_l2j_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1256000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3j_0p8: ldo3 {
+ regulator-name = "vreg_l3j_0p8";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+};
+
+&gpu {
+ status = "okay";
+};
+
+&gpu_zap_shader {
+ firmware-name = "qcom/x1p42100/Microsoft/Surface12/qcdxkmsucpurwa.mbn";
+};
+
+&i2c8 {
+ clock-frequency = <1000000>;
+
+ status = "okay";
+
+ touchscreen@16 {
+ compatible = "hid-over-i2c";
+ reg = <0x16>;
+
+ hid-descr-addr = <0x1>;
+ interrupts-extended = <&tlmm 38 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+
+ vddl-supply = <&vreg_l15b_1p8>;
+
+ pinctrl-0 = <&ts0_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+
+ /* MAX34417 @12 */
+ /* MAX34417 @14 */
+ /* MAX34417 @16 */
+ /* MAX34417 @18 */
+ /* MAX34417 @1a */
+
+ status = "okay";
+};
+
+&i2c9 {
+ clock-frequency = <400000>;
+
+ /* NFC @28, commercial devices only */
+
+ status = "okay";
+};
+
+&lpass_tlmm {
+ spkr_01_sd_n_active: spkr-01-sd-n-active-state {
+ pins = "gpio12";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+};
+
+&lpass_vamacro {
+ qcom,dmic-sample-rate = <4800000>;
+
+ vdd-micb-supply = <&vreg_l1b_1p8>;
+
+ pinctrl-0 = <&dmic01_default>;
+ pinctrl-names = "default";
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss_dp1 {
+ status = "okay";
+};
+
+&mdss_dp1_out {
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss_dp3 {
+ /delete-property/ #sound-dai-cells;
+
+ pinctrl-0 = <&edp0_hpd_default>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ aux-bus {
+ panel: panel {
+ compatible = "edp-panel";
+
+ backlight = <&backlight>;
+
+ power-supply = <&vreg_edp_3p3>;
+
+ port {
+ edp_panel_in: endpoint {
+ remote-endpoint = <&mdss_dp3_out>;
+ };
+ };
+ };
+ };
+};
+
+&mdss_dp3_out {
+ data-lanes = <0 1 2 3>;
+ link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
+ remote-endpoint = <&edp_panel_in>;
+};
+
+&mdss_dp3_phy {
+ vdda-phy-supply = <&vreg_l3j_0p8>;
+ vdda-pll-supply = <&vreg_l2j_1p2>;
+
+ status = "okay";
+};
+
+&pcie4 {
+ pinctrl-0 = <&pcie4_default>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&pcie4_phy {
+ vdda-phy-supply = <&vreg_l3i_0p8>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&pcie4_port0 {
+ reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>;
+
+ wifi@0 {
+ compatible = "pci17cb,1107";
+ reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
+ vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+ vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+ };
+};
+
+&pm8550_gpios {
+ vol_up_n_default: vol-up-n-state {
+ pins = "gpio8";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+
+ vol_down_n_default: vol-down-n-state {
+ pins = "gpio6";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+&pmk8550_pwm {
+ status = "okay";
+};
+
+&qupv3_0 {
+ status = "okay";
+};
+
+&qupv3_1 {
+ status = "okay";
+};
+
+&qupv3_2 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/x1p42100/Microsoft/Surface12/qcadsp8380.mbn",
+ "qcom/x1p42100/Microsoft/Surface12/adsp_dtbs.elf";
+
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/x1p42100/Microsoft/Surface12/qccdsp8380.mbn",
+ "qcom/x1p42100/Microsoft/Surface12/cdsp_dtbs.elf";
+
+ status = "okay";
+};
+
+&smb2360_0 {
+ status = "okay";
+};
+
+&smb2360_0_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1 {
+ status = "okay";
+};
+
+&smb2360_1_eusb2_repeater {
+ vdd18-supply = <&vreg_l3d_1p8>;
+ vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&swr0 {
+ pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ /* WSA8845, Left speaker */
+ left_spkr: speaker@0,0 {
+ compatible = "sdw20217020400";
+ reg = <0 0>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SpkrLeft";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ qcom,port-mapping = <1 2 3 7 10 13>;
+ };
+
+ /* WSA8845, Right speaker */
+ right_spkr: speaker@0,1 {
+ compatible = "sdw20217020400";
+ reg = <0 1>;
+ reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SpkrRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ qcom,port-mapping = <4 5 6 7 11 13>;
+ };
+};
+
+&tlmm {
+ gpio-reserved-ranges = <34 2>, /* Unused */
+ <44 4>; /* SPI (TPM) */
+
+ edp_reg_en: edp-reg-en-state {
+ pins = "gpio70";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ hall_int_n_default: hall-int-n-state {
+ pins = "gpio2";
+ function = "gpio";
+ bias-disable;
+ };
+
+ panel_en: panel-en-state {
+ pins = "gpio29";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ pcie4_default: pcie4-default-state {
+ clkreq-n-pins {
+ pins = "gpio147";
+ function = "pcie4_clk";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio146";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ wake-n-pins {
+ pins = "gpio148";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ ssam_state: ssam-state-state {
+ pins = "gpio91";
+ function = "gpio";
+ bias-disable;
+ };
+
+ ts0_default: ts0-default-state {
+ int-n-pins {
+ pins = "gpio38";
+ function = "gpio";
+ bias-disable;
+ };
+
+ reset-n-pins {
+ pins = "gpio48";
+ function = "gpio";
+ output-high;
+ drive-strength = <16>;
+ };
+ };
+
+ wcn_sw_en: wcn-sw-en-state {
+ pins = "gpio214";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ wcn_wlan_bt_en: wcn-wlan-bt-en-state {
+ pins = "gpio116", "gpio117";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ usb_1_ss0_sbu_default: usb-1-ss0-sbu-state {
+ oe-n-pins {
+ pins = "gpio168";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ sel-pins {
+ pins = "gpio167";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+ };
+
+ usb_1_ss1_sbu_default: usb-1-ss1-sbu-state {
+ oe-n-pins {
+ pins = "gpio179";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ sel-pins {
+ pins = "gpio178";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+ };
+};
+
+&uart2 {
+ status = "okay";
+
+ embedded-controller {
+ compatible = "microsoft,surface-sam";
+
+ interrupts-extended = <&tlmm 91 IRQ_TYPE_EDGE_RISING>;
+
+ current-speed = <4000000>;
+
+ pinctrl-0 = <&ssam_state>;
+ pinctrl-names = "default";
+ };
+};
+
+&uart14 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn7850-bt";
+ max-speed = <3200000>;
+
+ vddaon-supply = <&vreg_pmu_aon_0p59>;
+ vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+ vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+ vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+ vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+ vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+ vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>;
+ };
+};
+
+&ufs_mem_hc {
+ vcc-supply = <&vreg_l17b_2p5>;
+ vcc-max-microamp = <800000>;
+ vccq-supply = <&vreg_l2i_1p2>;
+ vccq-max-microamp = <900000>;
+
+ vdd-hba-supply = <&vreg_l3j_0p8>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vreg_l3i_0p8>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+};
+
+&usb_1_ss0_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_0_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss0_qmpphy {
+ vdda-phy-supply = <&vreg_l2j_1p2>;
+ vdda-pll-supply = <&vreg_l1j_0p8>;
+
+ status = "okay";
+};
+
+&usb_1_ss0 {
+ dr_mode = "host";
+
+ status = "okay";
+};
+
+&usb_1_ss0_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss0_hs_in>;
+};
+
+&usb_1_ss0_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss0_ss_in>;
+};
+
+&usb_1_ss1_hsphy {
+ vdd-supply = <&vreg_l3j_0p8>;
+ vdda12-supply = <&vreg_l2j_1p2>;
+
+ phys = <&smb2360_1_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_1_ss1_qmpphy {
+ vdda-phy-supply = <&vreg_l2j_1p2>;
+ vdda-pll-supply = <&vreg_l2d_0p9>;
+
+ status = "okay";
+};
+
+&usb_1_ss1 {
+ dr_mode = "host";
+
+ status = "okay";
+};
+
+&usb_1_ss1_dwc3_hs {
+ remote-endpoint = <&pmic_glink_ss1_hs_in>;
+};
+
+&usb_1_ss1_qmpphy_out {
+ remote-endpoint = <&pmic_glink_ss1_ss_in>;
+};
--
2.53.0
^ permalink raw reply related
* [PATCH] Input: tca8418_keypad - enable overflow mode per datasheet (SCPS215G)
From: Zhian Liang @ 2026-05-29 1:39 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, stable, Zhian Liang
The driver currently sets only the overflow interrupt enable bit
(OVR_FLOW_IEN) in the configuration register, leaving the overflow
mode bit (OVR_FLOW_M) at its default value of 0.
According to the TCA8418 datasheet (SCPS215G, Section 8.6.4.1
"Overflow Errata - Description"), both OVR_FLOW_M (Bit_5) and
OVR_FLOW_IEN (Bit_3) must be set high for the overflow interrupt
to be generated. If only OVR_FLOW_IEN is set, FIFO overflow events
are silently lost without notifying the host.
Fix this by setting OVR_FLOW_M alongside OVR_FLOW_IEN in the
configuration register.
Note: I do not have access to hardware to test this change.
Testing by generating 11+ key events without reading the FIFO
would be appreciated. Full handling of overflow events in the
interrupt handler is left for future improvement.
Signed-off-by: Zhian Liang <liangzhan5dev@gmail.com>
---
drivers/input/keyboard/tca8418_keypad.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index 68c0afafee7b..b124e576feca 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -254,7 +254,7 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
return error;
error = tca8418_write_byte(keypad_data, REG_CFG,
- CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
+ CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_OVR_FLOW_M | CFG_KE_IEN);
return error;
}
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] Input: tca8418_keypad - enable overflow mode per datasheet (SCPS215G)
From: sashiko-bot @ 2026-05-29 2:03 UTC (permalink / raw)
To: Zhian Liang; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260529013900.43854-1-liangzhan5dev@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The driver does not sufficiently validate the hardware keycode, allowing a malformed I2C read to cause an out-of-bounds array access.
- [High] The keypad FIFO read loop lacks an upper iteration bound, risking an infinite loop if the I2C bus fails silently.
--
commit c17e8cb1a67b8fa0dfa772dc4d63c35917e63ccb
Author: Zhian Liang <liangzhan5dev@gmail.com>
Input: tca8418_keypad - enable overflow mode per datasheet (SCPS215G)
This commit sets the OVR_FLOW_M bit alongside OVR_FLOW_IEN in the
configuration register. This ensures the overflow interrupt is properly
generated, preventing FIFO overflow events from being silently lost.
> diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
> index 68c0afafee7bf..b124e576feca4 100644
> --- a/drivers/input/keyboard/tca8418_keypad.c
> +++ b/drivers/input/keyboard/tca8418_keypad.c
> @@ -254,7 +254,7 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
> return error;
>
> error = tca8418_write_byte(keypad_data, REG_CFG,
> - CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
> + CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_OVR_FLOW_M | CFG_KE_IEN);
>
> return error;
> }
While reviewing this, I noticed a couple of potential issues in the same
file.
drivers/input/keyboard/tca8418_keypad.c:tca8418_read_keypad() {
[ ... ]
do {
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
if (error < 0) {
dev_err(&keypad_data->client->dev,
"unable to read REG_KEY_EVENT_A\n");
break;
}
/* Assume that key code 0 signifies empty FIFO */
if (reg <= 0)
break;
[ ... ]
[Severity: High]
This is a pre-existing issue, but does this loop risk running infinitely if
the I2C bus fails silently?
If the I2C bus gets stuck high, it may return 0xFF. Because reg is an
unsigned u8, the condition reg <= 0 evaluates to false for 0xFF (255).
The loop would never terminate, stalling the threaded IRQ handler
indefinitely.
[ ... ]
row = code / TCA8418_MAX_COLS;
col = code % TCA8418_MAX_COLS;
row = (col) ? row : row - 1;
col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
input_event(input, EV_MSC, MSC_SCAN, code);
input_report_key(input, keymap[code], state);
[ ... ]
}
[Severity: High]
This isn't a bug introduced by this patch, but does the driver sufficiently
validate the hardware keycode to prevent an out-of-bounds array access?
If the I2C bus returns 0xFF, code is calculated as 127. The index
calculations yield row = 12 and col = 6, resulting in code = 198.
Since the keymap array allocated for this device has a maximum of 128
elements, this results in an out-of-bounds memory read on keymap[198].
Similarly, a malformed value of 0x80 results in row = -1, col = 9, and
code = 249, causing the same out-of-bounds access.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260529013900.43854-1-liangzhan5dev@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v3 2/2] arm64: dts: qcom: Add Microsoft Surface Pro 12in
From: sashiko-bot @ 2026-05-29 2:15 UTC (permalink / raw)
To: Harrison Vanderbyl
Cc: robh, devicetree, dmitry.torokhov, linux-input, conor+dt
In-Reply-To: <20260529011619.9586-3-harrison.vanderbyl@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] LDO regulators defined across PMICs c, d, e, i, and j are missing their corresponding parent 'vdd-lX-supply' properties.
--
commit ad40084fe87bf7f45bba2d17354ba7647d363116
Author: Harrison Vanderbyl <harrison.vanderbyl@gmail.com>
arm64: dts: qcom: Add Microsoft Surface Pro 12in
This commit introduces the initial device tree for the Microsoft Surface
Pro 12in based on the Snapdragon X Elite platform. It enables basic
hardware support including ufs, touchscreen, display, and various
connectivity peripherals.
> diff --git a/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
> new file mode 100644
> index 0000000000000..983966e123e55
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
[ ... ]
> + regulators-6 {
> + compatible = "qcom,pm8550ve-rpmh-regulators";
> + qcom,pmic-id = "i";
> +
> + vdd-l1-supply = <&vreg_s4c_1p8>;
> + vdd-l2-supply = <&vreg_s5j_1p2>;
> + vdd-s1-supply = <&vph_pwr>;
> + vdd-s2-supply = <&vph_pwr>;
[Severity: High]
Are we missing the parent supply properties (such as vdd-l3-supply) for the
ldos defined across pmics c, d, e, i, and j?
Without linking these child ldos to their active parent buck converters on this
board (for example, vreg_s1i_0p9), the regulator core cannot track the hardware
dependency hierarchy.
Because the parent buck converter has no explicitly recorded consumers in the
device tree, will the Linux regulator core forcefully disable it during late
initcall as an unused regulator?
Since ldos like vreg_l3i_0p8 supply essential components such as the ufs phy,
could this regression disconnect the storage and result in an unavoidable
kernel panic?
> +
> + vreg_s1i_0p9: smps1 {
> + regulator-name = "vreg_s1i_0p9";
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <920000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260529011619.9586-1-harrison.vanderbyl@gmail.com?part=2
^ permalink raw reply
* [PATCH 4/4] dt-bindings: input: remove obsolete matrix-keymap.txt
From: Akash Sukhavasi @ 2026-05-29 5:22 UTC (permalink / raw)
To: devicetree
Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Thierry Reding, Jonathan Hunter, Lee Jones, linux-input,
linux-kernel, linux-tegra
In-Reply-To: <20260529052246.4934-1-akash.sukhavasi@gmail.com>
matrix-keymap.txt has been a single-line redirect to
matrix-keymap.yaml since commit 639d6eda3b80 ("dt-bindings: input:
Convert matrix-keymap to json-schema"), which introduced the .yaml
schema and reduced the .txt to a stub in the same change. The .yaml
has the same filename in the same directory, making this redirect
unnecessary for discoverability.
Eight files still reference matrix-keymap.txt, forcing readers
through an extra hop to reach the .yaml. The stub has not been
touched since June 2020. Update all references across input and mfd
binding documentation to point directly to matrix-keymap.yaml and
remove the stub.
Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
---
Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt | 2 +-
Documentation/devicetree/bindings/input/clps711x-keypad.txt | 2 +-
Documentation/devicetree/bindings/input/matrix-keymap.txt | 1 -
.../devicetree/bindings/input/nvidia,tegra20-kbc.txt | 2 +-
Documentation/devicetree/bindings/input/pxa27x-keypad.txt | 2 +-
Documentation/devicetree/bindings/input/st-keyscan.txt | 2 +-
Documentation/devicetree/bindings/mfd/tc3589x.txt | 6 +++---
7 files changed, 8 insertions(+), 9 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/input/matrix-keymap.txt
diff --git a/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt b/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt
index 262deab73588..33514eba0c9c 100644
--- a/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt
+++ b/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt
@@ -59,7 +59,7 @@ Board Specific Properties:
subsystem (optional).
- linux,keymap: The keymap for keys as described in the binding document
- devicetree/bindings/input/matrix-keymap.txt.
+ devicetree/bindings/input/matrix-keymap.yaml.
Example:
#include "dt-bindings/input/input.h"
diff --git a/Documentation/devicetree/bindings/input/clps711x-keypad.txt b/Documentation/devicetree/bindings/input/clps711x-keypad.txt
index 3eed8819d05d..5f4514c0cd5f 100644
--- a/Documentation/devicetree/bindings/input/clps711x-keypad.txt
+++ b/Documentation/devicetree/bindings/input/clps711x-keypad.txt
@@ -5,7 +5,7 @@ Required Properties:
- row-gpios: List of GPIOs used as row lines.
- poll-interval: Poll interval time in milliseconds.
- linux,keymap: The definition can be found at
- bindings/input/matrix-keymap.txt.
+ bindings/input/matrix-keymap.yaml.
Optional Properties:
- autorepeat: Enable autorepeat feature.
diff --git a/Documentation/devicetree/bindings/input/matrix-keymap.txt b/Documentation/devicetree/bindings/input/matrix-keymap.txt
deleted file mode 100644
index 79f6d01aecaa..000000000000
--- a/Documentation/devicetree/bindings/input/matrix-keymap.txt
+++ /dev/null
@@ -1 +0,0 @@
-This file has been moved to matrix-keymap.yaml
diff --git a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
index 1faa7292e21f..460b64d332cd 100644
--- a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
+++ b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
@@ -12,7 +12,7 @@ Required properties:
- nvidia,kbc-col-pins: The KBC pins which are configured as column. This is an
array of pin numbers which is used as column.
- linux,keymap: The keymap for keys as described in the binding document
- devicetree/bindings/input/matrix-keymap.txt.
+ devicetree/bindings/input/matrix-keymap.yaml.
- clocks: Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets: Must contain an entry for each entry in reset-names.
diff --git a/Documentation/devicetree/bindings/input/pxa27x-keypad.txt b/Documentation/devicetree/bindings/input/pxa27x-keypad.txt
index f8674f7e5ea5..a727d66eece4 100644
--- a/Documentation/devicetree/bindings/input/pxa27x-keypad.txt
+++ b/Documentation/devicetree/bindings/input/pxa27x-keypad.txt
@@ -10,7 +10,7 @@ Required Properties
interval for matrix key. The value is in binary number of 2ms
Optional Properties For Matrix Keyes
-Please refer to matrix-keymap.txt
+Please refer to matrix-keymap.yaml
Optional Properties for Direct Keyes
- marvell,direct-key-count : How many direct keyes are used.
diff --git a/Documentation/devicetree/bindings/input/st-keyscan.txt b/Documentation/devicetree/bindings/input/st-keyscan.txt
index 51eb428e5c85..fd88f40faebf 100644
--- a/Documentation/devicetree/bindings/input/st-keyscan.txt
+++ b/Documentation/devicetree/bindings/input/st-keyscan.txt
@@ -17,7 +17,7 @@ Required properties:
See ../pinctrl/pinctrl-bindings.txt for details.
- linux,keymap: The keymap for keys as described in the binding document
- devicetree/bindings/input/matrix-keymap.txt.
+ devicetree/bindings/input/matrix-keymap.yaml.
- keypad,num-rows: Number of row lines connected to the keypad controller.
diff --git a/Documentation/devicetree/bindings/mfd/tc3589x.txt b/Documentation/devicetree/bindings/mfd/tc3589x.txt
index 4f22b2b07dc5..a6d356e90f42 100644
--- a/Documentation/devicetree/bindings/mfd/tc3589x.txt
+++ b/Documentation/devicetree/bindings/mfd/tc3589x.txt
@@ -48,11 +48,11 @@ Optional nodes:
- compatible : must be "toshiba,tc3589x-keypad"
- debounce-delay-ms : debounce interval in milliseconds
- keypad,num-rows : number of rows in the matrix, see
- bindings/input/matrix-keymap.txt
+ bindings/input/matrix-keymap.yaml
- keypad,num-columns : number of columns in the matrix, see
- bindings/input/matrix-keymap.txt
+ bindings/input/matrix-keymap.yaml
- linux,keymap: the definition can be found in
- bindings/input/matrix-keymap.txt
+ bindings/input/matrix-keymap.yaml
- linux,no-autorepeat: do no enable autorepeat feature.
- wakeup-source: use any event on keypad as wakeup event.
(Legacy property supported: "linux,wakeup")
--
2.54.0
^ permalink raw reply related
* Re: [PATCH 02/10] [v3] input: gpio-keys: make legacy gpiolib optional
From: Dmitry Torokhov @ 2026-05-29 5:37 UTC (permalink / raw)
To: Linus Walleij
Cc: Arnd Bergmann, linux-gpio, linux-kernel, Arnd Bergmann,
Christian Lamparter, Johannes Berg, Aaro Koskinen,
Andreas Kemnade, Kevin Hilman, Roger Quadros, Tony Lindgren,
Thomas Bogendoerfer, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Bartosz Golaszewski, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev
In-Reply-To: <CAD++jLnYeh3GfEfNXfCYdcdg_j2RAU63TYewwaTx3tm0tM531w@mail.gmail.com>
On Mon, May 25, 2026 at 10:57:44AM +0200, Linus Walleij wrote:
> On Wed, May 20, 2026 at 8:38 PM Arnd Bergmann <arnd@kernel.org> wrote:
>
> > From: Arnd Bergmann <arnd@arndb.de>
> >
> > Most users of gpio-keys and gpio-keys-polled use modern gpiolib
> > interfaces, but there are still number of ancient sh, arm32 and x86
> > machines that have never been converted.
> >
> > Add an #ifdef block for the parts of the driver that are only used on
> > those legacy machines.
> >
> > The two Rohm PMIC drivers use a gpio-keys device without an actual GPIO,
> > passing an IRQ number instead. In order to keep this working both with
> > and with CONFIG_GPIOLIB_LEGACY, change the gpio-keys driver to ignore
> > the gpio number if an IRQ is passed.
> >
> > Link: https://lore.kernel.org/all/b3c94552-c104-42e3-be15-7e8362e8039e@gmail.com/
> > Link: https://lore.kernel.org/all/afJXG4_rtaj3l2Dk@google.com/
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>
> Reviewed-by: Linus Walleij <linusw@kernel.org>
OK, if Lee Acks MFD changes I can pick this up.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v8 2/2] Input: Add support for Wacom W9000-series penabled touchscreens
From: Dmitry Torokhov @ 2026-05-29 5:42 UTC (permalink / raw)
To: Hendrik Noack
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ferass El Hafidi,
linux-input, devicetree, linux-kernel
In-Reply-To: <20260528074818.12151-3-hendrik-noack@gmx.de>
Hi Hendrik,
On Thu, May 28, 2026 at 09:48:18AM +0200, Hendrik Noack wrote:
> +
> +struct wacom_w9000_data {
> + struct i2c_client *client;
> + struct input_dev *input_dev;
> + const struct wacom_w9000_variant *variant;
> + u16 fw_version;
> +
> + struct touchscreen_properties prop;
> + u16 max_pressure;
> +
> + struct regulator *regulator;
> + bool powered;
We do not really need this flag as ling as you use
input_device_enabled() in wacom_w9000_suspend().
...
> +
> + dev_dbg(dev, "max_x:%d, max_y:%d, max_pressure:%d, fw:%#x", wacom_data->prop.max_x,
> + wacom_data->prop.max_y, wacom_data->max_pressure,
> + wacom_data->fw_version);
Here and in couple of other places we miss '\n' in the diagnostic
messages.
> +
> + input_dev->name = wacom_data->variant->name;
> + input_dev->id.bustype = BUS_I2C;
> + input_dev->dev.parent = dev;
This is not needed: devm_input_allocate_device() sets the patent for us.
No need to resubmit, I made edits on my end.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v10 1/4] HID: hid-msi: Add MSI Claw configuration driver
From: Derek John Clark @ 2026-05-29 6:34 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jiri Kosina, Benjamin Tissoires, Pierre-Loup A . Griffais,
Denis Benato, Zhouwang Huang, linux-input, linux-doc,
linux-kernel
In-Reply-To: <ahfQW54YoHj2Pal_@google.com>
On Wed, May 27, 2026 at 10:32 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> Hi Derek,
>
> On Wed, May 27, 2026 at 10:21:19PM +0000, Derek J. Clark wrote:
> > Adds configuration HID driver for the MSI Claw series of handheld PC's.
> > In this initial patch add the initial driver outline and attributes for
> > changing the gamepad mode, M-key behavior, and add a WO reset function.
> >
> > Sending the SWITCH_MODE and RESET commands causes a USB disconnect in
> > the device. The completion will therefore never get hit and would trigger
> > an -EIO. To avoid showing the user an error for every write to these
> > attrs a bypass for the completion handling is introduced when timeout ==
> > 0.
> >
> > The initial version of this patch was written by Denis Benato, which
> > contained the initial reverse-engineering and implementation for the
> > gamepad mode switching. This work was later expanded by Zhouwang Huang
> > to include more gamepad modes. Finally, I refactored the drivers data
> > in/out flow and overall format to conform to kernel driver best
> > practices and style guides. Claude was used as an initial reviewer of
> > this patch.
>
> I wonder why do you need to roll asynchronous probing and asynchronous
> resume by hand? This I think complicates the driver greatly and forces
> you to use a ton of works, spinlocks, and checks.
>
> Thanks.
>
Hi Dmitry,
I suppose being asked this means my cover letter and commit
descriptions need some additional context. The MCU in these Claw
devices is quite temperamental. There are a few specific issues that
cause the need for multiple work queues, a serialization mutex, and
subsequently spinlocks to prevent stale data reads.
1.) The MCU will halt function if it receives any output reports
before ~500MS after probe or resume. This can either manifest as the
device never responding to a command, or it can cause the entire
system to become unstable and reboot. This creates the need for
cfg_setup to query the MCU and then add the gamepad attrs, led_mc
device, and rgb attrs. As a side effect, because a system could
technically be suspended during that 500ms delay, there exists the
need to re-queue the work if it was never triggered, hence the resume
queue.
2.) The MCU will not always respond in order if two or more output
reports are sent within a few ms of each other. Since many of the
commands use a generic "ACK", or share an "ACK" type but don't provide
specific context about what sub-function called them, we could
potentially have cross talk where data is saved in the wrong attribute
or errors propagate because of a missed message. To get around this
serialization issue we hold a mutex through a completion triggered in
raw_event and, for most events, save a state machine on what command
is expected and what sub-command was the initiator. (I.E. profile
events handle the M1, M2, RGB, Left rumble, and right rumble). Since
the state machine is accessed on both sides, we need spinlocks
guarding the reads. This essentially serializes the data and makes it
predictable. Using this pattern I haven't had any issues reading from
or writing to the MCU.
3.) Some commands will never return their "ACK" while a completion is
held, so we have a workaround to basically ignore them and hope the
command worked. This is only needed for SYNC_TO_ROM, from which we
don't need to set anything on its "ACK", and switching the gamepad
mode, which causes USB disconnect/reconnect and the driver fully
reloads, so we'll never be able to read it anyway.
4.) The RGB work queue is used to free the userspace write while the
completion is held. I found that use without it could stall userspace
quite significantly if it has multiple writes back to back. I
experienced this using Steam's customization menu, which sends a
single write for every increment of its color and brightness sliders.
when traversing the full length of the slider it is possible to have
effects changing for nearly a minute after stopping. With the queue,
only the most recent write is eventually sent to the MCU. This issue
also affects the Go 2 driver as well, though not to the same extent,
but for which I'll be adding a similar de-bounce queue soon. Go S is
also technically affected by this bug, but that returns quickly enough
that it isn't really feasible to trigger the bug with much frequency.
I'll still fix that one as well though.
TBH I'm not "happy" with the complexity of the driver, but I don't see
a reasonable alternative. If you have any specific suggestions that I
could try that might simplify it, I'd be more than happy to give it a
shot. That being said, I'm not very optimistic about it. Development
on this device has been like wrestling a bear.
- Derek
> --
> 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