Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f732850 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina
Browse files

HID: core: allow concurrent registration of drivers



Detected on the Dell XPS 9365.

The laptop has 2 devices that benefit from the hid-generic auto-unbinding.
When those 2 devices are presented to the userspace, udev loads both wacom and
hid-multitouch. When this happens, the code in __hid_bus_reprobe_drivers() is
called concurrently and the second device gets reprobed twice.

An other bug in the power_supply subsystem prevent to remove the wacom driver
if it just finished its initialization, which basically kills the wacom node.

[jkosina@suse.cz: reformat changelog a bit]
Fixes c17a7476 ("HID: core: rewrite the hid-generic automatic unbind")
Cc: stable@vger.kernel.org # v4.17
Tested-by: default avatarMario Limonciello <mario.limonciello@dell.com>
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent d471b6b2
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1949,6 +1949,8 @@ static int hid_device_probe(struct device *dev)
	}
	hdev->io_started = false;

	clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);

	if (!hdev->driver) {
		id = hid_match_device(hdev, hdrv);
		if (id == NULL) {
@@ -2212,7 +2214,8 @@ static int __hid_bus_reprobe_drivers(struct device *dev, void *data)
	struct hid_device *hdev = to_hid_device(dev);

	if (hdev->driver == hdrv &&
	    !hdrv->match(hdev, hid_ignore_special_drivers))
	    !hdrv->match(hdev, hid_ignore_special_drivers) &&
	    !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
		return device_reprobe(dev);

	return 0;
+2 −1
Original line number Diff line number Diff line
@@ -511,6 +511,7 @@ struct hid_output_fifo {
#define HID_STAT_ADDED		BIT(0)
#define HID_STAT_PARSED		BIT(1)
#define HID_STAT_DUP_DETECTED	BIT(2)
#define HID_STAT_REPROBED	BIT(3)

struct hid_input {
	struct list_head list;
@@ -579,7 +580,7 @@ struct hid_device { /* device report descriptor */
	bool battery_avoid_query;
#endif

	unsigned int status;						/* see STAT flags above */
	unsigned long status;						/* see STAT flags above */
	unsigned claimed;						/* Claimed by hidinput, hiddev? */
	unsigned quirks;						/* Various quirks the device can pull on us */
	bool io_started;						/* If IO has started */