From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
To: jikos@kernel.org, bentiss@kernel.org
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Subject: [PATCH v10 1/2] HID: haptic: make FF creation the last fallible init step
Date: Sat, 17 Oct 2026 11:38:09 -0300 [thread overview]
Message-ID: <20261017143810.1567677-2-qwe.aldo@gmail.com> (raw)
In-Reply-To: <20261017143810.1567677-1-qwe.aldo@gmail.com>
The caller holds the module while setting up the device. Use
__module_get() after input_ff_create() succeeds, leaving no fallible
step after the FF callbacks are installed.
Drain haptic work through ff->stop when the input device is
unregistered, before it drops its parent reference. The destroy
callback also drains work for devices that were never registered.
After unregistration, that callback only frees local allocations, so
remove the extra HID device reference and its error path.
Clear the FF capability bits if input_ff_create() fails. Return the
error from hid_haptic_input_configured() and save it in the multitouch
driver. Probe must fail even if hidraw lets hid_connect() succeed after
hidinput_connect() has unwound.
Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
drivers/hid/hid-haptic.c | 48 ++++++++++++++----------------------
drivers/hid/hid-multitouch.c | 18 ++++++++++++--
2 files changed, 35 insertions(+), 31 deletions(-)
diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 8760eeb..0a6126e 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -96,7 +96,7 @@ int hid_haptic_input_configured(struct hid_device *hdev,
if (error) {
dev_warn(&hdev->dev, "Cannot allocate haptic for %s\n",
hdev->name);
- return 0;
+ return error;
}
return 1;
@@ -377,14 +377,22 @@ static int hid_haptic_erase(struct input_dev *dev, int effect_id)
return 0;
}
+static void hid_haptic_stop(struct ff_device *ff)
+{
+ struct hid_haptic_device *haptic = ff->private;
+
+ if (haptic->wq) {
+ destroy_workqueue(haptic->wq);
+ haptic->wq = NULL;
+ }
+}
+
static void hid_haptic_destroy(struct ff_device *ff)
{
struct hid_haptic_device *haptic = ff->private;
- struct hid_device *hdev = haptic->hdev;
int r;
- if (hdev)
- put_device(&hdev->dev);
+ hid_haptic_stop(ff);
kfree(haptic->stop_effect.report_buf);
haptic->stop_effect.report_buf = NULL;
@@ -396,9 +404,6 @@ static void hid_haptic_destroy(struct ff_device *ff)
}
haptic->effect = NULL;
- destroy_workqueue(haptic->wq);
- haptic->wq = NULL;
-
kfree(haptic->duration_map);
haptic->duration_map = NULL;
@@ -419,8 +424,6 @@ int hid_haptic_init(struct hid_device *hdev,
};
const char *prefix = "hid-haptic";
char *name;
- int (*flush)(struct input_dev *dev, struct file *file);
- int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
haptic->hdev = hdev;
haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
@@ -501,38 +504,25 @@ int hid_haptic_init(struct hid_device *hdev,
input_set_capability(dev, EV_FF, FF_HAPTIC);
- flush = dev->flush;
- event = dev->event;
ret = input_ff_create(dev, FF_MAX_EFFECTS);
if (ret) {
dev_err(&hdev->dev, "Failed to create ff device.\n");
- goto stop_buffer_free;
+ goto ff_cap_clear;
}
ff = dev->ff;
- ff->private = haptic;
ff->upload = hid_haptic_upload_effect;
ff->playback = hid_haptic_playback;
ff->erase = hid_haptic_erase;
+ ff->stop = hid_haptic_stop;
ff->destroy = hid_haptic_destroy;
- if (!try_module_get(THIS_MODULE)) {
- dev_err(&hdev->dev, "Failed to increase module count.\n");
- goto input_free;
- }
- if (!get_device(&hdev->dev)) {
- dev_err(&hdev->dev, "Failed to get hdev device.\n");
- module_put(THIS_MODULE);
- goto input_free;
- }
+ __module_get(THIS_MODULE);
+ ff->private = haptic;
return 0;
-input_free:
- input_ff_destroy(dev);
- /* Restore dev flush and event */
- dev->flush = flush;
- dev->event = event;
- return ret;
-stop_buffer_free:
+ff_cap_clear:
+ __clear_bit(FF_HAPTIC, dev->ffbit);
+ __clear_bit(EV_FF, dev->evbit);
kfree(haptic->stop_effect.report_buf);
haptic->stop_effect.report_buf = NULL;
buffer_free:
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 4e19a0c..154dc94 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -174,6 +174,7 @@ struct mt_device {
struct mt_class mtclass; /* our mt device class */
struct timer_list release_timer; /* to release sticky fingers */
struct hid_haptic_device *haptic; /* haptic related configuration */
+ int haptic_init_error;
struct hid_device *hdev; /* hid_device we're attached to */
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING) */
unsigned long *active_slots; /* bitmap of slots with an active
@@ -1958,8 +1959,16 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
if (td->is_haptic_touchpad && (td->mtclass.name == MT_CLS_WIN_8 ||
td->mtclass.name == MT_CLS_WIN_8_FORCE_MULTI_INPUT ||
td->mtclass.name == MT_CLS_WIN_8_KEEP_LATENCY_ON_CLOSE)) {
- if (hid_haptic_input_configured(hdev, td->haptic, hi) == 0)
- td->is_haptic_touchpad = false;
+ if (hi->application == HID_DG_TOUCHPAD) {
+ ret = hid_haptic_input_configured(hdev, td->haptic, hi);
+ if (ret < 0) {
+ td->haptic_init_error = ret;
+ td->is_haptic_touchpad = false;
+ return ret;
+ }
+ if (ret == 0)
+ td->is_haptic_touchpad = false;
+ }
} else {
td->is_haptic_touchpad = false;
}
@@ -2197,6 +2206,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret)
return ret;
+ if (td->haptic_init_error) {
+ ret = td->haptic_init_error;
+ hid_hw_stop(hdev);
+ return ret;
+ }
ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
if (ret)
--
2.53.0
next prev parent reply other threads:[~2026-10-17 14:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 14:38 [PATCH v10 0/2] HID: multitouch: fix haptic lifetime on delayed input release Aldo Ariel Panzardo
2026-10-17 14:38 ` Aldo Ariel Panzardo [this message]
2026-10-17 14:38 ` [PATCH v10 2/2] HID: multitouch: give FF core ownership of haptic state Aldo Ariel Panzardo
2026-10-17 14:52 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261017143810.1567677-2-qwe.aldo@gmail.com \
--to=qwe.aldo@gmail.com \
--cc=bentiss@kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox