[PATCH 21/21] HID: haptic: move FF initialization into .input_configured()

Dmitry Torokhov <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kernel.vger.linux-doc,org.kernel.vger.linux-input
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.