[PATCH 21/21] HID: haptic: move FF initialization into .input_configured()
Dmitry Torokhov <[email protected]> Mon, 03 Aug 2026 11:46:46 -0700
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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