diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2018-05-31 13:49:29 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-06-25 15:29:16 +0200 |
commit | 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 (patch) | |
tree | 6404276bcb01659e9933242c89a9ba7672edcb66 /drivers/hid/hid-core.c | |
parent | d471b6b22d37bf9928c6d0202bdaaf76583b8b61 (diff) | |
download | blackbird-obmc-linux-8f732850df1b2b4d8d719f7e606dfb3050e7ea11.tar.gz blackbird-obmc-linux-8f732850df1b2b4d8d719f7e606dfb3050e7ea11.zip |
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 c17a7476e4c4 ("HID: core: rewrite the hid-generic automatic unbind")
Cc: stable@vger.kernel.org # v4.17
Tested-by: Mario Limonciello <mario.limonciello@dell.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r-- | drivers/hid/hid-core.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 355dc7e49562..a460ec147aee 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -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; |