* Re: [PATCH] xpad: Overhaul device data for wireless devices
From: Dmitry Torokhov @ 2026-04-04 5:33 UTC (permalink / raw)
To: Sanjay Govind
Cc: Vicki Pfau, Nilton Perim Neto, Mario Limonciello,
Pierre-Loup A. Griffais, Antheas Kapenekakis, linux-input,
linux-kernel
In-Reply-To: <20260314075034.1488655-2-sanjay.govind9@gmail.com>
Hi Sanjay,
On Sat, Mar 14, 2026 at 08:50:32PM +1300, Sanjay Govind wrote:
> Xbox 360 wireless controllers expose information in the link and
> capabilities reports.
>
> Extract and use the vendor id for wireless controllers, and use
> the subtype to build a nicer device name and product id.
>
> Some xbox 360 controllers put a vid and pid into the stick capability
> data, so check if this was done, and pull the vid, pid and revision from
> there.
>
> Signed-off-by: Sanjay Govind <sanjay.govind9@gmail.com>
> ---
> drivers/input/joystick/xpad.c | 138 +++++++++++++++++++++++++++++++++-
> 1 file changed, 135 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index bf4accf3f581..2490eb21a534 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -94,6 +94,22 @@
> #define XTYPE_XBOXONE 3
> #define XTYPE_UNKNOWN 4
>
> +#define FLAG_FORCE_FEEDBACK 0x01
> +
> +#define SUBTYPE_GAMEPAD 0x01
> +#define SUBTYPE_WHEEL 0x02
> +#define SUBTYPE_ARCADE_STICK 0x03
> +#define SUBTYPE_FLIGHT_SICK 0x04
> +#define SUBTYPE_DANCE_PAD 0x05
> +#define SUBTYPE_GUITAR 0x06
> +#define SUBTYPE_GUITAR_ALTERNATE 0x07
> +#define SUBTYPE_DRUM_KIT 0x08
> +#define SUBTYPE_GUITAR_BASS 0x0B
> +#define SUBTYPE_RB_KEYBOARD 0x0F
> +#define SUBTYPE_ARCADE_PAD 0x13
> +#define SUBTYPE_TURNTABLE 0x17
> +#define SUBTYPE_PRO_GUITAR 0x19
> +
> /* Send power-off packet to xpad360w after holding the mode button for this many
> * seconds
> */
> @@ -795,6 +811,9 @@ struct usb_xpad {
> int xtype; /* type of xbox device */
> int packet_type; /* type of the extended packet */
> int pad_nr; /* the order x360 pads were attached */
> + u8 sub_type;
> + u16 flags;
> + u16 wireless_vid;
> const char *name; /* name of the device */
> struct work_struct work; /* init/remove device from callback */
> time64_t mode_btn_down_ts;
> @@ -807,6 +826,8 @@ static void xpad_deinit_input(struct usb_xpad *xpad);
> static int xpad_start_input(struct usb_xpad *xpad);
> static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
> static void xpad360w_poweroff_controller(struct usb_xpad *xpad);
> +static int xpad_inquiry_pad_capabilities(struct usb_xpad *xpad);
> +
>
> /*
> * xpad_process_packet
> @@ -1026,12 +1047,46 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
> if (data[0] & 0x08) {
> present = (data[1] & 0x80) != 0;
>
> - if (xpad->pad_present != present) {
> + /* delay prescence until after we get the link report */
s/prescence/presence
But I would say "Only handle no longer being present here. When
a controller appears mark it as present only after receiving link
report".
> + if (!present && xpad->pad_present) {
> xpad->pad_present = present;
> schedule_work(&xpad->work);
> }
> }
>
> + /* Link report */
> + if (data[0] == 0x00 && data[1] == 0x0F) {
> + xpad->sub_type = data[25] & 0x7f;
> +
> + /* Decode vendor id from link report */
> + xpad->wireless_vid = ((data[0x16] & 0xf) | data[0x18] << 4) << 8 | data[0x17];
> +
> + if ((data[25] & 0x80) != 0)
> + xpad->flags |= FLAG_FORCE_FEEDBACK;
> +
> + if (!xpad->pad_present) {
> + xpad->pad_present = true;
> + schedule_work(&xpad->work);
> + }
> + xpad_inquiry_pad_capabilities(xpad);
> + }
> +
> + /* Capabilities report */
> + if (data[0] == 0x00 && data[1] == 0x05 && data[5] == 0x12) {
> + xpad->flags |= data[20];
> + /*
> + * A bunch of vendors started putting vids and pids
> + * into capabilities data because they can't be
> + * retrieved by xinput easliy.
easily.
> + * Not all of them do though, so check the vids match
> + * before extracting that info.
> + */
> + if (((data[11] << 8) | data[10]) == xpad->wireless_vid) {
get_unaaligned_le16()
> + xpad->dev->id.product = (data[13] << 8) | data[12];
get_unaligned_le16()
> + xpad->dev->id.version = (data[15] << 8) | data[14];
get_unaligned_le16()
However you should not change product and version once input device is
registered. So you should delay not until after link packet is received,
but until after capabilities packet.
You might need an enum instead of bool for controller state.
> + }
> + }
> +
> /* Valid pad data */
> if (data[1] != 0x1)
> return;
> @@ -1495,6 +1550,31 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
> return xpad_try_sending_next_out_packet(xpad);
> }
>
> +static int xpad_inquiry_pad_capabilities(struct usb_xpad *xpad)
> +{
> + struct xpad_output_packet *packet =
> + &xpad->out_packets[XPAD_OUT_CMD_IDX];
> +
> + guard(spinlock_irqsave)(&xpad->odata_lock);
> +
> + packet->data[0] = 0x00;
> + packet->data[1] = 0x00;
> + packet->data[2] = 0x02;
> + packet->data[3] = 0x80;
> + packet->data[4] = 0x00;
> + packet->data[5] = 0x00;
> + packet->data[6] = 0x00;
> + packet->data[7] = 0x00;
> + packet->data[8] = 0x00;
> + packet->data[9] = 0x00;
> + packet->data[10] = 0x00;
> + packet->data[11] = 0x00;
> + packet->len = 12;
> + packet->pending = true;
> +
> + return xpad_try_sending_next_out_packet(xpad);
> +}
> +
> static int xpad_start_xbox_one(struct usb_xpad *xpad)
> {
> int error;
> @@ -1965,8 +2045,60 @@ static int xpad_init_input(struct usb_xpad *xpad)
> usb_to_input_id(xpad->udev, &input_dev->id);
>
> if (xpad->xtype == XTYPE_XBOX360W) {
> - /* x360w controllers and the receiver have different ids */
> - input_dev->id.product = 0x02a1;
> + /*
> + * x360w controllers on windows put the subtype into the product
> + * for wheels and gamepads, but it makes sense to do it for all
> + * subtypes
> + */
> + input_dev->id.product = 0x02a0 + xpad->sub_type;
Another option is to use version field...
> + /* If the Link report has provided a vid, it won't be set to 1 */
> + if (xpad->wireless_vid != 1)
> + input_dev->id.vendor = xpad->wireless_vid;
> + switch (xpad->sub_type) {
> + case SUBTYPE_GAMEPAD:
> + input_dev->name = "Xbox 360 Wireless Controller";
> + break;
> + case SUBTYPE_WHEEL:
> + input_dev->name = "Xbox 360 Wireless Wheel";
> + break;
> + case SUBTYPE_ARCADE_STICK:
> + input_dev->name = "Xbox 360 Wireless Arcade Stick";
> + break;
> + case SUBTYPE_FLIGHT_SICK:
> + input_dev->name = "Xbox 360 Wireless Flight Stick";
> + break;
> + case SUBTYPE_DANCE_PAD:
> + input_dev->name = "Xbox 360 Wireless Dance Pad";
> + break;
> + case SUBTYPE_GUITAR:
> + input_dev->name = "Xbox 360 Wireless Guitar";
> + break;
> + case SUBTYPE_GUITAR_ALTERNATE:
> + input_dev->name = "Xbox 360 Wireless Alternate Guitar";
> + break;
> + case SUBTYPE_GUITAR_BASS:
> + input_dev->name = "Xbox 360 Wireless Bass Guitar";
> + break;
> + case SUBTYPE_DRUM_KIT:
> + /* Vendors used force feedback flag to differentiate these */
> + if (xpad->flags & FLAG_FORCE_FEEDBACK)
> + input_dev->name = "Xbox 360 Wireless Guitar Hero Drum Kit";
> + else
> + input_dev->name = "Xbox 360 Wireless Rock Band Drum Kit";
> + break;
> + case SUBTYPE_RB_KEYBOARD:
> + input_dev->name = "Xbox 360 Wireless Rock Band Keyboard";
> + break;
> + case SUBTYPE_ARCADE_PAD:
> + input_dev->name = "Xbox 360 Wireless Arcade Pad";
> + break;
> + case SUBTYPE_TURNTABLE:
> + input_dev->name = "Xbox 360 Wireless DJ Hero Turntable";
> + break;
> + case SUBTYPE_PRO_GUITAR:
> + input_dev->name = "Xbox 360 Wireless Rock Band Pro Guitar";
> + break;
> + }
Maybe have an array of
[type] = "Name"
instead of this switch?
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] xpad: Add RedOctane Games vendor id
From: Dmitry Torokhov @ 2026-04-04 5:34 UTC (permalink / raw)
To: Sanjay Govind
Cc: Vicki Pfau, Nilton Perim Neto, Mario Limonciello, Lode Willems,
Pierre-Loup A. Griffais, linux-input, linux-kernel
In-Reply-To: <CALQgdA3AzKnjD-rooix=8K9-Vh_zZa7HaZdM-mHhgqg=tVPxYQ@mail.gmail.com>
On Sat, Apr 04, 2026 at 06:13:25PM +1300, Sanjay Govind wrote:
> On Sat, Apr 4, 2026 at 6:07 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> > Don't we also need to add some entries to the xpad_device table?
>
> It's not strictly necessary, xpad will pick the devices up with just
> the vendor id, since they have the correct class, subclass and
> protocol needed for matching, you only really need to put them into
> xpad_device if you want to customize the name or give it different
> flags, and that isn't necessary for these devices. A few of these
> devices are still in development, so we don't have PIDs assigned yet.
OK, I'll queue it to the next release then.
Thanks.
--
Dmitry
^ permalink raw reply
* [git pull] Input updates for v7.0-rc6
From: Dmitry Torokhov @ 2026-04-04 6:02 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, linux-input
Hi Linus,
Please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v7.0-rc6
to receive updates for the input subsystem. You will get:
- new IDs for BETOP BTP-KP50B/C and Razer Wolverine V3 Pro added to
xpad controller driver
- another quirk for new TUXEDO InfinityBook added to i8042
- a small fixup for Synaptics RMI4 driver to properly unlock mutex when
encountering an error in F54
- an update to bcm5974 touch controller driver to reliably switch into
wellspring mode.
Changelog:
---------
Bart Van Assche (1):
Input: synaptics-rmi4 - fix a locking bug in an error path
Christoffer Sandberg (1):
Input: i8042 - add TUXEDO InfinityBook Max 16 Gen10 AMD to i8042 quirk table
Liam Mitchell (1):
Input: bcm5974 - recover from failed mode switch
Shengyu Qu (1):
Input: xpad - add support for BETOP BTP-KP50B/C controller's wireless mode
Zoltan Illes (1):
Input: xpad - add support for Razer Wolverine V3 Pro
Diffstat:
--------
drivers/input/joystick/xpad.c | 5 +++++
drivers/input/mouse/bcm5974.c | 42 ++++++++++++++++++++++++++++++++++-
drivers/input/rmi4/rmi_f54.c | 4 ++--
drivers/input/serio/i8042-acpipnpio.h | 7 ++++++
4 files changed, 55 insertions(+), 3 deletions(-)
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] xpad: Overhaul device data for wireless devices
From: Sanjay Govind @ 2026-04-04 6:35 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Vicki Pfau, Nilton Perim Neto, Mario Limonciello,
Pierre-Loup A. Griffais, Antheas Kapenekakis, linux-input,
linux-kernel
In-Reply-To: <adCc8OuHm7wwkysq@google.com>
> However you should not change product and version once input device is
> registered. So you should delay not until after link packet is received,
> but until after the capabilities packet.
Yeah i wanted to do that originally, but the main issue with that is
some gamepads don't actually send the capabilities data at all. An
Easy solution I could think of is to just start a timer and continue
the init if it expires and we haven't gotten the capabilities data.
> Another option is to use version field...
Yeah that is reasonable, I had just gone with putting it in the
product id like that as it made things easier for SDL, and microsoft
had done that for the wheel subtype already, so some apps already have
the 0x02a2 pid.
Happy to change that though if you'd prefer i use the version field.
> Maybe have an array of
>
> [type] = "Name"
>
> instead of this switch?
The main problem is there's a lot of gaps in the list of subtypes, and
this also isn't an exhaustive list, there are a few other subtypes out
there that were used for some bespoke controllers, and so using switch
at least means they can keep a generic name if they are used.
^ permalink raw reply
* Re: [PATCH] xpad: Overhaul device data for wireless devices
From: Dmitry Torokhov @ 2026-04-04 6:39 UTC (permalink / raw)
To: Sanjay Govind
Cc: Vicki Pfau, Nilton Perim Neto, Mario Limonciello,
Pierre-Loup A. Griffais, Antheas Kapenekakis, linux-input,
linux-kernel
In-Reply-To: <CALQgdA1soGo6U2_pKS0RZ6smOSS9Zd-g+eMD7KjwUwz-_pAK_w@mail.gmail.com>
On April 3, 2026 11:35:35 PM PDT, Sanjay Govind <sanjay.govind9@gmail.com> wrote:
>> However you should not change product and version once input device is
>> registered. So you should delay not until after link packet is received,
>> but until after the capabilities packet.
>Yeah i wanted to do that originally, but the main issue with that is
>some gamepads don't actually send the capabilities data at all. An
>Easy solution I could think of is to just start a timer and continue
>the init if it expires and we haven't gotten the capabilities data.
That sounds sensible.
>
>> Another option is to use version field...
>Yeah that is reasonable, I had just gone with putting it in the
>product id like that as it made things easier for SDL, and microsoft
>had done that for the wheel subtype already, so some apps already have
>the 0x02a2 pid.
>Happy to change that though if you'd prefer i use the version field.
No, this is fine too.
>
>> Maybe have an array of
>>
>> [type] = "Name"
>>
>> instead of this switch?
>The main problem is there's a lot of gaps in the list of subtypes, and
>this also isn't an exhaustive list, there are a few other subtypes out
>there that were used for some bespoke controllers, and so using switch
>at least means they can keep a generic name if they are used.
OK, then let's keep it as switch.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH v2] xpad: Overhaul device data for wireless devices
From: Sanjay Govind @ 2026-04-04 8:39 UTC (permalink / raw)
To: Dmitry Torokhov, Vicki Pfau, Nilton Perim Neto, Sanjay Govind,
Mario Limonciello, Antheas Kapenekakis
Cc: Pierre-Loup A. Griffais, linux-input, linux-kernel
Xbox 360 wireless controllers expose information in the link and
capabilities reports.
Extract and use the vendor id for wireless controllers, and use
the subtype to build a nicer device name and product id.
Some xbox 360 controllers put a vid and pid into the stick capability
data, so check if this was done, and pull the vid, pid and revision from
there.
Signed-off-by: Sanjay Govind <sanjay.govind9@gmail.com>
---
v2: Delay marking device as present until after capabilities or timeout
drivers/input/joystick/xpad.c | 162 ++++++++++++++++++++++++++++++++--
1 file changed, 155 insertions(+), 7 deletions(-)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index bf4accf3f581..c35512c7c199 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -68,6 +68,7 @@
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/module.h>
+#include <linux/unaligned.h>
#include <linux/usb/input.h>
#include <linux/usb/quirks.h>
@@ -94,6 +95,22 @@
#define XTYPE_XBOXONE 3
#define XTYPE_UNKNOWN 4
+#define FLAG_FORCE_FEEDBACK 0x01
+
+#define SUBTYPE_GAMEPAD 0x01
+#define SUBTYPE_WHEEL 0x02
+#define SUBTYPE_ARCADE_STICK 0x03
+#define SUBTYPE_FLIGHT_SICK 0x04
+#define SUBTYPE_DANCE_PAD 0x05
+#define SUBTYPE_GUITAR 0x06
+#define SUBTYPE_GUITAR_ALTERNATE 0x07
+#define SUBTYPE_DRUM_KIT 0x08
+#define SUBTYPE_GUITAR_BASS 0x0B
+#define SUBTYPE_RB_KEYBOARD 0x0F
+#define SUBTYPE_ARCADE_PAD 0x13
+#define SUBTYPE_TURNTABLE 0x17
+#define SUBTYPE_PRO_GUITAR 0x19
+
/* Send power-off packet to xpad360w after holding the mode button for this many
* seconds
*/
@@ -795,8 +812,13 @@ struct usb_xpad {
int xtype; /* type of xbox device */
int packet_type; /* type of the extended packet */
int pad_nr; /* the order x360 pads were attached */
+ u8 sub_type;
+ u16 flags;
+ u16 wireless_vid;
+ u16 wireless_pid;
+ u16 wireless_version;
const char *name; /* name of the device */
- struct work_struct work; /* init/remove device from callback */
+ struct delayed_work work; /* init/remove device from callback */
time64_t mode_btn_down_ts;
bool delay_init; /* init packets should be delayed */
bool delayed_init_done;
@@ -807,6 +829,8 @@ static void xpad_deinit_input(struct usb_xpad *xpad);
static int xpad_start_input(struct usb_xpad *xpad);
static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
static void xpad360w_poweroff_controller(struct usb_xpad *xpad);
+static int xpad_inquiry_pad_capabilities(struct usb_xpad *xpad);
+
/*
* xpad_process_packet
@@ -980,7 +1004,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
static void xpad_presence_work(struct work_struct *work)
{
- struct usb_xpad *xpad = container_of(work, struct usb_xpad, work);
+ struct usb_xpad *xpad = container_of(work, struct usb_xpad, work.work);
int error;
if (xpad->pad_present) {
@@ -1028,10 +1052,60 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
if (xpad->pad_present != present) {
xpad->pad_present = present;
- schedule_work(&xpad->work);
+ if (present) {
+ /*
+ * Delay marking device as present, so we can make sure
+ * we have received all the information from the capabilities
+ * report. Some devices don't send one, so the delay
+ * guarantees that these devices are still initialized.
+ */
+ schedule_delayed_work(&xpad->work, msecs_to_jiffies(500));
+ } else {
+ schedule_delayed_work(&xpad->work, 0);
+ }
}
}
+ /* Link report */
+ if (data[0] == 0x00 && data[1] == 0x0F) {
+ xpad->sub_type = data[25] & 0x7f;
+
+ /* Decode vendor id from link report */
+ xpad->wireless_vid = ((data[0x16] & 0xf) | data[0x18] << 4) << 8 | data[0x17];
+ /*
+ * x360w controllers on windows put the subtype into the product
+ * for wheels and gamepads, but it makes sense to do it for all
+ * subtypes. This will be used if the capabilities report
+ * doesn't provide us with a product id later.
+ */
+ xpad->wireless_pid = 0x02a0 + xpad->sub_type;
+ xpad->wireless_version = 0;
+
+ if ((data[25] & 0x80) != 0)
+ xpad->flags |= FLAG_FORCE_FEEDBACK;
+
+ xpad_inquiry_pad_capabilities(xpad);
+ }
+
+ /* Capabilities report */
+ if (data[0] == 0x00 && data[1] == 0x05 && data[5] == 0x12) {
+ xpad->flags |= data[20];
+ /*
+ * A bunch of vendors started putting vids and pids
+ * into capabilities data because they can't be
+ * retrieved by xinput easliy.
+ * Not all of them do though, so check the vids match
+ * before extracting that info.
+ */
+ if (get_unaligned_le16(data + 10) == xpad->wireless_vid) {
+ xpad->wireless_pid = get_unaligned_le16(data + 12);
+ xpad->wireless_version = get_unaligned_le16(data + 14);
+ }
+ /* We got the capabilities report, so mark the device present now */
+ cancel_delayed_work(&xpad->work);
+ schedule_delayed_work(&xpad->work, 0);
+ }
+
/* Valid pad data */
if (data[1] != 0x1)
return;
@@ -1495,6 +1569,31 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
return xpad_try_sending_next_out_packet(xpad);
}
+static int xpad_inquiry_pad_capabilities(struct usb_xpad *xpad)
+{
+ struct xpad_output_packet *packet =
+ &xpad->out_packets[XPAD_OUT_CMD_IDX];
+
+ guard(spinlock_irqsave)(&xpad->odata_lock);
+
+ packet->data[0] = 0x00;
+ packet->data[1] = 0x00;
+ packet->data[2] = 0x02;
+ packet->data[3] = 0x80;
+ packet->data[4] = 0x00;
+ packet->data[5] = 0x00;
+ packet->data[6] = 0x00;
+ packet->data[7] = 0x00;
+ packet->data[8] = 0x00;
+ packet->data[9] = 0x00;
+ packet->data[10] = 0x00;
+ packet->data[11] = 0x00;
+ packet->len = 12;
+ packet->pending = true;
+
+ return xpad_try_sending_next_out_packet(xpad);
+}
+
static int xpad_start_xbox_one(struct usb_xpad *xpad)
{
int error;
@@ -1893,7 +1992,7 @@ static void xpad360w_stop_input(struct usb_xpad *xpad)
usb_kill_urb(xpad->irq_in);
/* Make sure we are done with presence work if it was scheduled */
- flush_work(&xpad->work);
+ flush_delayed_work(&xpad->work);
}
static int xpad_open(struct input_dev *dev)
@@ -1965,8 +2064,57 @@ static int xpad_init_input(struct usb_xpad *xpad)
usb_to_input_id(xpad->udev, &input_dev->id);
if (xpad->xtype == XTYPE_XBOX360W) {
- /* x360w controllers and the receiver have different ids */
- input_dev->id.product = 0x02a1;
+ /* If the Link report has provided a vid, it won't be set to 1 */
+ if (xpad->wireless_vid != 1)
+ input_dev->id.vendor = xpad->wireless_vid;
+ if (xpad->wireless_version)
+ input_dev->id.version = xpad->wireless_version;
+ input_dev->id.product = xpad->wireless_pid;
+ switch (xpad->sub_type) {
+ case SUBTYPE_GAMEPAD:
+ input_dev->name = "Xbox 360 Wireless Controller";
+ break;
+ case SUBTYPE_WHEEL:
+ input_dev->name = "Xbox 360 Wireless Wheel";
+ break;
+ case SUBTYPE_ARCADE_STICK:
+ input_dev->name = "Xbox 360 Wireless Arcade Stick";
+ break;
+ case SUBTYPE_FLIGHT_SICK:
+ input_dev->name = "Xbox 360 Wireless Flight Stick";
+ break;
+ case SUBTYPE_DANCE_PAD:
+ input_dev->name = "Xbox 360 Wireless Dance Pad";
+ break;
+ case SUBTYPE_GUITAR:
+ input_dev->name = "Xbox 360 Wireless Guitar";
+ break;
+ case SUBTYPE_GUITAR_ALTERNATE:
+ input_dev->name = "Xbox 360 Wireless Alternate Guitar";
+ break;
+ case SUBTYPE_GUITAR_BASS:
+ input_dev->name = "Xbox 360 Wireless Bass Guitar";
+ break;
+ case SUBTYPE_DRUM_KIT:
+ /* Vendors used force feedback flag to differentiate these */
+ if (xpad->flags & FLAG_FORCE_FEEDBACK)
+ input_dev->name = "Xbox 360 Wireless Guitar Hero Drum Kit";
+ else
+ input_dev->name = "Xbox 360 Wireless Rock Band Drum Kit";
+ break;
+ case SUBTYPE_RB_KEYBOARD:
+ input_dev->name = "Xbox 360 Wireless Rock Band Keyboard";
+ break;
+ case SUBTYPE_ARCADE_PAD:
+ input_dev->name = "Xbox 360 Wireless Arcade Pad";
+ break;
+ case SUBTYPE_TURNTABLE:
+ input_dev->name = "Xbox 360 Wireless DJ Hero Turntable";
+ break;
+ case SUBTYPE_PRO_GUITAR:
+ input_dev->name = "Xbox 360 Wireless Rock Band Pro Guitar";
+ break;
+ }
}
input_dev->dev.parent = &xpad->intf->dev;
@@ -2106,7 +2254,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->delay_init = true;
xpad->packet_type = PKT_XB;
- INIT_WORK(&xpad->work, xpad_presence_work);
+ INIT_DELAYED_WORK(&xpad->work, xpad_presence_work);
if (xpad->xtype == XTYPE_UNKNOWN) {
if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
--
2.53.0
^ permalink raw reply related
* [PATCH] HID: apple: ensure the keyboard backlight is off if suspending
From: Aditya Garg @ 2026-04-04 9:44 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, stable, André Eikmeyer
Some users reported that upon suspending their keyboard backlight
remained on. Fix this by adding the missing LED_CORE_SUSPENDRESUME flag.
Cc: stable@vger.kernel.org
Fixes: 394ba612f941 ("HID: apple: Add support for magic keyboard backlight on T2 Macs")
Fixes: 9018eacbe623 ("HID: apple: Add support for keyboard backlight on certain T2 Macs.")
Reported-by: André Eikmeyer <andre.eikmeyer@gmail.com>
Tested-by: André Eikmeyer <andre.eikmeyer@gmail.com>
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
drivers/hid/hid-apple.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index fc5897a6b..2eb45fac8 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -858,6 +858,7 @@ static int apple_backlight_init(struct hid_device *hdev)
asc->backlight->cdev.name = "apple::kbd_backlight";
asc->backlight->cdev.max_brightness = rep->backlight_on_max;
asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set;
+ asc->backlight->cdev.flags = LED_CORE_SUSPENDRESUME;
ret = apple_backlight_set(hdev, 0, 0);
if (ret < 0) {
@@ -926,6 +927,7 @@ static int apple_magic_backlight_init(struct hid_device *hdev)
backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT;
backlight->cdev.max_brightness = backlight->brightness->field[0]->logical_maximum;
backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set;
+ backlight->cdev.flags = LED_CORE_SUSPENDRESUME;
apple_magic_backlight_set(backlight, 0, 0);
--
2.52.0
^ permalink raw reply related
* Re: [PATCH] HID: lg-g15: Add support for the Logitech G710/G710+ gaming keyboards
From: Xavier Bestel @ 2026-04-04 10:05 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires; +Cc: Hans de Goede, linux-input, linux-kernel
In-Reply-To: <20260402075239.3829699-1-xav@bes.tel>
Le jeudi 02 avril 2026 à 09:52 +0200, Xavier Bestel a écrit :
> Add support for the Logitech G710 and G710+ (USB ID 046d:c24d) gaming
> keyboards to the hid-lg-g15 driver.
Did that mail get through ?
Xav
^ permalink raw reply
* Re: [PATCH] HID: lg-g15: Add support for the Logitech G710/G710+ gaming keyboards
From: Hans de Goede @ 2026-04-04 10:07 UTC (permalink / raw)
To: Xavier Bestel, Jiri Kosina, Benjamin Tissoires; +Cc: linux-input, linux-kernel
In-Reply-To: <f6f46cfe110053208e7dbb4dd3074eab7966e8e7.camel@free.fr>
Hi,
On 4-Apr-26 12:05, Xavier Bestel wrote:
> Le jeudi 02 avril 2026 à 09:52 +0200, Xavier Bestel a écrit :
>> Add support for the Logitech G710 and G710+ (USB ID 046d:c24d) gaming
>> keyboards to the hid-lg-g15 driver.
>
> Did that mail get through ?
Yes we've received your patch. most kernel maintainers have
a very high workload, so the HID maintainers will look at
this patch when they have time, which can take a while.
Regards,
Hans
^ permalink raw reply
* [PATCH v2 0/1] HID: add malicious HID device detection driver
From: Zubeyr Almaho @ 2026-04-04 13:37 UTC (permalink / raw)
To: Jiri Kosina
Cc: Zubeyr Almaho, Benjamin Tissoires, linux-input, linux-kernel,
security
Hi Jiri, Benjamin,
This series introduces hid-omg-detect, a passive HID monitor that scores
potentially malicious keyboard-like USB devices (BadUSB / O.MG style)
using:
- keystroke timing entropy,
- plug-and-type latency,
- USB descriptor fingerprinting.
When the configurable threshold is crossed, the module emits a warning
with a userspace mitigation hint (usbguard).
The driver does not block, delay, or modify HID input events.
Changes since v1:
- Replaced global list + mutex with per-device drvdata.
- Removed logging inside spinlock-held regions.
- Moved VID/PID lookup to probe() to avoid hot-path overhead.
- Switched logging to hid_{info,warn,err} helpers.
- Capped timing sample counter at MAX_TIMING_SAMPLES.
- Renamed file to hid-omg-detect.c for kernel naming conventions.
Thanks,
Zubeyr Almaho
---
drivers/hid/hid-omg-detect.c | 435 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 435 insertions(+)
^ permalink raw reply
* [PATCH v2 1/1] HID: add malicious HID device detection driver
From: Zubeyr Almaho @ 2026-04-04 13:37 UTC (permalink / raw)
To: Jiri Kosina
Cc: Zubeyr Almaho, Benjamin Tissoires, linux-input, linux-kernel,
security
In-Reply-To: <20260404133746.80914-1-zybo1000@gmail.com>
Add a passive HID driver that computes a suspicion score for keyboard-like
USB devices based on:
- low keystroke timing entropy,
- immediate post-enumeration typing,
- known suspicious VID/PID and descriptor anomalies.
If the score exceeds a tunable threshold, the driver emits a warning and
suggests userspace blocking (e.g. usbguard). The module never blocks or
modifies HID events.
Signed-off-by: Zubeyr Almaho <zybo1000@gmail.com>
---
drivers/hid/hid-omg-detect.c | 435 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 435 insertions(+)
create mode 100644 drivers/hid/hid-omg-detect.c
diff --git a/drivers/hid/hid-omg-detect.c b/drivers/hid/hid-omg-detect.c
new file mode 100644
--- /dev/null
+++ b/drivers/hid/hid-omg-detect.c
@@ -0,0 +1,435 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * hid-omg-detect.c - Malicious HID Device Detection Kernel Module
+ *
+ * Detects O.MG Cable and similar BadUSB devices by combining:
+ * 1. Keystroke timing entropy analysis (human vs machine rhythm)
+ * 2. Plug-and-type detection (typing immediately after connect)
+ * 3. USB descriptor fingerprinting (known bad VID/PIDs + anomalies)
+ *
+ * When suspicion score >= threshold, logs a kernel warning and suggests
+ * blocking the device with usbguard.
+ *
+ * The driver is purely passive — it does not drop, modify, or delay any
+ * HID events.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hid.h>
+#include <linux/usb.h>
+#include <linux/ktime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/math64.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Zübeyr Almaho <zybo1000@gmail.com>");
+MODULE_DESCRIPTION("O.MG Cable / Malicious HID Device Detector");
+
+/* ============================================================
+ * Tuneable parameters (pass as insmod args)
+ * ============================================================ */
+static int score_threshold = 70;
+module_param(score_threshold, int, 0644);
+MODULE_PARM_DESC(score_threshold,
+ "Suspicion score (0-100) to trigger alert (default: 70)");
+
+static int plug_type_ms = 500;
+module_param(plug_type_ms, int, 0644);
+MODULE_PARM_DESC(plug_type_ms,
+ "Max ms after connect before first key = plug-and-type (default: 500)");
+
+static int entropy_variance_low = 500;
+module_param(entropy_variance_low, int, 0644);
+MODULE_PARM_DESC(entropy_variance_low,
+ "Variance (us^2) below which typing is machine-like (default: 500)");
+
+/* ============================================================
+ * Constants
+ * ============================================================ */
+#define DRIVER_NAME "hid_omg_detect"
+#define MAX_TIMING_SAMPLES 64
+#define MIN_SAMPLES 10
+
+/* ============================================================
+ * Known suspicious VID/PID pairs (O.MG Cable, Rubber Ducky, etc.)
+ * ============================================================ */
+static const struct {
+ u16 vid;
+ u16 pid;
+ const char *name;
+} suspicious_ids[] = {
+ { 0x16c0, 0x27db, "O.MG Cable (classic)" },
+ { 0x1209, 0xa000, "O.MG Cable (Elite)" },
+ { 0x16c0, 0x27dc, "USB Rubber Ducky" },
+ { 0x1b4f, 0x9208, "LilyPad Arduino BadUSB" },
+};
+
+/* ============================================================
+ * Per-device state (allocated on probe, freed on remove)
+ * ============================================================ */
+struct omg_device_state {
+ struct hid_device *hdev;
+
+ /* --- connection timing --- */
+ ktime_t connect_time;
+ ktime_t first_key_time;
+ bool first_key_seen;
+
+ /* --- keystroke interval circular buffer --- */
+ ktime_t last_key_time;
+ s64 intervals_us[MAX_TIMING_SAMPLES];
+ unsigned int sample_count;
+ unsigned int sample_head;
+
+ /* --- USB info (immutable after probe) --- */
+ u16 vid;
+ u16 pid;
+ const char *vid_pid_match_name; /* non-NULL if VID/PID matched */
+ bool descriptor_anomaly;
+
+ /* --- verdict --- */
+ int score;
+ bool alerted;
+
+ spinlock_t lock;
+};
+
+/* ============================================================
+ * Math helpers
+ * ============================================================ */
+static void timing_stats(struct omg_device_state *s, s64 *mean, s64 *variance)
+{
+ unsigned int i, n;
+ s64 sum = 0, sq = 0, m;
+
+ n = min(s->sample_count, (unsigned int)MAX_TIMING_SAMPLES);
+
+ if (n < 2) {
+ *mean = 0;
+ *variance = 0;
+ return;
+ }
+
+ for (i = 0; i < n; i++)
+ sum += s->intervals_us[i];
+ m = div_s64(sum, n);
+
+ for (i = 0; i < n; i++) {
+ s64 d = s->intervals_us[i] - m;
+
+ sq += d * d;
+ }
+
+ *mean = m;
+ *variance = div_s64(sq, n);
+}
+
+/* ============================================================
+ * Signal 1: Timing entropy
+ *
+ * Humans: high variance (pauses, rhythm changes)
+ * Machines: low variance (constant clock)
+ *
+ * Also penalises extremely fast consistent typing (mean < 15 ms).
+ * ============================================================ */
+static int score_entropy(struct omg_device_state *s)
+{
+ s64 mean, var;
+ int pts = 0;
+
+ if (s->sample_count < MIN_SAMPLES)
+ return 0;
+
+ timing_stats(s, &mean, &var);
+
+ if (var < (s64)entropy_variance_low)
+ pts += 35;
+ else if (var < (s64)entropy_variance_low * 10)
+ pts += 20;
+ else if (var < (s64)entropy_variance_low * 40)
+ pts += 8;
+
+ if (mean > 0 && mean < 5000)
+ pts += 25;
+ else if (mean > 0 && mean < 15000)
+ pts += 10;
+
+ return min(pts, 60);
+}
+
+/* ============================================================
+ * Signal 2: Plug-and-type
+ *
+ * A legitimate keyboard sits idle for a while after connect.
+ * A script device starts injecting within milliseconds.
+ * ============================================================ */
+static int score_plug_type(struct omg_device_state *s)
+{
+ s64 delta_ms;
+
+ if (!s->first_key_seen)
+ return 0;
+
+ delta_ms = ktime_to_ms(ktime_sub(s->first_key_time, s->connect_time));
+
+ if (delta_ms < 100)
+ return 30;
+ if (delta_ms < (s64)plug_type_ms)
+ return 15;
+ if (delta_ms < 2000)
+ return 5;
+
+ return 0;
+}
+
+/* ============================================================
+ * Signal 3: USB descriptor fingerprint
+ * ============================================================ */
+static int score_descriptor(struct omg_device_state *s)
+{
+ int pts = 0;
+
+ if (s->vid_pid_match_name)
+ pts += 50;
+
+ if (s->descriptor_anomaly)
+ pts += 20;
+
+ return min(pts, 50);
+}
+
+/* ============================================================
+ * Combine all signals and return per-signal breakdown.
+ * Caller is responsible for alerting outside any lock.
+ * ============================================================ */
+struct omg_score_result {
+ int entropy;
+ int plug_type;
+ int descriptor;
+ int total;
+ bool newly_alerted;
+};
+
+static void compute_score(struct omg_device_state *s,
+ struct omg_score_result *res)
+{
+ res->entropy = score_entropy(s);
+ res->plug_type = score_plug_type(s);
+ res->descriptor = score_descriptor(s);
+ res->total = min(res->entropy + res->plug_type + res->descriptor,
+ 100);
+
+ s->score = res->total;
+ res->newly_alerted = false;
+
+ if (res->total >= score_threshold && !s->alerted) {
+ s->alerted = true;
+ res->newly_alerted = true;
+ }
+}
+
+/* Emit alert outside of spinlock */
+static void emit_alert(struct hid_device *hdev,
+ struct omg_device_state *s,
+ const struct omg_score_result *res)
+{
+ hid_warn(hdev, "=============================================\n");
+ hid_warn(hdev, "!! SUSPICIOUS HID DEVICE DETECTED !!\n");
+ hid_warn(hdev, "Device : %s\n", hdev->name);
+ hid_warn(hdev, "VID/PID: %04x:%04x\n", s->vid, s->pid);
+ if (s->vid_pid_match_name)
+ hid_warn(hdev, "Match : %s\n", s->vid_pid_match_name);
+ hid_warn(hdev, "Score : %d/100 (threshold=%d)\n",
+ res->total, score_threshold);
+ hid_warn(hdev, " Entropy : %d pts\n", res->entropy);
+ hid_warn(hdev, " Plug-and-type: %d pts\n", res->plug_type);
+ hid_warn(hdev, " Descriptor : %d pts\n", res->descriptor);
+ hid_warn(hdev, "Action : sudo usbguard block-device <id>\n");
+ hid_warn(hdev, "=============================================\n");
+}
+
+/* ============================================================
+ * HID raw_event hook — called for every incoming HID report
+ *
+ * This runs in softirq/BH context — no sleeping locks allowed.
+ * ============================================================ */
+static int omg_raw_event(struct hid_device *hdev,
+ struct hid_report *report,
+ u8 *data, int size)
+{
+ struct omg_device_state *s = hid_get_drvdata(hdev);
+ struct omg_score_result res;
+ ktime_t now;
+ unsigned long flags;
+ bool keystroke = false;
+ int i;
+
+ if (!s)
+ return 0;
+
+ if (report->type != HID_INPUT_REPORT)
+ return 0;
+
+ /* Byte 0 = modifier, byte 1 = reserved, bytes 2-7 = keycodes */
+ for (i = 2; i < size && i < 8; i++) {
+ if (data[i] != 0) {
+ keystroke = true;
+ break;
+ }
+ }
+ if (size > 0 && data[0] != 0)
+ keystroke = true;
+
+ if (!keystroke)
+ return 0;
+
+ now = ktime_get();
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (!s->first_key_seen) {
+ s->first_key_seen = true;
+ s->first_key_time = now;
+ s->last_key_time = now;
+ } else {
+ s64 interval = ktime_to_us(ktime_sub(now, s->last_key_time));
+
+ /* ignore idle gaps > 10 s */
+ if (interval < 10000000LL) {
+ s->intervals_us[s->sample_head] = interval;
+ s->sample_head =
+ (s->sample_head + 1) % MAX_TIMING_SAMPLES;
+ if (s->sample_count < MAX_TIMING_SAMPLES)
+ s->sample_count++;
+ }
+ s->last_key_time = now;
+ }
+
+ compute_score(s, &res);
+
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ /* Alert outside the spinlock — hid_warn may sleep */
+ if (res.newly_alerted)
+ emit_alert(hdev, s, &res);
+
+ return 0;
+}
+
+/* ============================================================
+ * HID probe — device connected
+ * ============================================================ */
+static int omg_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ struct omg_device_state *s;
+ struct usb_interface *intf;
+ struct usb_device *udev;
+ struct omg_score_result res;
+ int ret, i;
+
+ if (hdev->bus != BUS_USB)
+ return -ENODEV;
+
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ spin_lock_init(&s->lock);
+ s->hdev = hdev;
+ s->connect_time = ktime_get();
+
+ /* Extract USB descriptor info */
+ intf = to_usb_interface(hdev->dev.parent);
+ udev = interface_to_usbdev(intf);
+ s->vid = le16_to_cpu(udev->descriptor.idVendor);
+ s->pid = le16_to_cpu(udev->descriptor.idProduct);
+
+ /* Check known bad VID/PID table (once, at probe time) */
+ for (i = 0; i < ARRAY_SIZE(suspicious_ids); i++) {
+ if (s->vid == suspicious_ids[i].vid &&
+ s->pid == suspicious_ids[i].pid) {
+ s->vid_pid_match_name = suspicious_ids[i].name;
+ break;
+ }
+ }
+
+ /*
+ * Anomaly: legitimate HID keyboards use bDeviceClass = 0x00
+ * (class defined at interface level). Any other value here
+ * for a device presenting as a keyboard is suspicious.
+ */
+ s->descriptor_anomaly =
+ (udev->descriptor.bDeviceClass != 0x00 &&
+ udev->descriptor.bDeviceClass != 0x03);
+
+ hid_set_drvdata(hdev, s);
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "hid_parse failed: %d\n", ret);
+ goto err_free;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ hid_err(hdev, "hid_hw_start failed: %d\n", ret);
+ goto err_free;
+ }
+
+ hid_info(hdev, "Monitoring %s (VID=%04x PID=%04x%s%s)\n",
+ hdev->name, s->vid, s->pid,
+ s->vid_pid_match_name ? " KNOWN-BAD:" : "",
+ s->vid_pid_match_name ? s->vid_pid_match_name : "");
+
+ if (s->descriptor_anomaly)
+ hid_warn(hdev, "Descriptor anomaly: bDeviceClass=0x%02x\n",
+ udev->descriptor.bDeviceClass);
+
+ /* Run initial descriptor-only score */
+ compute_score(s, &res);
+ if (res.newly_alerted)
+ emit_alert(hdev, s, &res);
+
+ return 0;
+
+err_free:
+ hid_set_drvdata(hdev, NULL);
+ kfree(s);
+ return ret;
+}
+
+/* ============================================================
+ * HID remove — device disconnected
+ * ============================================================ */
+static void omg_remove(struct hid_device *hdev)
+{
+ struct omg_device_state *s = hid_get_drvdata(hdev);
+
+ hid_hw_stop(hdev);
+
+ if (s) {
+ hid_info(hdev, "Removed %s (final score: %d/100)\n",
+ hdev->name, s->score);
+ hid_set_drvdata(hdev, NULL);
+ kfree(s);
+ }
+}
+
+/* Match all USB HID devices — we inspect and score them all */
+static const struct hid_device_id omg_table[] = {
+ { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, omg_table);
+
+static struct hid_driver omg_driver = {
+ .name = DRIVER_NAME,
+ .id_table = omg_table,
+ .probe = omg_probe,
+ .remove = omg_remove,
+ .raw_event = omg_raw_event,
+};
+
+module_hid_driver(omg_driver);
^ permalink raw reply
* Re: [git pull] Input updates for v7.0-rc6
From: pr-tracker-bot @ 2026-04-04 15:34 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Linus Torvalds, linux-kernel, linux-input
In-Reply-To: <adCpWQOyfvE6E6k0@google.com>
The pull request you sent on Fri, 3 Apr 2026 23:02:12 -0700:
> git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v7.0-rc6
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/3aae9383f42f687221c011d7ee87529398e826b3
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* [PATCH] HID: winwing: add support for URSA MINOR combat joysticks
From: René Onier @ 2026-04-04 17:26 UTC (permalink / raw)
To: linux-input; +Cc: jikos, bentiss, ivan.gorinov, rene.onier
Add device IDs for the Winwing URSA MINOR Combat Joystick L (0xbc29)
and R (0xbc2a). These joysticks declare 128 buttons in their HID
report descriptor, causing the generic HID driver to reject buttons
above KEY_MAX (767) with "Invalid code" errors.
The URSA MINOR joysticks use buttons in the 33-64 range for grip
controls including the index trigger, so map_more_buttons is set
to 1 to enable the extended KEY_MACRO mapping.
Tested with both left and right URSA MINOR joysticks on kernel 6.19.
Signed-off-by: René Onier <rene.onier@gmail.com>
---
hid-winwing.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hid-winwing.c b/hid-winwing.c
index ab65dc1..f3e6ea0 100644
--- a/hid-winwing.c
+++ b/hid-winwing.c
@@ -250,6 +250,8 @@ static const struct hid_device_id winwing_devices[] = {
{ HID_USB_DEVICE(0x4098, 0xbd64), .driver_data = 1 }, /* TGRIP-15EX */
{ HID_USB_DEVICE(0x4098, 0xbe68), .driver_data = 0 }, /* TGRIP-16EX */
{ HID_USB_DEVICE(0x4098, 0xbe62), .driver_data = 0 }, /* TGRIP-18 */
+ { HID_USB_DEVICE(0x4098, 0xbc29), .driver_data = 1 }, /* URSA MINOR L */
+ { HID_USB_DEVICE(0x4098, 0xbc2a), .driver_data = 1 }, /* URSA MINOR R */
{}
};
--
2.43.0
^ permalink raw reply related
* [dtor-input:for-linus] BUILD SUCCESS 0d9363a764d9d601a05591f9695cea8b429e9be3
From: kernel test robot @ 2026-04-04 18:08 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
branch HEAD: 0d9363a764d9d601a05591f9695cea8b429e9be3 Input: xpad - add support for BETOP BTP-KP50B/C controller's wireless mode
elapsed time: 735m
configs tested: 195
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc defconfig gcc-15.2.0
arc randconfig-001-20260404 gcc-15.2.0
arc randconfig-002-20260404 gcc-15.2.0
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm defconfig gcc-15.2.0
arm randconfig-001-20260404 gcc-15.2.0
arm randconfig-002-20260404 gcc-15.2.0
arm randconfig-003-20260404 gcc-15.2.0
arm randconfig-004-20260404 gcc-15.2.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001-20260404 gcc-15.2.0
arm64 randconfig-001-20260404 gcc-8.5.0
arm64 randconfig-002-20260404 gcc-15.2.0
arm64 randconfig-002-20260404 gcc-8.5.0
arm64 randconfig-003-20260404 clang-23
arm64 randconfig-003-20260404 gcc-15.2.0
arm64 randconfig-004-20260404 gcc-15.2.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001-20260404 gcc-15.2.0
csky randconfig-001-20260404 gcc-9.5.0
csky randconfig-002-20260404 gcc-15.2.0
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260404 gcc-15.2.0
hexagon randconfig-002-20260404 gcc-15.2.0
i386 allmodconfig clang-20
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 buildonly-randconfig-001-20260404 clang-20
i386 buildonly-randconfig-001-20260404 gcc-14
i386 buildonly-randconfig-002-20260404 clang-20
i386 buildonly-randconfig-003-20260404 clang-20
i386 buildonly-randconfig-003-20260404 gcc-14
i386 buildonly-randconfig-004-20260404 clang-20
i386 buildonly-randconfig-005-20260404 clang-20
i386 buildonly-randconfig-006-20260404 clang-20
i386 defconfig gcc-15.2.0
i386 randconfig-001-20260404 clang-20
i386 randconfig-002-20260404 clang-20
i386 randconfig-003-20260404 clang-20
i386 randconfig-004-20260404 clang-20
i386 randconfig-005-20260404 clang-20
i386 randconfig-006-20260404 clang-20
i386 randconfig-007-20260404 clang-20
i386 randconfig-011-20260404 clang-20
i386 randconfig-012-20260404 clang-20
i386 randconfig-013-20260404 clang-20
i386 randconfig-014-20260404 clang-20
i386 randconfig-015-20260404 clang-20
i386 randconfig-016-20260404 clang-20
i386 randconfig-017-20260404 clang-20
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch randconfig-001-20260404 gcc-15.2.0
loongarch randconfig-002-20260404 gcc-15.2.0
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k defconfig clang-19
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
mips omega2p_defconfig clang-23
nios2 allmodconfig clang-23
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-19
nios2 randconfig-001-20260404 gcc-15.2.0
nios2 randconfig-002-20260404 gcc-15.2.0
openrisc allmodconfig clang-23
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-15.2.0
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-15.2.0
parisc allyesconfig clang-19
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260404 gcc-13.4.0
parisc randconfig-002-20260404 gcc-15.2.0
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-15.2.0
powerpc ksi8560_defconfig gcc-15.2.0
powerpc mpc834x_itx_defconfig clang-16
powerpc randconfig-001-20260404 gcc-8.5.0
powerpc randconfig-002-20260404 clang-23
powerpc64 randconfig-001-20260404 clang-23
powerpc64 randconfig-002-20260404 gcc-10.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-15.2.0
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260404 clang-19
riscv randconfig-001-20260404 clang-20
riscv randconfig-002-20260404 clang-20
riscv randconfig-002-20260404 clang-23
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260404 clang-20
s390 randconfig-002-20260404 clang-20
s390 randconfig-002-20260404 clang-23
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-23
sh allnoconfig gcc-15.2.0
sh allyesconfig clang-19
sh defconfig gcc-14
sh randconfig-001-20260404 clang-20
sh randconfig-001-20260404 gcc-15.2.0
sh randconfig-002-20260404 clang-20
sh randconfig-002-20260404 gcc-9.5.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-15.2.0
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260404 clang-20
sparc randconfig-002-20260404 clang-20
sparc64 allmodconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260404 clang-20
sparc64 randconfig-002-20260404 clang-20
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-15.2.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260404 clang-20
um randconfig-002-20260404 clang-20
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-20
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20260404 gcc-13
x86_64 buildonly-randconfig-002-20260404 gcc-13
x86_64 buildonly-randconfig-003-20260404 gcc-13
x86_64 buildonly-randconfig-004-20260404 gcc-13
x86_64 buildonly-randconfig-005-20260404 gcc-13
x86_64 buildonly-randconfig-006-20260404 gcc-13
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260404 gcc-14
x86_64 randconfig-002-20260404 gcc-14
x86_64 randconfig-003-20260404 gcc-14
x86_64 randconfig-004-20260404 gcc-14
x86_64 randconfig-005-20260404 gcc-14
x86_64 randconfig-006-20260404 gcc-14
x86_64 randconfig-011-20260404 clang-20
x86_64 randconfig-011-20260404 gcc-14
x86_64 randconfig-012-20260404 gcc-14
x86_64 randconfig-013-20260404 clang-20
x86_64 randconfig-013-20260404 gcc-14
x86_64 randconfig-014-20260404 clang-20
x86_64 randconfig-014-20260404 gcc-14
x86_64 randconfig-015-20260404 clang-20
x86_64 randconfig-015-20260404 gcc-14
x86_64 randconfig-016-20260404 clang-20
x86_64 randconfig-016-20260404 gcc-14
x86_64 randconfig-071-20260404 gcc-14
x86_64 randconfig-072-20260404 gcc-14
x86_64 randconfig-073-20260404 gcc-14
x86_64 randconfig-074-20260404 gcc-14
x86_64 randconfig-075-20260404 gcc-14
x86_64 randconfig-076-20260404 gcc-14
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-15.2.0
xtensa allyesconfig clang-23
xtensa randconfig-001-20260404 clang-20
xtensa randconfig-002-20260404 clang-20
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [dtor-input:next] BUILD SUCCESS 84e7a17d1813394b48b0641fce8217fc0bba1960
From: kernel test robot @ 2026-04-04 18:08 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
branch HEAD: 84e7a17d1813394b48b0641fce8217fc0bba1960 Input: xpad - add RedOctane Games vendor id
elapsed time: 735m
configs tested: 235
configs skipped: 3
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allmodconfig gcc-15.2.0
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc allyesconfig gcc-15.2.0
arc defconfig gcc-15.2.0
arc randconfig-001-20260404 gcc-15.2.0
arc randconfig-001-20260404 gcc-8.5.0
arc randconfig-002-20260404 gcc-15.2.0
arc randconfig-002-20260404 gcc-8.5.0
arm allnoconfig clang-23
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm allyesconfig gcc-15.2.0
arm defconfig gcc-15.2.0
arm randconfig-001-20260404 gcc-14.3.0
arm randconfig-001-20260404 gcc-15.2.0
arm randconfig-002-20260404 gcc-15.2.0
arm randconfig-003-20260404 gcc-10.5.0
arm randconfig-003-20260404 gcc-15.2.0
arm randconfig-004-20260404 gcc-12.5.0
arm randconfig-004-20260404 gcc-15.2.0
arm64 allmodconfig clang-19
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001-20260404 gcc-15.2.0
arm64 randconfig-001-20260404 gcc-8.5.0
arm64 randconfig-002-20260404 gcc-15.2.0
arm64 randconfig-002-20260404 gcc-8.5.0
arm64 randconfig-003-20260404 clang-23
arm64 randconfig-003-20260404 gcc-15.2.0
arm64 randconfig-004-20260404 gcc-15.2.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001-20260404 gcc-15.2.0
csky randconfig-001-20260404 gcc-9.5.0
csky randconfig-002-20260404 gcc-15.2.0
hexagon allmodconfig clang-17
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260404 gcc-15.2.0
hexagon randconfig-002-20260404 gcc-15.2.0
i386 allmodconfig clang-20
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 allyesconfig gcc-14
i386 buildonly-randconfig-001-20260404 clang-20
i386 buildonly-randconfig-001-20260404 gcc-14
i386 buildonly-randconfig-002-20260404 clang-20
i386 buildonly-randconfig-003-20260404 clang-20
i386 buildonly-randconfig-003-20260404 gcc-14
i386 buildonly-randconfig-004-20260404 clang-20
i386 buildonly-randconfig-005-20260404 clang-20
i386 buildonly-randconfig-006-20260404 clang-20
i386 defconfig gcc-15.2.0
i386 randconfig-001-20260404 clang-20
i386 randconfig-002-20260404 clang-20
i386 randconfig-003-20260404 clang-20
i386 randconfig-004-20260404 clang-20
i386 randconfig-005-20260404 clang-20
i386 randconfig-005-20260404 gcc-14
i386 randconfig-006-20260404 clang-20
i386 randconfig-007-20260404 clang-20
i386 randconfig-011-20260404 clang-20
i386 randconfig-012-20260404 clang-20
i386 randconfig-013-20260404 clang-20
i386 randconfig-014-20260404 clang-20
i386 randconfig-015-20260404 clang-20
i386 randconfig-015-20260404 gcc-14
i386 randconfig-016-20260404 clang-20
i386 randconfig-017-20260404 clang-20
i386 randconfig-017-20260404 gcc-12
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch randconfig-001-20260404 gcc-15.2.0
loongarch randconfig-002-20260404 gcc-15.2.0
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k allyesconfig gcc-15.2.0
m68k defconfig clang-19
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
mips omega2p_defconfig clang-23
nios2 allmodconfig clang-23
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-19
nios2 randconfig-001-20260404 gcc-15.2.0
nios2 randconfig-002-20260404 gcc-15.2.0
openrisc allmodconfig clang-23
openrisc allmodconfig gcc-15.2.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-15.2.0
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-15.2.0
parisc allyesconfig clang-19
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260404 gcc-13.4.0
parisc randconfig-002-20260404 gcc-15.2.0
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-15.2.0
powerpc bamboo_defconfig clang-23
powerpc ep88xc_defconfig gcc-15.2.0
powerpc ksi8560_defconfig gcc-15.2.0
powerpc mpc834x_itx_defconfig clang-16
powerpc randconfig-001-20260404 gcc-8.5.0
powerpc randconfig-002-20260404 clang-23
powerpc64 randconfig-001-20260404 clang-23
powerpc64 randconfig-002-20260404 gcc-10.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-15.2.0
riscv allyesconfig clang-16
riscv defconfig clang-23
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260404 clang-19
riscv randconfig-001-20260404 clang-20
riscv randconfig-002-20260404 clang-20
riscv randconfig-002-20260404 clang-23
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig clang-23
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260404 clang-20
s390 randconfig-002-20260404 clang-20
s390 randconfig-002-20260404 clang-23
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-23
sh allnoconfig gcc-15.2.0
sh allyesconfig clang-19
sh defconfig gcc-14
sh defconfig gcc-15.2.0
sh randconfig-001-20260404 clang-20
sh randconfig-001-20260404 gcc-15.2.0
sh randconfig-002-20260404 clang-20
sh randconfig-002-20260404 gcc-9.5.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-15.2.0
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260404 clang-20
sparc randconfig-001-20260404 gcc-15.2.0
sparc randconfig-002-20260404 clang-20
sparc randconfig-002-20260404 gcc-8.5.0
sparc64 allmodconfig clang-23
sparc64 defconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260404 clang-20
sparc64 randconfig-001-20260404 gcc-14.3.0
sparc64 randconfig-002-20260404 clang-20
sparc64 randconfig-002-20260404 clang-23
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-15.2.0
um defconfig clang-23
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260404 clang-20
um randconfig-002-20260404 clang-20
um randconfig-002-20260404 gcc-14
um x86_64_defconfig clang-23
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-20
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20260404 gcc-13
x86_64 buildonly-randconfig-002-20260404 gcc-13
x86_64 buildonly-randconfig-003-20260404 gcc-13
x86_64 buildonly-randconfig-004-20260404 gcc-13
x86_64 buildonly-randconfig-005-20260404 gcc-13
x86_64 buildonly-randconfig-006-20260404 gcc-13
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260404 gcc-14
x86_64 randconfig-002-20260404 gcc-14
x86_64 randconfig-003-20260404 gcc-14
x86_64 randconfig-004-20260404 gcc-14
x86_64 randconfig-005-20260404 gcc-14
x86_64 randconfig-006-20260404 gcc-14
x86_64 randconfig-011-20260404 clang-20
x86_64 randconfig-011-20260404 gcc-14
x86_64 randconfig-012-20260404 gcc-14
x86_64 randconfig-013-20260404 clang-20
x86_64 randconfig-013-20260404 gcc-14
x86_64 randconfig-014-20260404 clang-20
x86_64 randconfig-014-20260404 gcc-14
x86_64 randconfig-015-20260404 clang-20
x86_64 randconfig-015-20260404 gcc-14
x86_64 randconfig-016-20260404 clang-20
x86_64 randconfig-016-20260404 gcc-14
x86_64 randconfig-071-20260404 gcc-14
x86_64 randconfig-072-20260404 gcc-14
x86_64 randconfig-073-20260404 gcc-14
x86_64 randconfig-074-20260404 gcc-14
x86_64 randconfig-075-20260404 gcc-14
x86_64 randconfig-076-20260404 gcc-14
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-15.2.0
xtensa allyesconfig clang-23
xtensa allyesconfig gcc-15.2.0
xtensa randconfig-001-20260404 clang-20
xtensa randconfig-001-20260404 gcc-11.5.0
xtensa randconfig-002-20260404 clang-20
xtensa randconfig-002-20260404 gcc-13.4.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v2 0/1] HID: add malicious HID device detection driver
From: Greg KH @ 2026-04-05 5:31 UTC (permalink / raw)
To: Zubeyr Almaho
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel,
security
In-Reply-To: <20260404133746.80914-1-zybo1000@gmail.com>
On Sat, Apr 04, 2026 at 04:37:44PM +0300, Zubeyr Almaho wrote:
> Hi Jiri, Benjamin,
>
> This series introduces hid-omg-detect, a passive HID monitor that scores
> potentially malicious keyboard-like USB devices (BadUSB / O.MG style)
> using:
>
> - keystroke timing entropy,
> - plug-and-type latency,
> - USB descriptor fingerprinting.
>
> When the configurable threshold is crossed, the module emits a warning
> with a userspace mitigation hint (usbguard).
>
> The driver does not block, delay, or modify HID input events.
That's cute, but no need to get security@kernel.org involved as this is
a new feature, not a bug triage.
Also, why not just do this as an ebpf program instead as you have full
access to the hid data stream there?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH RESEND] Input: atkbd - skip cleanup when used as a wakeup source
From: Henry Barnor @ 2026-04-05 5:36 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: hbarnor, linux-input, linux-kernel
In-Reply-To: <acrwy_Y6QMapp5fw@google.com>
Hi Dmitry,
> We unfortunately need to support devices much older than that, so we can
> not be sure that this change is safe. Historically there we a lot of
> instances where systems were unhappy if we attempted to enter shutdown
> or suspend paths with devices in state other than freshly reset.
Thanks for the feedback and the context on legacy hardware risks. That makes sense.
I will explore handling this within the Android system layer instead.
Thanks.
^ permalink raw reply
* [PATCH] HID: sony: fix style issues
From: Rosalie Wanders @ 2026-04-06 2:47 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, Henrik Rydberg
Cc: Rosalie Wanders, linux-input, linux-kernel
This commit fixes inconsistent quirk names and also fixes all the
checkpatch.pl issues alongside inconsistent code, it also adds static
asserts to assert struct sizes at compile time.
Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
---
drivers/hid/hid-sony.c | 79 +++++++++++++++++++-----------------------
1 file changed, 35 insertions(+), 44 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index bd4b4a470869..695ca085b410 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -67,8 +67,8 @@
#define RB4_GUITAR_PS4_USB BIT(18)
#define RB4_GUITAR_PS4_BT BIT(19)
#define RB4_GUITAR_PS5 BIT(20)
-#define RB3_PS3_PRO_INSTRUMENT BIT(21)
-#define PS3_DJH_TURNTABLE BIT(22)
+#define RB3_PRO_INSTRUMENT BIT(21)
+#define DJH_TURNTABLE BIT(22)
#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
#define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
@@ -110,13 +110,6 @@ static const char ghl_ps4_magic_data[] = {
0x30, 0x02, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00
};
-/* Rock Band 3 PS3 Pro Instruments require sending a report
- * once an instrument is connected to its dongle.
- * We need to retry sending these reports,
- * but to avoid doing this too often we delay the retries
- */
-#define RB3_PRO_INSTRUMENT_POKE_RETRY_INTERVAL 8 /* In seconds */
-
/* PS/3 Motion controller */
static const u8 motion_rdesc[] = {
0x05, 0x01, /* Usage Page (Desktop), */
@@ -477,6 +470,7 @@ struct sixaxis_led {
u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */
} __packed;
+static_assert(sizeof(struct sixaxis_led) == 5);
struct sixaxis_rumble {
u8 padding;
@@ -485,6 +479,7 @@ struct sixaxis_rumble {
u8 left_duration; /* Left motor duration (0xff means forever) */
u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
} __packed;
+static_assert(sizeof(struct sixaxis_rumble) == 5);
struct sixaxis_output_report {
u8 report_id;
@@ -494,11 +489,13 @@ struct sixaxis_output_report {
struct sixaxis_led led[4]; /* LEDx at (4 - x) */
struct sixaxis_led _reserved; /* LED5, not actually soldered */
} __packed;
+static_assert(sizeof(struct sixaxis_output_report) == 36);
union sixaxis_output_report_01 {
struct sixaxis_output_report data;
u8 buf[36];
};
+static_assert(sizeof(union sixaxis_output_report_01) == 36);
struct motion_output_report_02 {
u8 type, zero;
@@ -506,6 +503,7 @@ struct motion_output_report_02 {
u8 zero2;
u8 rumble;
};
+static_assert(sizeof(struct motion_output_report_02) == 7);
#define SIXAXIS_REPORT_0xF2_SIZE 17
#define SIXAXIS_REPORT_0xF5_SIZE 8
@@ -536,7 +534,7 @@ struct sony_sc {
struct led_classdev *leds[MAX_LEDS];
unsigned long quirks;
struct work_struct state_worker;
- void (*send_output_report)(struct sony_sc *);
+ void (*send_output_report)(struct sony_sc *sc);
struct power_supply *battery;
struct power_supply_desc battery_desc;
int device_id;
@@ -613,11 +611,11 @@ static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev,
pipe = usb_sndctrlpipe(usbdev, 0);
cr = devm_kzalloc(&sc->hdev->dev, sizeof(*cr), GFP_ATOMIC);
- if (cr == NULL)
+ if (!cr)
return -ENOMEM;
databuf = devm_kzalloc(&sc->hdev->dev, poke_size, GFP_ATOMIC);
- if (databuf == NULL)
+ if (!databuf)
return -ENOMEM;
cr->bRequestType =
@@ -952,6 +950,7 @@ static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size)
static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
unsigned long flags;
int offset;
+ u8 index;
u8 battery_capacity;
int battery_status;
@@ -967,7 +966,7 @@ static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size)
battery_capacity = 100;
battery_status = (rd[offset] & 0x01) ? POWER_SUPPLY_STATUS_FULL : POWER_SUPPLY_STATUS_CHARGING;
} else {
- u8 index = rd[offset] <= 5 ? rd[offset] : 5;
+ index = rd[offset] <= 5 ? rd[offset] : 5;
battery_capacity = sixaxis_battery_capacity[index];
battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
}
@@ -1005,7 +1004,7 @@ static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size)
* the touch-related data starts at offset 2.
* For the first byte, bit 0 is set when touchpad button is pressed.
* Bit 2 is set when a touch is active and the drag (Fn) key is pressed.
- * This drag key is mapped to BTN_LEFT. It is operational only when a
+ * This drag key is mapped to BTN_LEFT. It is operational only when a
* touch point is active.
* Bit 4 is set when only the first touch point is active.
* Bit 6 is set when only the second touch point is active.
@@ -1152,11 +1151,10 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
/* Rock Band 3 PS3 Pro instruments set rd[24] to 0xE0 when they're
* sending full reports, and 0x02 when only sending navigation.
*/
- if ((sc->quirks & RB3_PS3_PRO_INSTRUMENT) && rd[24] == 0x02) {
- /* Only attempt to enable report every 8 seconds */
+ if ((sc->quirks & RB3_PRO_INSTRUMENT) && rd[24] == 0x02) {
+ /* Only attempt to enable full report every 8 seconds */
if (time_after(jiffies, sc->rb3_pro_poke_jiffies)) {
- sc->rb3_pro_poke_jiffies = jiffies +
- (RB3_PRO_INSTRUMENT_POKE_RETRY_INTERVAL * HZ);
+ sc->rb3_pro_poke_jiffies = jiffies + secs_to_jiffies(8);
rb3_pro_instrument_enable_full_report(sc);
}
}
@@ -1218,7 +1216,7 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
if (sc->quirks & GH_GUITAR_TILT)
return gh_guitar_mapping(hdev, hi, field, usage, bit, max);
- if (sc->quirks & PS3_DJH_TURNTABLE)
+ if (sc->quirks & DJH_TURNTABLE)
return djh_turntable_mapping(hdev, hi, field, usage, bit, max);
if (sc->quirks & (RB4_GUITAR_PS4_USB | RB4_GUITAR_PS4_BT))
@@ -1273,19 +1271,18 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
if (touch_major > 0) {
- input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR,
+ input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR,
0, touch_major, 0, 0);
if (touch_minor > 0)
- input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR,
+ input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR,
0, touch_minor, 0, 0);
if (orientation > 0)
- input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION,
+ input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION,
0, orientation, 0, 0);
}
- if (sc->quirks & NSG_MRXU_REMOTE) {
+ if (sc->quirks & NSG_MRXU_REMOTE)
__set_bit(EV_REL, sc->touchpad->evbit);
- }
ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
if (ret < 0)
@@ -1440,7 +1437,7 @@ static void sixaxis_set_leds_from_id(struct sony_sc *sc)
int id = sc->device_id;
- BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
+ BUILD_BUG_ON(ARRAY_SIZE(sixaxis_leds[0]) > MAX_LEDS);
if (id < 0)
return;
@@ -1458,7 +1455,7 @@ static void buzz_set_leds(struct sony_sc *sc)
struct hid_report, list);
s32 *value = report->field[0]->value;
- BUILD_BUG_ON(MAX_LEDS < 4);
+ BUILD_BUG_ON(4 > MAX_LEDS);
value[0] = 0x00;
value[1] = sc->led_state[0] ? 0xff : 0x00;
@@ -1655,15 +1652,12 @@ static int sony_leds_init(struct sony_sc *sc)
name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_name_str[n]) + 2;
led = devm_kzalloc(&hdev->dev, sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
- if (!led) {
- hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
+ if (!led)
return -ENOMEM;
- }
name = (void *)(&led[1]);
if (use_color_names)
- snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
- color_name_str[n]);
+ snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_name_str[n]);
else
snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
led->name = name;
@@ -2180,7 +2174,7 @@ static int sony_input_configured(struct hid_device *hdev,
}
sony_init_output_report(sc, sixaxis_send_output_report);
- } else if (sc->quirks & RB3_PS3_PRO_INSTRUMENT) {
+ } else if (sc->quirks & RB3_PRO_INSTRUMENT) {
/*
* Rock Band 3 PS3 Pro Instruments also do not handle HID Output
* Reports on the interrupt EP like they should, so we need to force
@@ -2309,10 +2303,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
quirks |= SHANWAN_GAMEPAD;
sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
- if (sc == NULL) {
- hid_err(hdev, "can't alloc sony descriptor\n");
+ if (!sc)
return -ENOMEM;
- }
spin_lock_init(&sc->lock);
@@ -2360,9 +2352,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err;
}
- if (sc->quirks & RB3_PS3_PRO_INSTRUMENT) {
+ if (sc->quirks & RB3_PRO_INSTRUMENT)
sc->rb3_pro_poke_jiffies = 0;
- }
if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) {
if (!hid_is_usb(hdev)) {
@@ -2514,7 +2505,7 @@ static const struct hid_device_id sony_devices[] = {
.driver_data = INSTRUMENT },
/* DJ Hero PS3 Guitar Dongle */
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE),
- .driver_data = PS3_DJH_TURNTABLE | INSTRUMENT },
+ .driver_data = DJH_TURNTABLE | INSTRUMENT },
/* Guitar Hero Live PS4 guitar dongles */
{ HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE),
.driver_data = GHL_GUITAR_PS4 | GH_GUITAR_TILT | INSTRUMENT },
@@ -2552,17 +2543,17 @@ static const struct hid_device_id sony_devices[] = {
.driver_data = INSTRUMENT },
/* Rock Band 3 PS3 Pro instruments */
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR),
- .driver_data = INSTRUMENT | RB3_PS3_PRO_INSTRUMENT },
+ .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_SQUIRE_GUITAR),
- .driver_data = INSTRUMENT | RB3_PS3_PRO_INSTRUMENT },
+ .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE),
- .driver_data = INSTRUMENT | RB3_PS3_PRO_INSTRUMENT },
+ .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIRE_MODE),
- .driver_data = INSTRUMENT | RB3_PS3_PRO_INSTRUMENT },
+ .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD),
- .driver_data = INSTRUMENT | RB3_PS3_PRO_INSTRUMENT },
+ .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE),
- .driver_data = INSTRUMENT | RB3_PS3_PRO_INSTRUMENT },
+ .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT },
/* Rock Band 4 PS4 guitars */
{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER),
.driver_data = RB4_GUITAR_PS4_USB | INSTRUMENT },
--
2.53.0
^ permalink raw reply related
* [PATCH] HID: alps: fix NULL pointer dereference in alps_raw_event()
From: Greg Kroah-Hartman @ 2026-04-06 14:03 UTC (permalink / raw)
To: linux-input
Cc: linux-kernel, Greg Kroah-Hartman, stable, Jiri Kosina,
Benjamin Tissoires, Masaki Ota
Commit ecfa6f34492c ("HID: Add HID_CLAIMED_INPUT guards in raw_event
callbacks missing them") attempted to fix up the HID drivers that had
missed the previous fix that was done in 2ff5baa9b527 ("HID: appleir:
Fix potential NULL dereference at raw event handle"), but the alps
driver was missed.
Fix this up by properly checking in the hid-alps driver that it had been
claimed correctly before attempting to process the raw event.
Fixes: 73196ebe134d ("HID: alps: add support for Alps T4 Touchpad device")
Cc: stable <stable@kernel.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Benjamin Tissoires <bentiss@kernel.org>
Cc: Masaki Ota <masaki.ota@jp.alps.com>
Cc: linux-input@vger.kernel.org
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-alps.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index 21e55f3d0d1b..67179e3fe39b 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -437,6 +437,9 @@ static int alps_raw_event(struct hid_device *hdev,
int ret = 0;
struct alps_dev *hdata = hid_get_drvdata(hdev);
+ if (!(hdev->claimed & HID_CLAIMED_INPUT) || !hdata->input)
+ return 0;
+
switch (hdev->product) {
case HID_PRODUCT_ID_T4_BTNLESS:
ret = t4_raw_event(hdata, data, size);
--
2.53.0
^ permalink raw reply related
* [PATCH] HID: core: clamp report_size in s32ton() to avoid undefined shift
From: Greg Kroah-Hartman @ 2026-04-06 14:04 UTC (permalink / raw)
To: linux-input
Cc: linux-kernel, Greg Kroah-Hartman, stable, Jiri Kosina,
Benjamin Tissoires
s32ton() shifts by n-1 where n is the field's report_size, a value that
comes directly from a HID device. The HID parser bounds report_size
only to <= 256, so a broken HID device can supply a report descriptor
with a wide field that triggers shift exponents up to 256 on a 32-bit
type when an output report is built via hid_output_field() or
hid_set_field().
Commit ec61b41918587 ("HID: core: fix shift-out-of-bounds in
hid_report_raw_event") added the same n > 32 clamp to the function
snto32(), but s32ton() was never given the same fix as I guess syzbot
hadn't figured out how to fuzz a device the same way.
Fix this up by just clamping the max value of n, just like snto32()
does.
Cc: stable <stable@kernel.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Benjamin Tissoires <bentiss@kernel.org>
Cc: linux-input@vger.kernel.org
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 833df14ef68f..868c65684aa8 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -71,6 +71,9 @@ static u32 s32ton(__s32 value, unsigned int n)
if (!value || !n)
return 0;
+ if (n > 32)
+ n = 32;
+
a = value >> (n - 1);
if (a && a != -1)
return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
--
2.53.0
^ permalink raw reply related
* [PATCH] Input: gpio-keys - add hibernation support
From: Armando De Leon @ 2026-04-06 16:04 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Armando De Leon
The gpio-keys driver uses DEFINE_SIMPLE_DEV_PM_OPS which maps .freeze
and .restore to the same callbacks as .suspend and .resume. This is
insufficient for hibernation (suspend-to-disk) because the SoC is fully
powered off, unlike suspend-to-RAM where hardware state is preserved.
After hibernation resume, GPIO keys fail to function correctly because
the interrupt controller (e.g. GIC) is fully re-initialized during
restore, resetting all IRQ trigger type configurations to defaults.
GPIO keys require IRQ_TYPE_EDGE_BOTH for proper press/release detection,
but after the interrupt controller re-initialization only a single edge
remains active. This causes buttons to report only release events but
not press events, or vice versa.
The existing gpio_keys_button_disable_wakeup() does restore
IRQ_TYPE_EDGE_BOTH, but only when wakeup_trigger_type is non-zero.
When the device tree does not specify wakeup-event-action (the common
case), wakeup_trigger_type defaults to zero and the IRQ type
restoration is skipped entirely.
Fix this by implementing dedicated .freeze and .restore callbacks:
- gpio_keys_freeze(): Marks all buttons as suspended before the
hibernate image is created. Unlike .suspend, it does not configure
wakeup IRQs since the SoC will be powered off.
- gpio_keys_restore(): Re-applies the pinctrl default state to restore
GPIO pin configuration, explicitly reconfigures IRQ trigger type to
IRQ_TYPE_EDGE_BOTH for all GPIO-backed buttons, clears the suspended
flag, and re-syncs current GPIO state with the input subsystem.
The .thaw callback reuses gpio_keys_resume() since the SoC remains
powered when hibernation is aborted and hardware state is intact.
Signed-off-by: Armando De Leon <learmand@amazon.com>
---
drivers/input/keyboard/gpio_keys.c | 60 +++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index e19617485..9fb77c9aa 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -27,6 +27,7 @@
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_irq.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/spinlock.h>
#include <dt-bindings/input/gpio-keys.h>
@@ -1088,7 +1089,64 @@ static int gpio_keys_resume(struct device *dev)
return 0;
}
-static DEFINE_SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume);
+static int gpio_keys_freeze(struct device *dev)
+{
+ struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
+ struct gpio_button_data *bdata;
+ int i;
+
+ for (i = 0; i < ddata->pdata->nbuttons; i++) {
+ bdata = &ddata->data[i];
+ bdata->suspended = true;
+ }
+
+ return 0;
+}
+
+static int gpio_keys_restore(struct device *dev)
+{
+ struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
+ struct gpio_button_data *bdata;
+ int error;
+ int i;
+
+ error = pinctrl_pm_select_default_state(dev);
+ if (error)
+ dev_warn(dev, "failed to restore pinctrl default state: %d\n",
+ error);
+
+ for (i = 0; i < ddata->pdata->nbuttons; i++) {
+ bdata = &ddata->data[i];
+ bdata->suspended = false;
+
+ /*
+ * After hibernation the interrupt controller is
+ * re-initialized and loses its configuration.
+ * Restore dual-edge triggering for GPIO-backed
+ * buttons so both press and release are detected.
+ */
+ if (bdata->gpiod) {
+ error = irq_set_irq_type(bdata->irq,
+ IRQ_TYPE_EDGE_BOTH);
+ if (error)
+ dev_warn(dev,
+ "failed to restore IRQ %d trigger: %d\n",
+ bdata->irq, error);
+ }
+ }
+
+ gpio_keys_report_state(ddata);
+ return 0;
+}
+
+static const struct dev_pm_ops gpio_keys_pm_ops = {
+ .suspend = gpio_keys_suspend,
+ .resume = gpio_keys_resume,
+ .freeze = gpio_keys_freeze,
+ .restore = gpio_keys_restore,
+ .thaw = gpio_keys_resume,
+ .poweroff = gpio_keys_suspend,
+};
static void gpio_keys_shutdown(struct platform_device *pdev)
{
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] Input: gpio-keys - add hibernation support
From: Dmitry Torokhov @ 2026-04-06 16:24 UTC (permalink / raw)
To: Armando De Leon; +Cc: linux-input, linux-kernel, Armando De Leon
In-Reply-To: <20260406160437.3084755-1-learmand@amazon.com>
Hi Armando,
On Mon, Apr 06, 2026 at 09:04:37AM -0700, Armando De Leon wrote:
> The gpio-keys driver uses DEFINE_SIMPLE_DEV_PM_OPS which maps .freeze
> and .restore to the same callbacks as .suspend and .resume. This is
> insufficient for hibernation (suspend-to-disk) because the SoC is fully
> powered off, unlike suspend-to-RAM where hardware state is preserved.
>
> After hibernation resume, GPIO keys fail to function correctly because
> the interrupt controller (e.g. GIC) is fully re-initialized during
> restore, resetting all IRQ trigger type configurations to defaults.
> GPIO keys require IRQ_TYPE_EDGE_BOTH for proper press/release detection,
> but after the interrupt controller re-initialization only a single edge
> remains active. This causes buttons to report only release events but
> not press events, or vice versa.
I believe you just described a bug in the interrupt controller handling
of hibernation. It needs to be fixed there, not in consumer driver.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: gpio-keys - add hibernation support
From: Armando De Leon @ 2026-04-06 16:58 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: Armando De Leon, linux-input, linux-kernel
In-Reply-To: <adPdc2Z1SYxvqDmP@google.com>
Hi Dmitry,
Thank you for the review.
The interrupt controller (GICv3) is re-initialized by platform
firmware during hibernate restore - this is expected behavior, not
a bug. The IRQ trigger type (EDGE_BOTH) was originally configured
by devm_request_any_context_irq() during probe(), which does not
run again after hibernate restore.
The TLMM/pinctrl registers are correctly saved and restored by the
platform's syscore_ops - I verified this with register dumps. The
issue is specifically that the IRQ trigger type configured at the
GIC level during probe is lost and not re-applied.
Should the generic IRQ core be responsible for restoring trigger
types across hibernate? Otherwise, consumer drivers like gpio-keys need to handle
this in their .restore callback.
Either way, gpio-keys currently lacks .freeze/.restore callbacks
entirely, which is needed for proper hibernation support.
Thanks,
Armando
^ permalink raw reply
* Re: [PATCH 1/2] input: pc110pad: change PCI check to get rid of orphaned no_pci_devices
From: Bjorn Helgaas @ 2026-04-06 17:23 UTC (permalink / raw)
To: Heiner Kallweit
Cc: Dmitry Torokhov, Bjorn Helgaas, open list:HID CORE LAYER,
linux-pci@vger.kernel.org
In-Reply-To: <cf519463-775a-4d43-be38-20742fdad407@gmail.com>
On Fri, Apr 03, 2026 at 12:17:35AM +0200, Heiner Kallweit wrote:
> As a prerequisite for removing no_pci_devices(), replace its usage here
> with an equivalent check for presence of a PCI bus.
>
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
> drivers/input/mouse/pc110pad.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
> index efa58049f..c7a6df210 100644
> --- a/drivers/input/mouse/pc110pad.c
> +++ b/drivers/input/mouse/pc110pad.c
> @@ -91,7 +91,7 @@ static int __init pc110pad_init(void)
> {
> int err;
>
> - if (!no_pci_devices())
> + if (pci_find_next_bus(NULL))
> return -ENODEV;
I'd certainly love to get rid of no_pci_devices(), although using
pci_find_next_bus() is not really much better.
I don't have much opinion about pc110pad.c change. It's essentially
still the same kludge, which has been there at least since the
beginning of git history.
Dmitry, if you want to ack this, I can take both together.
Bjorn
^ permalink raw reply
* Re: [PATCH] Input: gpio-keys - add hibernation support
From: Dmitry Torokhov @ 2026-04-06 18:18 UTC (permalink / raw)
To: Armando De Leon; +Cc: Armando De Leon, linux-input, linux-kernel
In-Reply-To: <20260406165833.3137128-1-learmand@amazon.com>
On Mon, Apr 06, 2026 at 09:58:06AM -0700, Armando De Leon wrote:
> Hi Dmitry,
>
> Thank you for the review.
>
> The interrupt controller (GICv3) is re-initialized by platform
> firmware during hibernate restore - this is expected behavior, not
> a bug. The IRQ trigger type (EDGE_BOTH) was originally configured
> by devm_request_any_context_irq() during probe(), which does not
> run again after hibernate restore.
>
> The TLMM/pinctrl registers are correctly saved and restored by the
> platform's syscore_ops - I verified this with register dumps. The
> issue is specifically that the IRQ trigger type configured at the
> GIC level during probe is lost and not re-applied.
>
> Should the generic IRQ core be responsible for restoring trigger
> types across hibernate? Otherwise, consumer drivers like gpio-keys need to handle
> this in their .restore callback.
I am not sure if it is job of IRQ core vs. particular interrupt
controller, but they should restore the trigger types along with
entirety of the interrupts and pins states to exactly the same condition
that they were before entering hibernation.
>
> Either way, gpio-keys currently lacks .freeze/.restore callbacks
> entirely, which is needed for proper hibernation support.
Drivers only need dedicated freeze and restore handlers if the behavior
should be different between suspend-to-ram vs suspend-to-disk. For the
vast majority of the drivers they behave exactly the same and I do not
see why it would be different for gpio-keys.
Thanks.
--
Dmitry
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox