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 c17a7476e4
("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>
This commit is contained in:
parent
d471b6b22d
commit
8f732850df
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue