[PATCH 1/2] HID: quirks: add quirk to always keep device open

From: leo vriska

Date: Tue Mar 03 2026 - 22:33:45 EST


Some devices expect the host to open the device shortly after it is
connected. If this does not occur, they may freeze or disconnect. A
quirk allows these devices to function properly without userspace hacks.

The existing hid-axff driver solves this problem for some generic
controllers. This implementation is modelled after that driver, which
still needs to exist for force feedback on the controllers that use it.

Signed-off-by: leo vriska <leo@xxxxxxxxx>
---
drivers/hid/hid-generic.c | 23 ++++++++++++++++++++++-
include/linux/hid.h | 2 ++
2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c
index c2de916747de..0595e653b7e7 100644
--- a/drivers/hid/hid-generic.c
+++ b/drivers/hid/hid-generic.c
@@ -67,7 +67,27 @@ static int hid_generic_probe(struct hid_device *hdev,
if (ret)
return ret;

- return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret)
+ return ret;
+
+ if (hdev->quirks & HID_QUIRK_KEEP_OPEN) {
+ ret = hid_hw_open(hdev);
+ if (ret) {
+ hid_hw_stop(hdev);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void hid_generic_remove(struct hid_device *hdev)
+{
+ if (hdev->quirks & HID_QUIRK_KEEP_OPEN)
+ hid_hw_close(hdev);
+
+ hid_hw_stop(hdev);
}

static int hid_generic_reset_resume(struct hid_device *hdev)
@@ -89,6 +109,7 @@ static struct hid_driver hid_generic = {
.id_table = hid_table,
.match = hid_generic_match,
.probe = hid_generic_probe,
+ .remove = hid_generic_remove,
.reset_resume = hid_generic_reset_resume,
};
module_hid_driver(hid_generic);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 2990b9f94cb5..9d0ab7c217f3 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -388,6 +388,7 @@ struct hid_item {
* | @HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE:
* | @HID_QUIRK_IGNORE_SPECIAL_DRIVER
* | @HID_QUIRK_POWER_ON_AFTER_BACKLIGHT
+ * | @HID_QUIRK_KEEP_OPEN:
* | @HID_QUIRK_FULLSPEED_INTERVAL:
* | @HID_QUIRK_NO_INIT_REPORTS:
* | @HID_QUIRK_NO_IGNORE:
@@ -416,6 +417,7 @@ struct hid_item {
#define HID_QUIRK_NOINVERT BIT(21)
#define HID_QUIRK_IGNORE_SPECIAL_DRIVER BIT(22)
#define HID_QUIRK_POWER_ON_AFTER_BACKLIGHT BIT(23)
+#define HID_QUIRK_KEEP_OPEN BIT(24)
#define HID_QUIRK_FULLSPEED_INTERVAL BIT(28)
#define HID_QUIRK_NO_INIT_REPORTS BIT(29)
#define HID_QUIRK_NO_IGNORE BIT(30)
--
2.53.0