* Re: [PATCH RFC 3/4] Input: gpio-keys - add regulator to gpio_keys
From: sashiko-bot @ 2026-05-08 21:36 UTC (permalink / raw)
To: Griffin Kroah-Hartman
Cc: linux-input, robh, krzk+dt, dmitry.torokhov, conor+dt, devicetree
In-Reply-To: <20260508-gpiokeys-vdd-supply-v1-3-0bb32e8e6428@fairphone.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Tying the regulator's power state to the input device's open()/close() lifecycle leaves interrupts active while the hardware is unpowered, causing an interrupt storm.
- [Medium] System wakeup functionality is broken because regulators are disabled if the input device is closed.
- [Medium] Unsafe hardware access during system resume causes spurious key events.
- [Medium] Missing pdata->disable() in the gpio_keys_open() error path leads to a resource leak.
- [Low] Incorrect teardown order in gpio_keys_close() violates LIFO symmetry.
--
commit d47e6012a488ac21d0005ba6dd4aa95a285831d3
Author: Griffin Kroah-Hartman <griffin.kroah@fairphone.com>
Input: gpio-keys - add regulator to gpio_keys
This commit allows gpio-keys to have a vdd power supply managed through
regulators.
> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
> index e196174856796..2199ce7455cfc 100644
> --- a/drivers/input/keyboard/gpio_keys.c
> +++ b/drivers/input/keyboard/gpio_keys.c
[ ... ]
> @@ -729,6 +730,7 @@ static int gpio_keys_open(struct input_dev *input)
> struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
> const struct gpio_keys_platform_data *pdata = ddata->pdata;
> int error;
> + int i;
>
> if (pdata->enable) {
> error = pdata->enable(input->dev.parent);
> @@ -736,19 +738,48 @@ static int gpio_keys_open(struct input_dev *input)
> return error;
> }
>
> + for (i = 0; i < pdata->nbuttons; i++) {
> + const struct gpio_keys_button *button = &pdata->buttons[i];
> +
> + if (!button->regulator)
> + continue;
> + error = regulator_enable(button->regulator);
> + if (error)
> + goto reg_err;
> + }
Because interrupts are requested unconditionally in gpio_keys_probe() and
remain unmasked, tying the regulator power state to the input device's
open()/close() lifecycle leaves the physical button unpowered when the device
is closed. Could this allow the GPIO pin to float and trigger an interrupt
storm?
Also, if the input device is closed before suspend, the regulator remains
disabled. Does this prevent an unpowered physical button from generating the
electrical signal required to trigger a wakeup interrupt?
Additionally, gpio_keys_resume() unconditionally calls
gpio_keys_report_state(), which reads the current state of all GPIOs. If the
device is closed, the regulators are powered off. Can reading unpowered GPIOs
return floating states that inject spurious phantom key press events on every
resume?
> +
> /* Report current state of buttons that are connected to GPIOs */
> gpio_keys_report_state(ddata);
>
> return 0;
> +
> +reg_err:
> + for (--i; i >= 0; i--) {
> + const struct gpio_keys_button *button = &pdata->buttons[i];
> +
> + if (!button->regulator)
> + continue;
> + regulator_disable(button->regulator);
> + }
> + return error;
If regulator_enable() fails and we jump to reg_err, we return the error but
fail to call pdata->disable(). Does this leave the platform state permanently
active and leak resources since pdata->enable() was called earlier?
> }
>
> static void gpio_keys_close(struct input_dev *input)
> {
> struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
> const struct gpio_keys_platform_data *pdata = ddata->pdata;
> + int i;
>
> if (pdata->disable)
> pdata->disable(input->dev.parent);
> +
> + for (i = 0; i < pdata->nbuttons; i++) {
> + const struct gpio_keys_button *button = &pdata->buttons[i];
> +
> + if (!button->regulator)
> + continue;
> + regulator_disable(button->regulator);
> + }
> }
Is the teardown order correct here? In gpio_keys_open(), pdata->enable() is
called before the regulators are enabled. Should gpio_keys_close() reverse
this sequence by disabling the regulators before calling pdata->disable() to
maintain LIFO symmetry?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260508-gpiokeys-vdd-supply-v1-0-0bb32e8e6428@fairphone.com?part=3
^ permalink raw reply
* Re: [PATCH RFC 4/4] arm64: dts: qcom: milos-fairphone-fp6: add supply for Hall Effect sensor
From: sashiko-bot @ 2026-05-08 21:56 UTC (permalink / raw)
To: Griffin Kroah-Hartman
Cc: robh, conor+dt, linux-input, krzk+dt, devicetree, dmitry.torokhov
In-Reply-To: <20260508-gpiokeys-vdd-supply-v1-4-0bb32e8e6428@fairphone.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Removing `regulator-always-on` from the Hall sensor's supply causes interrupt storms, spurious events, and broken system wakeup when the input device is closed.
--
commit 35bf0d08eef4da2139153f5425e351a93d9d591d
Author: Griffin Kroah-Hartman <griffin.kroah@fairphone.com>
arm64: dts: qcom: milos-fairphone-fp6: add supply for Hall Effect sensor
This commit adds a vdd-supply property to the Hall Effect sensor and removes
the regulator-always-on property from vreg_l10b, relying on the gpio-keys
driver to manage power.
> diff --git a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
> index c1899db46e714..ae6900c3f75c6 100644
> --- a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
> +++ b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
> @@ -32,13 +32,13 @@ gpio-keys {
> pinctrl-0 = <&volume_up_default>, <&hall_sensor_default>;
> pinctrl-names = "default";
>
> - /* Powered by the always-on vreg_l10b */
> event-hall-sensor {
> label = "Hall Effect Sensor";
> gpios = <&tlmm 70 GPIO_ACTIVE_LOW>;
> linux,input-type = <EV_SW>;
> linux,code = <SW_LID>;
> linux,can-disable;
> + vdd-supply = <&vreg_l10b>;
When the device is opened, the driver reads the GPIO state immediately after
enabling the regulator. Without a startup-delay-us property on the regulator
to allow the voltage to stabilize, could this read an uninitialized state and
generate spurious lid events?
> wakeup-source;
> };
>
[ ... ]
> @@ -326,8 +326,6 @@ vreg_l10b: ldo10 {
> regulator-min-microvolt = <1800000>;
> regulator-max-microvolt = <1800000>;
> regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> - /* Hall sensor VDD */
> - regulator-always-on;
> };
Could removing this property cause an interrupt storm?
The gpio-keys driver requests and unmasks the GPIO interrupt during probe, but
only enables the vdd-supply regulator when the input device is explicitly
opened by userspace.
If the device is closed, the regulator is disabled. Cutting power to the Hall
sensor while its edge-triggered interrupt remains active might cause the GPIO
line to float. A floating line can pick up electrical noise and trigger a
continuous interrupt storm.
Additionally, does this break the system's ability to wake up?
If the system suspends while the device is closed, the sensor remains
unpowered. Even though the wake IRQ is armed due to the wakeup-source
property, an unpowered sensor wouldn't be able to detect lid events to wake
the system.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260508-gpiokeys-vdd-supply-v1-0-0bb32e8e6428@fairphone.com?part=4
^ permalink raw reply
* Re: [PATCH RESEND 2] HID: Add force feedback support for Speedlink Cougar Vibration Flightstick
From: sashiko-bot @ 2026-05-08 22:51 UTC (permalink / raw)
To: Harald Judt; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <b3bfa73b-0547-45f9-b6ae-f28815e6c632@gmx.at>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Race condition in force feedback initialization leading to a NULL pointer dereference.
- [High] Ignoring the return value of `gembird_joy_init()` causes a NULL pointer dereference when user-space interacts with the event device after an initialization failure.
- [High] Non-monotonic magnitude scaling logic severely breaks force feedback functionality.
- [Medium] Memory leak of the `gembird_joy_device` state structure upon device disconnect.
--
commit f9141496ab06cd22000d2487bbb234d7e91931b5
Author: Harald Judt <h.judt@gmx.at>
HID: Add force feedback support for Gembird based joystick
This commit adds force feedback (rumble) support for the SpeedLink Cougar
Vibration Flightstick (SL-6630) joystick, which uses a Gembird controller.
> diff --git a/drivers/hid/hid-gembird-joy.c b/drivers/hid/hid-gembird-joy.c
> new file mode 100644
> index 0000000000000..5a5afa02f8407
> --- /dev/null
> +++ b/drivers/hid/hid-gembird-joy.c
[ ... ]
> +static int hid_gembird_joy_play(struct input_dev *dev, void *data,
> + struct ff_effect *effect)
> +{
> + struct hid_device *hid = input_get_drvdata(dev);
> + struct gembird_joy_device *joy = data;
> + int strong, weak;
> +
> + strong = effect->u.rumble.strong_magnitude;
> + weak = effect->u.rumble.weak_magnitude;
[ ... ]
> + strong = (strong / 0xff) * 0x1f / 0xff;
> + weak = (weak / 0xff) * 0x1f / 0xff;
> +
> + /* ... and to support the notions of strong vs weak rumble effects,
> + * increase the magnitude for the strong rumble effect if it is below the
> + * half of the maximum value, as the strong motor has the same strength as
> + * the weak one. Likewise, decrease the magnitude for the weak effect.
> + */
> + if (strong < 0x10 && !weak) /* fftest effect 4 strong rumble */
> + strong *= 2;
> + else if (!strong && weak >= 0x10) /* fftest effect 5 weak rumble */
> + weak /= 2;
Will this cause issues with non-monotonic force feedback behavior and
unintended truncation?
Since the math uses integer division, any input value below 255 for strong
or weak will evaluate to zero during the first division by 0xff.
Additionally, could the conditional scaling cause abrupt changes in rumble
strength? For instance, if a game requests a strong magnitude that scales
down to 15, it gets doubled to 30 because of the strong < 0x10 check.
However, a slightly stronger requested magnitude that scales to 16 will
remain 16, meaning an increase in requested strength results in a drop in
physical rumble.
[ ... ]
> +static int gembird_joy_init(struct hid_device *hid)
> +{
[ ... ]
> + joy = kzalloc(sizeof(struct gembird_joy_device), GFP_KERNEL);
> + if (!joy)
> + return -ENOMEM;
Does this memory leak when the device is disconnected or the driver is
unbound? The allocation doesn't use devm_kzalloc, and there isn't a
remove callback to free it. The input_ff_create_memless teardown
handles its own structures but not the user-provided private data.
> +
> + dev = hidinput->input;
> +
> + set_bit(FF_RUMBLE, dev->ffbit);
> +
> + error = input_ff_create_memless(dev, joy, hid_gembird_joy_play);
> + if (error) {
> + kfree(joy);
> + return error;
> + }
> +
> + joy->report = report;
Is there a window here where an ioctl could trigger a NULL pointer
dereference?
The device was already started earlier in gembird_joy_probe via
hid_hw_start, so userspace can issue an EVIOCSFF ioctl as soon as
input_ff_create_memless succeeds. If the ioctl triggers
hid_gembird_joy_play before joy->report is assigned on the next line,
the callback will try to access joy->report->field and dereference NULL.
[ ... ]
> +static int gembird_joy_probe(struct hid_device *hdev, const struct hid_device_id *id)
> +{
> + int ret;
> +
> + ret = hid_parse(hdev);
> + if (ret) {
> + hid_err(hdev, "parse failed\n");
> + return ret;
> + }
> +
> + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
> + if (ret) {
> + hid_err(hdev, "hw start failed\n");
> + return ret;
> + }
> +
> + gembird_joy_init(hdev);
> +
> + return 0;
> +}
What happens if gembird_joy_init fails?
If input_ff_create_memless returns an error, gembird_joy_init
propagates it, but the return value is ignored here and probe succeeds.
Because set_bit(FF_RUMBLE, dev->ffbit) was already called, the device
remains registered and advertises rumble support. If userspace then issues
an EVIOCSFF ioctl, the kernel will allow it, which could lead to a panic
when it tries to dereference the missing force feedback structures.
--
Sashiko AI review · https://sashiko.dev/#/patchset/b3bfa73b-0547-45f9-b6ae-f28815e6c632@gmx.at?part=1
^ permalink raw reply
* Re: [PATCH RESEND 2] HID: Add force feedback support for Speedlink Cougar Vibration Flightstick
From: Dmitry Torokhov @ 2026-05-08 23:14 UTC (permalink / raw)
To: sashiko; +Cc: Harald Judt, linux-input
In-Reply-To: <20260508225130.C6D33C2BCB0@smtp.kernel.org>
On Fri, May 08, 2026 at 10:51:30PM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] Race condition in force feedback initialization leading to a NULL pointer dereference.
> - [High] Ignoring the return value of `gembird_joy_init()` causes a NULL pointer dereference when user-space interacts with the event device after an initialization failure.
> - [High] Non-monotonic magnitude scaling logic severely breaks force feedback functionality.
> - [Medium] Memory leak of the `gembird_joy_device` state structure upon device disconnect.
> --
>
> commit f9141496ab06cd22000d2487bbb234d7e91931b5
> Author: Harald Judt <h.judt@gmx.at>
>
> HID: Add force feedback support for Gembird based joystick
>
> This commit adds force feedback (rumble) support for the SpeedLink Cougar
> Vibration Flightstick (SL-6630) joystick, which uses a Gembird controller.
>
> > diff --git a/drivers/hid/hid-gembird-joy.c b/drivers/hid/hid-gembird-joy.c
> > new file mode 100644
> > index 0000000000000..5a5afa02f8407
> > --- /dev/null
> > +++ b/drivers/hid/hid-gembird-joy.c
>
> [ ... ]
>
> > +static int hid_gembird_joy_play(struct input_dev *dev, void *data,
> > + struct ff_effect *effect)
> > +{
> > + struct hid_device *hid = input_get_drvdata(dev);
> > + struct gembird_joy_device *joy = data;
> > + int strong, weak;
> > +
> > + strong = effect->u.rumble.strong_magnitude;
> > + weak = effect->u.rumble.weak_magnitude;
>
> [ ... ]
>
> > + strong = (strong / 0xff) * 0x1f / 0xff;
> > + weak = (weak / 0xff) * 0x1f / 0xff;
> > +
> > + /* ... and to support the notions of strong vs weak rumble effects,
> > + * increase the magnitude for the strong rumble effect if it is below the
> > + * half of the maximum value, as the strong motor has the same strength as
> > + * the weak one. Likewise, decrease the magnitude for the weak effect.
> > + */
> > + if (strong < 0x10 && !weak) /* fftest effect 4 strong rumble */
> > + strong *= 2;
> > + else if (!strong && weak >= 0x10) /* fftest effect 5 weak rumble */
> > + weak /= 2;
>
> Will this cause issues with non-monotonic force feedback behavior and
> unintended truncation?
>
> Since the math uses integer division, any input value below 255 for strong
> or weak will evaluate to zero during the first division by 0xff.
>
> Additionally, could the conditional scaling cause abrupt changes in rumble
> strength? For instance, if a game requests a strong magnitude that scales
> down to 15, it gets doubled to 30 because of the strong < 0x10 check.
> However, a slightly stronger requested magnitude that scales to 16 will
> remain 16, meaning an increase in requested strength results in a drop in
> physical rumble.
>
> [ ... ]
>
> > +static int gembird_joy_init(struct hid_device *hid)
> > +{
>
> [ ... ]
>
> > + joy = kzalloc(sizeof(struct gembird_joy_device), GFP_KERNEL);
> > + if (!joy)
> > + return -ENOMEM;
>
> Does this memory leak when the device is disconnected or the driver is
> unbound? The allocation doesn't use devm_kzalloc, and there isn't a
> remove callback to free it. The input_ff_create_memless teardown
> handles its own structures but not the user-provided private data.
Sashiko is wrong here.
>
> > +
> > + dev = hidinput->input;
> > +
> > + set_bit(FF_RUMBLE, dev->ffbit);
> > +
> > + error = input_ff_create_memless(dev, joy, hid_gembird_joy_play);
> > + if (error) {
> > + kfree(joy);
> > + return error;
> > + }
> > +
> > + joy->report = report;
>
> Is there a window here where an ioctl could trigger a NULL pointer
> dereference?
>
> The device was already started earlier in gembird_joy_probe via
> hid_hw_start, so userspace can issue an EVIOCSFF ioctl as soon as
> input_ff_create_memless succeeds. If the ioctl triggers
> hid_gembird_joy_play before joy->report is assigned on the next line,
> the callback will try to access joy->report->field and dereference NULL.
Sashiko is wrong here as well. The device is not accessible from
userspace until it is registered.
>
> [ ... ]
>
> > +static int gembird_joy_probe(struct hid_device *hdev, const struct hid_device_id *id)
> > +{
> > + int ret;
> > +
> > + ret = hid_parse(hdev);
> > + if (ret) {
> > + hid_err(hdev, "parse failed\n");
> > + return ret;
> > + }
> > +
> > + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
> > + if (ret) {
> > + hid_err(hdev, "hw start failed\n");
> > + return ret;
> > + }
> > +
> > + gembird_joy_init(hdev);
> > +
> > + return 0;
> > +}
>
> What happens if gembird_joy_init fails?
>
> If input_ff_create_memless returns an error, gembird_joy_init
> propagates it, but the return value is ignored here and probe succeeds.
>
> Because set_bit(FF_RUMBLE, dev->ffbit) was already called, the device
> remains registered and advertises rumble support. If userspace then issues
> an EVIOCSFF ioctl, the kernel will allow it, which could lead to a panic
> when it tries to dereference the missing force feedback structures.
>
Need to have error handling.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] Input: analog: replace deprecated simple_strtoul() with kstrtouint()
From: Akash Sukhavasi @ 2026-05-09 2:40 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Akash Sukhavasi
The simple_strtoul() function is deprecated because it ignores
trailing garbage characters, which can mask typos in input.
Replace it with kstrtouint() in analog_parse_options() to enforce
strict input parsing.
Note that this introduces a minor, intended behavior change: while
the old code would silently parse a malformed string like "12abc"
as 12, the new code will reject it entirely and fall back to the
unconfigured state (0xff). This strict parsing is the preferred
modern behavior for kernel parameters.
Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
---
drivers/input/joystick/analog.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index b6f7bce1c..07ad360f8 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -653,7 +653,7 @@ static struct analog_types analog_types[] = {
static void analog_parse_options(void)
{
int i, j;
- char *end;
+ unsigned int parsed_val;
for (i = 0; i < js_nargs; i++) {
@@ -664,8 +664,10 @@ static void analog_parse_options(void)
}
if (analog_types[j].name) continue;
- analog_options[i] = simple_strtoul(js[i], &end, 0);
- if (end != js[i]) continue;
+ if (kstrtouint(js[i], 0, &parsed_val) == 0) {
+ analog_options[i] = parsed_val;
+ continue;
+ }
analog_options[i] = 0xff;
if (!strlen(js[i])) continue;
--
2.54.0
^ permalink raw reply related
* [PATCH] HID: i2c-hid: add reset quirk for BLTP7853 touchpad
From: Xu Rao @ 2026-05-09 8:21 UTC (permalink / raw)
To: jikos, bentiss; +Cc: linux-input, linux-kernel, raoxu
The BLTP7853 I2C HID touchpad may fail to probe after reboot or
reprobe because reset completion is not signalled to the host. The
driver then waits for the reset-complete interrupt until it times out
and the device probe fails:
i2c_hid i2c-BLTP7853:00: failed to reset device.
i2c_hid i2c-BLTP7853:00: can't add hid device: -61
i2c_hid: probe of i2c-BLTP7853:00 failed with error -61
Add I2C_HID_QUIRK_NO_IRQ_AFTER_RESET for the device so i2c-hid does
not wait for a reset interrupt that may never arrive.
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/hid/hid-ids.h | 3 +++
drivers/hid/i2c-hid/i2c-hid-core.c | 2 ++
2 files changed, 5 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 0cf63742315b..dcb0b34cd069 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -277,6 +277,9 @@
#define USB_VENDOR_ID_BIGBEN 0x146b
#define USB_DEVICE_ID_BIGBEN_PS3OFMINIPAD 0x0902
+#define I2C_VENDOR_ID_BLTP 0x36b6
+#define I2C_PRODUCT_ID_BLTP7853 0xc001
+
#define USB_VENDOR_ID_BTC 0x046e
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 5a183af3d5c6..baff2728603e 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -149,6 +149,8 @@ static const struct i2c_hid_quirks {
I2C_HID_QUIRK_BOGUS_IRQ },
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
+ { I2C_VENDOR_ID_BLTP, I2C_PRODUCT_ID_BLTP7853,
+ I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
{ 0, 0 }
};
--
2.50.1
^ permalink raw reply related
* [PATCH] HID: mcp2221: fix OOB write in mcp2221_raw_event()
From: Florian Pradines @ 2026-05-09 9:45 UTC (permalink / raw)
To: gupt21, jikos, bentiss; +Cc: linux-i2c, linux-input, Florian Pradines
mcp2221_raw_event() copies device-supplied data into mcp->rxbuf at
offset rxbuf_idx without checking that the copy fits within the
destination buffer. A device responding with up to 60 bytes to a
small I2C/SMBus read can overflow the buffer.
Add a rxbuf_size field to struct mcp2221, set it alongside rxbuf in
mcp_i2c_smbus_read(), and check rxbuf_idx + data[3] <= rxbuf_size
before the memcpy.
Signed-off-by: Florian Pradines <florian.pradines@gmail.com>
---
drivers/hid/hid-mcp2221.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index be80970ab48e..e4ddd8e9293b 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -128,6 +128,7 @@ struct mcp2221 {
u8 *rxbuf;
u8 txbuf[64];
int rxbuf_idx;
+ int rxbuf_size;
int status;
u8 cur_i2c_clk_div;
struct gpio_chip *gc;
@@ -330,12 +331,14 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp,
mcp->txbuf[3] = (u8)(msg->addr << 1);
total_len = msg->len;
mcp->rxbuf = msg->buf;
+ mcp->rxbuf_size = msg->len;
} else {
mcp->txbuf[1] = smbus_len;
mcp->txbuf[2] = 0;
mcp->txbuf[3] = (u8)(smbus_addr << 1);
total_len = smbus_len;
mcp->rxbuf = smbus_buf;
+ mcp->rxbuf_size = smbus_len;
}
ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4);
@@ -919,6 +922,10 @@ static int mcp2221_raw_event(struct hid_device *hdev,
mcp->status = -EINVAL;
break;
}
+ if (mcp->rxbuf_idx + data[3] > mcp->rxbuf_size) {
+ mcp->status = -EINVAL;
+ break;
+ }
buf = mcp->rxbuf;
memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];
--
2.47.3
^ permalink raw reply related
* Re: [PATCH] Input: analog: replace deprecated simple_strtoul() with kstrtouint()
From: David Laight @ 2026-05-09 9:55 UTC (permalink / raw)
To: Akash Sukhavasi; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <20260509024048.46132-1-akash.sukhavasi@gmail.com>
On Fri, 8 May 2026 21:40:48 -0500
Akash Sukhavasi <akash.sukhavasi@gmail.com> wrote:
> The simple_strtoul() function is deprecated because it ignores
> trailing garbage characters, which can mask typos in input.
>
> Replace it with kstrtouint() in analog_parse_options() to enforce
> strict input parsing.
>
> Note that this introduces a minor, intended behavior change: while
> the old code would silently parse a malformed string like "12abc"
> as 12, the new code will reject it entirely and fall back to the
> unconfigured state (0xff). This strict parsing is the preferred
> modern behavior for kernel parameters.
However that might break existing systems.
So I'm not at all sure it should be done.
David
>
> Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
> ---
> drivers/input/joystick/analog.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
> index b6f7bce1c..07ad360f8 100644
> --- a/drivers/input/joystick/analog.c
> +++ b/drivers/input/joystick/analog.c
> @@ -653,7 +653,7 @@ static struct analog_types analog_types[] = {
> static void analog_parse_options(void)
> {
> int i, j;
> - char *end;
> + unsigned int parsed_val;
>
> for (i = 0; i < js_nargs; i++) {
>
> @@ -664,8 +664,10 @@ static void analog_parse_options(void)
> }
> if (analog_types[j].name) continue;
>
> - analog_options[i] = simple_strtoul(js[i], &end, 0);
> - if (end != js[i]) continue;
> + if (kstrtouint(js[i], 0, &parsed_val) == 0) {
> + analog_options[i] = parsed_val;
> + continue;
> + }
>
> analog_options[i] = 0xff;
> if (!strlen(js[i])) continue;
^ permalink raw reply
* [PATCH v3 0/9] iio: introduce devm_ API for hid sensro setup and cleanup
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Key highlights:
- Prepare change as pre-requisite for devm conversion for HID IIO
drivers by removing redundant argument
- Add devm API to setup trigger and clenaup resource using
devm_add_action_or_reset()
- few cleanup and prepratory changes before updating driver for devm_
- few sample driver update using devm conversion to auto release resource
changes in v3:
- Added cleanup and prepratory changes before adding devm_ API
conversion based on self review: 0002, 0004, 0006, 0007 and 0008
- Address andy's review comment on commit message and coding style
- v2 series -> https://lore.kernel.org/all/20260429175918.2541914-1-sanjayembedded@gmail.com/
changes in v2:
- Following input from Jonathan and Andy, squash initial patch v1
series in single change as individual change should not break anything
- Add devm API support and two driver using the same
- v1 series -> https://lore.kernel.org/all/20260428071613.1134053-1-sanjayembedded@gmail.com/
Testing:
- Compiled with W=1
- Build-tested on QEMU x86_64
Based on further feedback and reviews, I would extend this series to convert all HID IIO driver to use devm_* API.
Thanks,
Sanjay Chitroda
Sanjay Chitroda (9):
iio: hid-sensors: drop redundant iio_dev argument
iio: hid-sensors: cleanup codestyle warning
iio: hid-sensors: introduce device managed API
iio: gyro: hid-sensor-gyro-3d: cleanup codestyle warning
iio: gyro: hid-sensor-gyro-3d: drop hid_sensor_remove_trigger() using
devm API
iio: humidity: hid-sensor-humidity: cleanup codestyle check
iio: humidity: hid-sensor-humidity: use common device for devres
iio: humidity: hid-sensor-humidity: use local struct device
iio: humidity: hid-sensor-humidity: drop hid_sensor_remove_trigger()
using devm API
drivers/iio/accel/hid-sensor-accel-3d.c | 4 +-
.../common/hid-sensors/hid-sensor-trigger.c | 24 +++++++-
.../common/hid-sensors/hid-sensor-trigger.h | 5 +-
drivers/iio/gyro/hid-sensor-gyro-3d.c | 16 ++---
drivers/iio/humidity/hid-sensor-humidity.c | 61 +++++++++----------
drivers/iio/light/hid-sensor-als.c | 4 +-
drivers/iio/light/hid-sensor-prox.c | 4 +-
drivers/iio/magnetometer/hid-sensor-magn-3d.c | 4 +-
drivers/iio/orientation/hid-sensor-incl-3d.c | 4 +-
drivers/iio/orientation/hid-sensor-rotation.c | 4 +-
.../position/hid-sensor-custom-intel-hinge.c | 4 +-
drivers/iio/pressure/hid-sensor-press.c | 4 +-
.../iio/temperature/hid-sensor-temperature.c | 4 +-
13 files changed, 78 insertions(+), 64 deletions(-)
base-commit: 39b80c5c9830d12d2d6531059001301c4265322a
--
2.34.1
^ permalink raw reply
* [PATCH v3 1/9] iio: hid-sensors: drop redundant iio_dev argument
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
hid_sensor_remove_trigger() uses struct hid_sensor_common to release
resources acquired during trigger setup.
Earlier implementations required struct iio_dev to clean up buffers,
but with the current code this argument is no longer used and is
redundant.
Adapt to hid_sensor_remove_trigger() API change across all HID IIO
drivers to match updated prototype.
Removing it simplifies the API and is a preparatory step toward
converting the trigger handling to a devm-based API.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/accel/hid-sensor-accel-3d.c | 4 ++--
drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 3 +--
drivers/iio/common/hid-sensors/hid-sensor-trigger.h | 3 +--
drivers/iio/gyro/hid-sensor-gyro-3d.c | 4 ++--
drivers/iio/humidity/hid-sensor-humidity.c | 4 ++--
drivers/iio/light/hid-sensor-als.c | 4 ++--
drivers/iio/light/hid-sensor-prox.c | 4 ++--
drivers/iio/magnetometer/hid-sensor-magn-3d.c | 4 ++--
drivers/iio/orientation/hid-sensor-incl-3d.c | 4 ++--
drivers/iio/orientation/hid-sensor-rotation.c | 4 ++--
drivers/iio/position/hid-sensor-custom-intel-hinge.c | 4 ++--
drivers/iio/pressure/hid-sensor-press.c | 4 ++--
drivers/iio/temperature/hid-sensor-temperature.c | 4 ++--
13 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 2ff591b3458f..a63dae90dadc 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -416,7 +416,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
return ret;
}
@@ -429,7 +429,7 @@ static void hid_accel_3d_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
}
static const struct platform_device_id hid_accel_3d_ids[] = {
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 417c4ab8c1b2..28d050b45c74 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -218,8 +218,7 @@ static const struct iio_buffer_setup_ops hid_sensor_buffer_ops = {
.predisable = buffer_predisable,
};
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
- struct hid_sensor_common *attrb)
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
{
if (atomic_read(&attrb->runtime_pm_enable))
pm_runtime_disable(&attrb->pdev->dev);
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
index f94fca4f1edf..afec46ecbe71 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
@@ -16,8 +16,7 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
- struct hid_sensor_common *attrb);
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
#endif
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index c340cc899a7c..fe663b19e902 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -354,7 +354,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes);
+ hid_sensor_remove_trigger(&gyro_state->common_attributes);
return ret;
}
@@ -367,7 +367,7 @@ static void hid_gyro_3d_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes);
+ hid_sensor_remove_trigger(&gyro_state->common_attributes);
}
static const struct platform_device_id hid_gyro_3d_ids[] = {
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index be2338d5f407..e580a2af9562 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -255,7 +255,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &humid_st->common_attributes);
+ hid_sensor_remove_trigger(&humid_st->common_attributes);
return ret;
}
@@ -268,7 +268,7 @@ static void hid_humidity_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
- hid_sensor_remove_trigger(indio_dev, &humid_st->common_attributes);
+ hid_sensor_remove_trigger(&humid_st->common_attributes);
}
static const struct platform_device_id hid_humidity_ids[] = {
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 384572844162..9b57cdced18a 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -432,7 +432,7 @@ static int hid_als_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
+ hid_sensor_remove_trigger(&als_state->common_attributes);
return ret;
}
@@ -445,7 +445,7 @@ static void hid_als_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
+ hid_sensor_remove_trigger(&als_state->common_attributes);
}
static const struct platform_device_id hid_als_ids[] = {
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index efa904a70d0e..473c45626487 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -340,7 +340,7 @@ static int hid_prox_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
+ hid_sensor_remove_trigger(&prox_state->common_attributes);
return ret;
}
@@ -353,7 +353,7 @@ static void hid_prox_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
+ hid_sensor_remove_trigger(&prox_state->common_attributes);
}
static const struct platform_device_id hid_prox_ids[] = {
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index b01dd53eb100..8be3dfe4dd58 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -542,7 +542,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes);
+ hid_sensor_remove_trigger(&magn_state->magn_flux_attributes);
return ret;
}
@@ -555,7 +555,7 @@ static void hid_magn_3d_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes);
+ hid_sensor_remove_trigger(&magn_state->magn_flux_attributes);
}
static const struct platform_device_id hid_magn_3d_ids[] = {
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index 4e23a598a3fb..56fd9c53dfc2 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -378,7 +378,7 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes);
+ hid_sensor_remove_trigger(&incl_state->common_attributes);
return ret;
}
@@ -391,7 +391,7 @@ static void hid_incl_3d_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes);
+ hid_sensor_remove_trigger(&incl_state->common_attributes);
}
static const struct platform_device_id hid_incl_3d_ids[] = {
diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index 4a11e4555099..56fdb3412fe3 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -353,7 +353,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
+ hid_sensor_remove_trigger(&rot_state->common_attributes);
return ret;
}
@@ -366,7 +366,7 @@ static void hid_dev_rot_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
+ hid_sensor_remove_trigger(&rot_state->common_attributes);
}
static const struct platform_device_id hid_dev_rot_ids[] = {
diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
index a26d391661fd..5288b63f4e21 100644
--- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
+++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
@@ -337,7 +337,7 @@ static int hid_hinge_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
+ hid_sensor_remove_trigger(&st->common_attributes);
return ret;
}
@@ -350,7 +350,7 @@ static void hid_hinge_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
+ hid_sensor_remove_trigger(&st->common_attributes);
}
static const struct platform_device_id hid_hinge_ids[] = {
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 5f1d6abda3e4..2bf5d055e175 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -319,7 +319,7 @@ static int hid_press_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
+ hid_sensor_remove_trigger(&press_state->common_attributes);
return ret;
}
@@ -332,7 +332,7 @@ static void hid_press_remove(struct platform_device *pdev)
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
+ hid_sensor_remove_trigger(&press_state->common_attributes);
}
static const struct platform_device_id hid_press_ids[] = {
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
index 9f628a8e5cfb..60d4fcc8043b 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -253,7 +253,7 @@ static int hid_temperature_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
+ hid_sensor_remove_trigger(&temp_st->common_attributes);
return ret;
}
@@ -265,7 +265,7 @@ static void hid_temperature_remove(struct platform_device *pdev)
struct temperature_state *temp_st = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
- hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
+ hid_sensor_remove_trigger(&temp_st->common_attributes);
}
static const struct platform_device_id hid_temperature_ids[] = {
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/9] iio: hid-sensors: cleanup codestyle warning
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reported by checkpatch:
FILE: drivers/iio/common/hid-sensors/hid-sensor-trigger.c
WARNING: Missing a blank line after declarations
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 28d050b45c74..98fadc61a68a 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -313,7 +313,9 @@ static int __maybe_unused hid_sensor_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+
schedule_work(&attrb->work);
+
return 0;
}
@@ -321,6 +323,7 @@ static int __maybe_unused hid_sensor_runtime_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+
return _hid_sensor_power_state(attrb, true);
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 3/9] iio: hid-sensors: introduce device managed API
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
hid_sensor_setup_trigger() is common API used for the HID IIO drivers,
prepare devm API devm_hid_sensor_setup_trigger() to acquire resource
during setup and release using device managed framework during drivers
fail, unbind or remove path.
Register action with devm_add_action_or_reset() to release resource with
devres framework.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
Changes in v3:
- Remove cast and update function based on review comment from Andy
- v2 link -> https://lore.kernel.org/all/20260429175918.2541914-3-sanjayembedded@gmail.com/
---
.../common/hid-sensors/hid-sensor-trigger.c | 18 ++++++++++++++++++
.../common/hid-sensors/hid-sensor-trigger.h | 2 ++
2 files changed, 20 insertions(+)
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 98fadc61a68a..fb6a4587ae03 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -301,6 +301,24 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
}
EXPORT_SYMBOL_NS(hid_sensor_setup_trigger, "IIO_HID");
+static void hid_sensor_remove_trigger_action(void *attrb)
+{
+ hid_sensor_remove_trigger(attrb);
+}
+
+int devm_hid_sensor_setup_trigger(struct device *dev, struct iio_dev *indio_dev,
+ const char *name, struct hid_sensor_common *attrb)
+{
+ int ret;
+
+ ret = hid_sensor_setup_trigger(indio_dev, name, attrb);
+ if (ret)
+ return ret;
+
+ return devm_add_action_or_reset(dev, hid_sensor_remove_trigger_action, attrb);
+}
+EXPORT_SYMBOL_NS(devm_hid_sensor_setup_trigger, "IIO_HID");
+
static int __maybe_unused hid_sensor_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
index afec46ecbe71..6fd7c39a240d 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
@@ -17,6 +17,8 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
+int devm_hid_sensor_setup_trigger(struct device *dev, struct iio_dev *indio_dev,
+ const char *name, struct hid_sensor_common *attrb);
int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
#endif
--
2.34.1
^ permalink raw reply related
* [PATCH v3 4/9] iio: gyro: hid-sensor-gyro-3d: cleanup codestyle warning
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reported by checkpatch:
FILE: drivers/iio/gyro/hid-sensor-gyro-3d.c
WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
+ unsigned usage_id,
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/gyro/hid-sensor-gyro-3d.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index fe663b19e902..87537f9c58fb 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -187,7 +187,7 @@ static const struct iio_info gyro_3d_info = {
/* Callback handler to send event after all samples are received and captured */
static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
- unsigned usage_id,
+ unsigned int usage_id,
void *priv)
{
struct iio_dev *indio_dev = platform_get_drvdata(priv);
@@ -209,7 +209,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
/* Capture samples in local storage */
static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
- unsigned usage_id,
+ unsigned int usage_id,
size_t raw_len, char *raw_data,
void *priv)
{
@@ -244,7 +244,7 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
static int gyro_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
struct iio_chan_spec *channels,
- unsigned usage_id,
+ unsigned int usage_id,
struct gyro_3d_state *st)
{
int ret;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 5/9] iio: gyro: hid-sensor-gyro-3d: drop hid_sensor_remove_trigger() using devm API
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Use devm_hid_sensor_setup_trigger() to automatically release resource
during fail, unbind or removal of driver using devres framework.
This simplify the setup, remove goto, avoid manual resource cleanup in
teardown path.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/gyro/hid-sensor-gyro-3d.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index 87537f9c58fb..72e7db8ce3b2 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -326,8 +326,8 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
atomic_set(&gyro_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &gyro_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(&pdev->dev, indio_dev, name,
+ &gyro_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -336,7 +336,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_trigger;
+ return ret;
}
gyro_state->callbacks.send_event = gyro_3d_proc_event;
@@ -353,8 +353,6 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
error_iio_unreg:
iio_device_unregister(indio_dev);
-error_remove_trigger:
- hid_sensor_remove_trigger(&gyro_state->common_attributes);
return ret;
}
@@ -363,11 +361,9 @@ static void hid_gyro_3d_remove(struct platform_device *pdev)
{
struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
iio_device_unregister(indio_dev);
- hid_sensor_remove_trigger(&gyro_state->common_attributes);
}
static const struct platform_device_id hid_gyro_3d_ids[] = {
--
2.34.1
^ permalink raw reply related
* [PATCH v3 6/9] iio: humidity: hid-sensor-humidity: cleanup codestyle check
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reported by checkpatch:
FILE: drivers/iio/humidity/hid-sensor-humidity.c
CHECK: Alignment should match open parenthesis
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/humidity/hid-sensor-humidity.c | 46 +++++++++++-----------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index e580a2af9562..968dd8d4bb35 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -45,7 +45,7 @@ static const struct iio_chan_spec humidity_channels[] = {
/* Adjust channel real bits based on report descriptor */
static void humidity_adjust_channel_bit_mask(struct iio_chan_spec *channels,
- int channel, int size)
+ int channel, int size)
{
channels[channel].scan_type.sign = 's';
/* Real storage bits will change based on the report desc. */
@@ -55,8 +55,8 @@ static void humidity_adjust_channel_bit_mask(struct iio_chan_spec *channels,
}
static int humidity_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
{
struct hid_humidity_state *humid_st = iio_priv(indio_dev);
@@ -101,8 +101,8 @@ static int humidity_read_raw(struct iio_dev *indio_dev,
}
static int humidity_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val, int val2, long mask)
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
{
struct hid_humidity_state *humid_st = iio_priv(indio_dev);
@@ -127,7 +127,7 @@ static const struct iio_info humidity_info = {
/* Callback handler to send event after all samples are received and captured */
static int humidity_proc_event(struct hid_sensor_hub_device *hsdev,
- unsigned int usage_id, void *pdev)
+ unsigned int usage_id, void *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct hid_humidity_state *humid_st = iio_priv(indio_dev);
@@ -141,8 +141,8 @@ static int humidity_proc_event(struct hid_sensor_hub_device *hsdev,
/* Capture samples in local storage */
static int humidity_capture_sample(struct hid_sensor_hub_device *hsdev,
- unsigned int usage_id, size_t raw_len,
- char *raw_data, void *pdev)
+ unsigned int usage_id, size_t raw_len,
+ char *raw_data, void *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct hid_humidity_state *humid_st = iio_priv(indio_dev);
@@ -159,17 +159,17 @@ static int humidity_capture_sample(struct hid_sensor_hub_device *hsdev,
/* Parse report which is specific to an usage id */
static int humidity_parse_report(struct platform_device *pdev,
- struct hid_sensor_hub_device *hsdev,
- struct iio_chan_spec *channels,
- unsigned int usage_id,
- struct hid_humidity_state *st)
+ struct hid_sensor_hub_device *hsdev,
+ struct iio_chan_spec *channels,
+ unsigned int usage_id,
+ struct hid_humidity_state *st)
{
int ret;
ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
- usage_id,
- HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY,
- &st->humidity_attr);
+ usage_id,
+ HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY,
+ &st->humidity_attr);
if (ret < 0)
return ret;
@@ -208,20 +208,20 @@ static int hid_humidity_probe(struct platform_device *pdev)
humid_st->common_attributes.pdev = pdev;
ret = hid_sensor_parse_common_attributes(hsdev,
- HID_USAGE_SENSOR_HUMIDITY,
- &humid_st->common_attributes,
- humidity_sensitivity_addresses,
- ARRAY_SIZE(humidity_sensitivity_addresses));
+ HID_USAGE_SENSOR_HUMIDITY,
+ &humid_st->common_attributes,
+ humidity_sensitivity_addresses,
+ ARRAY_SIZE(humidity_sensitivity_addresses));
if (ret)
return ret;
humid_chans = devm_kmemdup(&indio_dev->dev, humidity_channels,
- sizeof(humidity_channels), GFP_KERNEL);
+ sizeof(humidity_channels), GFP_KERNEL);
if (!humid_chans)
return -ENOMEM;
ret = humidity_parse_report(pdev, hsdev, humid_chans,
- HID_USAGE_SENSOR_HUMIDITY, humid_st);
+ HID_USAGE_SENSOR_HUMIDITY, humid_st);
if (ret)
return ret;
@@ -234,7 +234,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
atomic_set(&humid_st->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
- &humid_st->common_attributes);
+ &humid_st->common_attributes);
if (ret)
return ret;
@@ -242,7 +242,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
humidity_callbacks.pdev = pdev;
ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY,
- &humidity_callbacks);
+ &humidity_callbacks);
if (ret)
goto error_remove_trigger;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 7/9] iio: humidity: hid-sensor-humidity: use common device for devres
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
kmemdup() is used for memory that is logically tied to the HID
platform device, even though the driver binds into the IIO framework.
Using &indio_dev->dev for devres allocations works functionally, but it
results in two separate devres ownership trees—one for the HID
platform device (pdev) and another for the IIO device (indio_dev).
The devres framework is intended to have a single, well-defined parent
device. Since the memory originates from HID sensor probing and is not
IIO-specific, &pdev->dev is the correct and logical owner.
Switch to using the platform device for devm_kmemdup() so that all
resources are released deterministically and consistently.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/humidity/hid-sensor-humidity.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index 968dd8d4bb35..18d4e376376d 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -215,7 +215,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
if (ret)
return ret;
- humid_chans = devm_kmemdup(&indio_dev->dev, humidity_channels,
+ humid_chans = devm_kmemdup(&pdev->dev, humidity_channels,
sizeof(humidity_channels), GFP_KERNEL);
if (!humid_chans)
return -ENOMEM;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 8/9] iio: humidity: hid-sensor-humidity: use local struct device
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Introduce a local struct device pointer derived from &pdev->dev.
This avoids repeated &pdev->dev usage and improves readability.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/humidity/hid-sensor-humidity.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index 18d4e376376d..d310ec43a118 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -196,10 +196,11 @@ static int hid_humidity_probe(struct platform_device *pdev)
struct iio_dev *indio_dev;
struct hid_humidity_state *humid_st;
struct iio_chan_spec *humid_chans;
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret;
- indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*humid_st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*humid_st));
if (!indio_dev)
return -ENOMEM;
@@ -215,7 +216,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
if (ret)
return ret;
- humid_chans = devm_kmemdup(&pdev->dev, humidity_channels,
+ humid_chans = devm_kmemdup(dev, humidity_channels,
sizeof(humidity_channels), GFP_KERNEL);
if (!humid_chans)
return -ENOMEM;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 9/9] iio: humidity: hid-sensor-humidity: drop hid_sensor_remove_trigger() using devm API
From: Sanjay Chitroda @ 2026-05-09 10:10 UTC (permalink / raw)
To: jikos, jic23, srinivas.pandruvada
Cc: dlechner, nuno.sa, andy, sanjayembeddedse, sakari.ailus,
linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Use devm_hid_sensor_setup_trigger() to automatically release resources
during failure, unbind or removal of driver using devres framework.
This is done in a way to simplify the setup, remove goto and avoid manual
resource cleanup in teardown path.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
changes in v3:
- Update commit message based on review comment from Andy
- Based on discussion using parent device of HID platform driver used
with devres framework for this driver
- v2 link -> https://lore.kernel.org/all/20260429175918.2541914-5-sanjayembedded@gmail.com/
---
drivers/iio/humidity/hid-sensor-humidity.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index d310ec43a118..4d4282e4b6e4 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -234,8 +234,8 @@ static int hid_humidity_probe(struct platform_device *pdev)
atomic_set(&humid_st->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &humid_st->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &humid_st->common_attributes);
if (ret)
return ret;
@@ -245,7 +245,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY,
&humidity_callbacks);
if (ret)
- goto error_remove_trigger;
+ return ret;
ret = iio_device_register(indio_dev);
if (ret)
@@ -255,8 +255,6 @@ static int hid_humidity_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
-error_remove_trigger:
- hid_sensor_remove_trigger(&humid_st->common_attributes);
return ret;
}
@@ -265,11 +263,9 @@ static void hid_humidity_remove(struct platform_device *pdev)
{
struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct hid_humidity_state *humid_st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
- hid_sensor_remove_trigger(&humid_st->common_attributes);
}
static const struct platform_device_id hid_humidity_ids[] = {
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] HID: mcp2221: fix OOB write in mcp2221_raw_event()
From: sashiko-bot @ 2026-05-09 10:36 UTC (permalink / raw)
To: Florian Pradines; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260509094517.2691246-1-florian.pradines@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] The patch adds a size bound but leaves a dangling pointer in `mcp->rxbuf` when a read times out, resulting in a Use-After-Free.
- [High] Unsynchronized updates to `mcp->rxbuf` and `mcp->rxbuf_size` allow an attacker to bypass the new bounds check completely, causing an Out-Of-Bounds (OOB) write.
- [High] The patch fails to prevent stack buffer overflows for `I2C_SMBUS_BLOCK_DATA` reads because it bases `mcp->rxbuf_size` on uninitialized stack memory.
- [High] The raw event handler blindly accesses payload data without validating against the actual received HID report size, leading to out-of-bounds kernel heap reads.
--
commit 2cea5cadcf6c54079354cc3c519d5621e3b06d74
Author: Florian Pradines <florian.pradines@gmail.com>
HID: mcp2221: fix OOB write in mcp2221_raw_event()
This commit attempts to fix an out-of-bounds write in mcp2221_raw_event()
by adding a rxbuf_size field. It sets this field alongside rxbuf in
mcp_i2c_smbus_read() and validates the incoming data length against it
before copying.
> diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
> index be80970ab48e2..e4ddd8e9293b6 100644
> --- a/drivers/hid/hid-mcp2221.c
> +++ b/drivers/hid/hid-mcp2221.c
[ ... ]
> @@ -330,12 +331,14 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp,
> mcp->txbuf[3] = (u8)(msg->addr << 1);
> total_len = msg->len;
> mcp->rxbuf = msg->buf;
> + mcp->rxbuf_size = msg->len;
> } else {
> mcp->txbuf[1] = smbus_len;
> mcp->txbuf[2] = 0;
> mcp->txbuf[3] = (u8)(smbus_addr << 1);
> total_len = smbus_len;
> mcp->rxbuf = smbus_buf;
> + mcp->rxbuf_size = smbus_len;
Does this code fail to prevent stack buffer overflows for
I2C_SMBUS_BLOCK_DATA reads?
In i2c_smbus_read_block_data(), the i2c_smbus_data union is allocated
on the stack but its first byte (data.block[0]) is not initialized before
the read. In mcp_smbus_xfer(), the driver uses data->block[0] + 1 to
determine the read length, which is then assigned here to mcp->rxbuf_size.
If this uninitialized stack memory contains a large value (e.g., 255), the
new bounds check will pass for large responses, and memcpy can write past
the 34-byte data->block array, overflowing the stack.
Also, are these updates to mcp->rxbuf and mcp->rxbuf_size safe from
concurrent access?
These are updated non-atomically in process context, while
mcp2221_raw_event() runs asynchronously.
If a previous read timed out leaving rxbuf_idx = 0 and rxbuf_size = 60,
could a late 60-byte response arrive just after mcp->rxbuf is assigned a new
2-byte buffer but before mcp->rxbuf_size is updated to 2?
This would cause the event handler to read the old rxbuf_size (60), pass the
check, and copy 60 bytes into the 2-byte buffer, bypassing the protection.
> }
>
> ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4);
If mcp_send_data_req_status() times out, it returns -ETIMEDOUT without
setting mcp->rxbuf to NULL.
If the caller then frees or pops the buffer, and a delayed or malicious
MCP2221_I2C_GET_DATA report is processed by mcp2221_raw_event(), could this
result in a use-after-free?
Since rxbuf is not NULL and rxbuf_idx < rxbuf_size, the new check passes,
and memcpy would write data directly into the freed memory.
[ ... ]
> @@ -919,6 +922,10 @@ static int mcp2221_raw_event(struct hid_device *hdev,
> mcp->status = -EINVAL;
> break;
> }
> + if (mcp->rxbuf_idx + data[3] > mcp->rxbuf_size) {
> + mcp->status = -EINVAL;
> + break;
> + }
> buf = mcp->rxbuf;
> memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
This isn't a regression from this patch, but does the raw event handler
blindly access payload data without validating against the actual received
HID report size?
The mcp2221_raw_event() function receives a size parameter representing the
length of the HID report but ignores it.
If a malicious USB device presents a HID report descriptor with a small
maximum report size (e.g., 4 bytes), the HID core will allocate a 4-byte
buffer.
If the device then sends data[3] = 60, this memcpy will read 60 bytes past
the end of the 4-byte kernel heap buffer, potentially leaking adjacent
kernel memory to user-space.
> mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260509094517.2691246-1-florian.pradines@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v3 1/9] iio: hid-sensors: drop redundant iio_dev argument
From: sashiko-bot @ 2026-05-09 10:42 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260509101040.791404-2-sanjayembedded@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] This problem wasn't introduced by this patch, but the removal sequence across HID IIO drivers cancels asynchronous suspend requests, leaving the hardware powered on, which violates PM subsystem guidelines.
- [High] This problem wasn't introduced by this patch, but in `hid-sensor-temperature.c`, the trigger is manually unregistered and freed in the `remove` callback while the IIO device is still active and registered, creating a use-after-free vulnerability.
--
commit 774f02b73d8b538afc5af51312b8682afec55f98
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: hid-sensors: drop redundant iio_dev argument
This commit removes the unused iio_dev argument from
hid_sensor_remove_trigger() across all HID IIO drivers, adapting the
function prototype to simplify the API for a future devm-based conversion.
> diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
> index 2ff591b3458f7..a63dae90dadc5 100644
> --- a/drivers/iio/accel/hid-sensor-accel-3d.c
> +++ b/drivers/iio/accel/hid-sensor-accel-3d.c
[ ... ]
> @@ -429,7 +429,7 @@ static void hid_accel_3d_remove(struct platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
> + hid_sensor_remove_trigger(&accel_state->common_attributes);
> }
This problem wasn't introduced by this patch, but could this removal sequence
leave the hardware powered on?
Looking at the removal path across these drivers, iio_device_unregister()
disables the IIO buffers, which eventually calls hid_sensor_power_state()
and queues an asynchronous suspend via pm_runtime_put_autosuspend().
Immediately afterward, hid_sensor_remove_trigger() calls
pm_runtime_disable(). Does calling pm_runtime_disable() immediately after an
async put cancel the pending suspend work, leaving the physical device active
while marking it suspended in the PM core?
[ ... ]
> diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
> index 9f628a8e5cfbe..60d4fcc8043b6 100644
> --- a/drivers/iio/temperature/hid-sensor-temperature.c
> +++ b/drivers/iio/temperature/hid-sensor-temperature.c
[ ... ]
> @@ -265,7 +265,7 @@ static void hid_temperature_remove(struct platform_device *pdev)
> struct temperature_state *temp_st = iio_priv(indio_dev);
>
> sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
> - hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
> + hid_sensor_remove_trigger(&temp_st->common_attributes);
> }
This problem also wasn't introduced by this patch, but is there a
use-after-free risk in this specific driver's removal sequence?
The temperature driver uses devm_iio_device_register() to register the IIO
device, which means the device unregistration is deferred until the devres
cleanup phase after hid_temperature_remove() returns.
However, hid_sensor_remove_trigger() is called manually here and it calls
iio_trigger_free(). Since the IIO device remains fully registered and exposed
to user-space until devres runs, could concurrent sysfs access or buffer
operations dereference the freed trigger pointer?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260509101040.791404-1-sanjayembedded@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v3 7/9] iio: humidity: hid-sensor-humidity: use common device for devres
From: sashiko-bot @ 2026-05-09 13:06 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260509101040.791404-8-sanjayembedded@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Use-After-Free due to lifetime mismatch between IIO device and platform device devres
--
commit 2edcf899b7cb430d80f56a0ef1506dd20ea46d9d
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: humidity: hid-sensor-humidity: use common device for devres
This commit changes the devres allocation of humidity channels to use the
platform device instead of the IIO device. The goal is to have a single,
well-defined parent device for devres ownership.
> diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
> --- a/drivers/iio/humidity/hid-sensor-humidity.c
> +++ b/drivers/iio/humidity/hid-sensor-humidity.c
> @@ -215,7 +215,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> - humid_chans = devm_kmemdup(&indio_dev->dev, humidity_channels,
> + humid_chans = devm_kmemdup(&pdev->dev, humidity_channels,
> sizeof(humidity_channels), GFP_KERNEL);
Could this change introduce a use-after-free if the IIO device outlives the
driver binding?
The indio_dev object is allocated using devm_iio_device_alloc(), meaning it is
reference-counted and its lifetime can exceed the platform device binding if
consumers hold a reference.
If the driver unbinds, the pdev devres callbacks will execute and free the
humid_chans memory. However, indio_dev->channels still points to this freed
array.
If a consumer later calls IIO APIs like iio_read_channel_ext_info(), they
will dereference the freed humid_chans memory.
> if (!humid_chans)
> return -ENOMEM;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260509101040.791404-1-sanjayembedded@gmail.com?part=7
^ permalink raw reply
* Re: [PATCH v3 1/9] iio: hid-sensors: drop redundant iio_dev argument
From: David Lechner @ 2026-05-09 21:32 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23, srinivas.pandruvada
Cc: nuno.sa, andy, sakari.ailus, linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-2-sanjayembedded@gmail.com>
On 5/9/26 5:10 AM, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> hid_sensor_remove_trigger() uses struct hid_sensor_common to release
> resources acquired during trigger setup.
>
> Earlier implementations required struct iio_dev to clean up buffers,
> but with the current code this argument is no longer used and is
> redundant.
>
> Adapt to hid_sensor_remove_trigger() API change across all HID IIO
> drivers to match updated prototype.
>
> Removing it simplifies the API and is a preparatory step toward
> converting the trigger handling to a devm-based API.
The subject and commit message don't make sense to me. It looks like
it is just removing an unused argument.
Code looks fine though.
^ permalink raw reply
* Re: [PATCH v3 2/9] iio: hid-sensors: cleanup codestyle warning
From: David Lechner @ 2026-05-09 21:35 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23, srinivas.pandruvada
Cc: nuno.sa, andy, sakari.ailus, linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-3-sanjayembedded@gmail.com>
On 5/9/26 5:10 AM, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> Reported by checkpatch:
> FILE: drivers/iio/common/hid-sensors/hid-sensor-trigger.c
checkpatch (or any other linter) says so is not a good reason
for a change. They are suggestions, not requirements. If the code
is improved, say why this is better. I.e. improve readability.
>
> WARNING: Missing a blank line after declarations
>
> Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
> ---
> drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> index 28d050b45c74..98fadc61a68a 100644
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> @@ -313,7 +313,9 @@ static int __maybe_unused hid_sensor_resume(struct device *dev)
> {
> struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
> +
> schedule_work(&attrb->work);
> +
> return 0;
> }
>
> @@ -321,6 +323,7 @@ static int __maybe_unused hid_sensor_runtime_resume(struct device *dev)
> {
> struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
> +
> return _hid_sensor_power_state(attrb, true);
> }
>
^ permalink raw reply
* Re: [PATCH v3 4/9] iio: gyro: hid-sensor-gyro-3d: cleanup codestyle warning
From: David Lechner @ 2026-05-09 21:38 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23, srinivas.pandruvada
Cc: nuno.sa, andy, sakari.ailus, linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-5-sanjayembedded@gmail.com>
On 5/9/26 5:10 AM, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> Reported by checkpatch:
> FILE: drivers/iio/gyro/hid-sensor-gyro-3d.c
>
> WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
> + unsigned usage_id,
Even better would be to use u32 since this driver already uses
that type.
>
> Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
> ---
> drivers/iio/gyro/hid-sensor-gyro-3d.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
> index fe663b19e902..87537f9c58fb 100644
> --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
> +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
> @@ -187,7 +187,7 @@ static const struct iio_info gyro_3d_info = {
>
> /* Callback handler to send event after all samples are received and captured */
> static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
> - unsigned usage_id,
> + unsigned int usage_id,
> void *priv)
> {
> struct iio_dev *indio_dev = platform_get_drvdata(priv);
> @@ -209,7 +209,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
>
> /* Capture samples in local storage */
> static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
> - unsigned usage_id,
> + unsigned int usage_id,
> size_t raw_len, char *raw_data,
> void *priv)
> {
> @@ -244,7 +244,7 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
> static int gyro_3d_parse_report(struct platform_device *pdev,
> struct hid_sensor_hub_device *hsdev,
> struct iio_chan_spec *channels,
> - unsigned usage_id,
> + unsigned int usage_id,
> struct gyro_3d_state *st)
> {
> int ret;
^ permalink raw reply
* Re: [PATCH v3 0/9] iio: introduce devm_ API for hid sensro setup and cleanup
From: David Lechner @ 2026-05-09 21:44 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23, srinivas.pandruvada
Cc: nuno.sa, andy, sakari.ailus, linux-input, linux-iio, linux-kernel
In-Reply-To: <20260509101040.791404-1-sanjayembedded@gmail.com>
On 5/9/26 5:10 AM, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> Key highlights:
> - Prepare change as pre-requisite for devm conversion for HID IIO
> drivers by removing redundant argument
> - Add devm API to setup trigger and clenaup resource using
> devm_add_action_or_reset()
> - few cleanup and prepratory changes before updating driver for devm_
> - few sample driver update using devm conversion to auto release resource
>
> changes in v3:
> - Added cleanup and prepratory changes before adding devm_ API
> conversion based on self review: 0002, 0004, 0006, 0007 and 0008
> - Address andy's review comment on commit message and coding style
> - v2 series -> https://lore.kernel.org/all/20260429175918.2541914-1-sanjayembedded@gmail.com/
> changes in v2:
> - Following input from Jonathan and Andy, squash initial patch v1
> series in single change as individual change should not break anything
> - Add devm API support and two driver using the same
> - v1 series -> https://lore.kernel.org/all/20260428071613.1134053-1-sanjayembedded@gmail.com/
>
> Testing:
> - Compiled with W=1
> - Build-tested on QEMU x86_64
>
> Based on further feedback and reviews, I would extend this series to convert all HID IIO driver to use devm_* API.
>
> Thanks,
> Sanjay Chitroda
>
>
> Sanjay Chitroda (9):
> iio: hid-sensors: drop redundant iio_dev argument
> iio: hid-sensors: cleanup codestyle warning
> iio: hid-sensors: introduce device managed API
> iio: gyro: hid-sensor-gyro-3d: cleanup codestyle warning
> iio: gyro: hid-sensor-gyro-3d: drop hid_sensor_remove_trigger() using
> devm API
> iio: humidity: hid-sensor-humidity: cleanup codestyle check
> iio: humidity: hid-sensor-humidity: use common device for devres
> iio: humidity: hid-sensor-humidity: use local struct device
> iio: humidity: hid-sensor-humidity: drop hid_sensor_remove_trigger()
> using devm API
The series would be easier to follow if all of the cleanups
were first and then all of the new code was the last 3
patches.
>
> drivers/iio/accel/hid-sensor-accel-3d.c | 4 +-
> .../common/hid-sensors/hid-sensor-trigger.c | 24 +++++++-
> .../common/hid-sensors/hid-sensor-trigger.h | 5 +-
> drivers/iio/gyro/hid-sensor-gyro-3d.c | 16 ++---
> drivers/iio/humidity/hid-sensor-humidity.c | 61 +++++++++----------
> drivers/iio/light/hid-sensor-als.c | 4 +-
> drivers/iio/light/hid-sensor-prox.c | 4 +-
> drivers/iio/magnetometer/hid-sensor-magn-3d.c | 4 +-
> drivers/iio/orientation/hid-sensor-incl-3d.c | 4 +-
> drivers/iio/orientation/hid-sensor-rotation.c | 4 +-
> .../position/hid-sensor-custom-intel-hinge.c | 4 +-
> drivers/iio/pressure/hid-sensor-press.c | 4 +-
> .../iio/temperature/hid-sensor-temperature.c | 4 +-
> 13 files changed, 78 insertions(+), 64 deletions(-)
>
>
> base-commit: 39b80c5c9830d12d2d6531059001301c4265322a
^ 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