HID: haptic: move FF initialization into .input_configured()

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@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
Dmitry Torokhov
2026-08-03 11:46:46 -07:00
committed by Jiri Kosina
parent 544315e401
commit 7939f787f4
3 changed files with 22 additions and 39 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -2181,16 +2181,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;
}