[PATCH 21/21] HID: haptic: move FF initialization into .input_configured()
From: Dmitry Torokhov
Date: Mon Aug 03 2026 - 15:05:10 EST
Refactor hid_haptic_init() to take a direct pointer to input_dev and
integrate its invocation into hid_haptic_input_configured().
Update hid-multitouch to rely on the refactored callback to perform the
force-feedback initialization during the registration loop. This ensures
that force-feedback capabilities are set up before the input device is
registered and exposed to userspace, closing the registration race.
Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
drivers/hid/hid-haptic.c | 45 +++++++++++++++++---------------------------
drivers/hid/hid-haptic.h | 6 ++++--
drivers/hid/hid-multitouch.c | 10 +---------
3 files changed, 22 insertions(+), 39 deletions(-)
diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index deadab28cdbe..5d365a9767dd 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -82,16 +82,24 @@ int hid_haptic_input_configured(struct hid_device *hdev,
struct hid_haptic_device *haptic,
struct hid_input *hi)
{
+ int error;
- if (hi->application == HID_DG_TOUCHPAD) {
- if (haptic->auto_trigger_report &&
- haptic->manual_trigger_report) {
- __set_bit(INPUT_PROP_PRESSUREPAD, hi->input->propbit);
- return 1;
- }
+ if (hi->application != HID_DG_TOUCHPAD)
+ return -1;
+
+ if (!haptic->auto_trigger_report || !haptic->manual_trigger_report)
+ return 0;
+
+ __set_bit(INPUT_PROP_PRESSUREPAD, hi->input->propbit);
+
+ error = hid_haptic_init(hdev, haptic, hi->input);
+ if (error) {
+ dev_warn(&hdev->dev, "Cannot allocate haptic for %s\n",
+ hdev->name);
return 0;
}
- return -1;
+
+ return 1;
}
EXPORT_SYMBOL_GPL(hid_haptic_input_configured);
@@ -401,11 +409,9 @@ static void hid_haptic_destroy(struct ff_device *ff)
}
int hid_haptic_init(struct hid_device *hdev,
- struct hid_haptic_device **haptic_ptr)
+ struct hid_haptic_device *haptic,
+ struct input_dev *dev)
{
- struct hid_haptic_device *haptic = *haptic_ptr;
- struct input_dev *dev = NULL;
- struct hid_input *hidinput;
struct ff_device *ff;
int ret = 0, r;
struct ff_haptic_effect stop_effect = {
@@ -447,19 +453,6 @@ int hid_haptic_init(struct hid_device *hdev,
for (r = 0; r < haptic->auto_trigger_report->maxfield; r++)
parse_auto_trigger_field(haptic, haptic->auto_trigger_report->field[r]);
- list_for_each_entry(hidinput, &hdev->inputs, list) {
- if (hidinput->application == HID_DG_TOUCHPAD) {
- dev = hidinput->input;
- break;
- }
- }
-
- if (!dev) {
- dev_err(&hdev->dev, "Failed to find the input device\n");
- ret = -ENODEV;
- goto duration_map;
- }
-
haptic->input_dev = dev;
haptic->manual_trigger_report_len =
hid_report_len(haptic->manual_trigger_report);
@@ -535,10 +528,6 @@ int hid_haptic_init(struct hid_device *hdev,
input_free:
input_ff_destroy(dev);
- /* Do not let double free happen, input_ff_destroy will call
- * hid_haptic_destroy.
- */
- *haptic_ptr = NULL;
/* Restore dev flush and event */
dev->flush = flush;
dev->event = event;
diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h
index c6539ac04c1d..6332991a7844 100644
--- a/drivers/hid/hid-haptic.h
+++ b/drivers/hid/hid-haptic.h
@@ -69,7 +69,8 @@ int hid_haptic_input_mapping(struct hid_device *hdev,
int hid_haptic_input_configured(struct hid_device *hdev,
struct hid_haptic_device *haptic,
struct hid_input *hi);
-int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr);
+int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device *haptic,
+ struct input_dev *dev);
void hid_haptic_handle_press_release(struct hid_haptic_device *haptic);
void hid_haptic_pressure_reset(struct hid_haptic_device *haptic);
void hid_haptic_pressure_increase(struct hid_haptic_device *haptic,
@@ -107,7 +108,8 @@ static inline
void hid_haptic_reset(struct hid_device *hdev, struct hid_haptic_device *haptic)
{}
static inline
-int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr)
+int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device *haptic,
+ struct input_dev *dev)
{
return 0;
}
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index edb37b4c867e..15218e92aaa4 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -2189,16 +2189,8 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
mt_set_modes(hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_ALL);
- if (td->is_haptic_touchpad) {
- if (hid_haptic_init(hdev, &td->haptic)) {
- dev_warn(&hdev->dev, "Cannot allocate haptic for %s\n",
- hdev->name);
- td->is_haptic_touchpad = false;
- devm_kfree(&hdev->dev, td->haptic);
- }
- } else {
+ if (!td->is_haptic_touchpad)
devm_kfree(&hdev->dev, td->haptic);
- }
return 0;
}
--
2.55.0.629.g250fe7f194-goog