Loading drivers/hid/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -1285,7 +1285,7 @@ config HID_MCP2221 config HID_KUNIT_TEST tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS depends on KUNIT=y depends on KUNIT depends on HID_BATTERY_STRENGTH depends on HID_UCLOGIC default KUNIT_ALL_TESTS Loading drivers/hid/hid-core.c +71 −47 Original line number Diff line number Diff line Loading @@ -2587,48 +2587,41 @@ bool hid_compare_device_paths(struct hid_device *hdev_a, } EXPORT_SYMBOL_GPL(hid_compare_device_paths); static int hid_device_probe(struct device *dev) static bool hid_check_device_match(struct hid_device *hdev, struct hid_driver *hdrv, const struct hid_device_id **id) { struct hid_driver *hdrv = to_hid_driver(dev->driver); struct hid_device *hdev = to_hid_device(dev); const struct hid_device_id *id; int ret = 0; if (down_interruptible(&hdev->driver_input_lock)) { ret = -EINTR; goto end; } hdev->io_started = false; clear_bit(ffs(HID_STAT_REPROBED), &hdev->status); *id = hid_match_device(hdev, hdrv); if (!*id) return false; if (!hdev->driver) { id = hid_match_device(hdev, hdrv); if (id == NULL) { ret = -ENODEV; goto unlock; } if (hdrv->match) return hdrv->match(hdev, hid_ignore_special_drivers); if (hdrv->match) { if (!hdrv->match(hdev, hid_ignore_special_drivers)) { ret = -ENODEV; goto unlock; } } else { /* * hid-generic implements .match(), so if * hid_ignore_special_drivers is set, we can safely * return. * hid-generic implements .match(), so we must be dealing with a * different HID driver here, and can simply check if * hid_ignore_special_drivers is set or not. */ if (hid_ignore_special_drivers) { ret = -ENODEV; goto unlock; } return !hid_ignore_special_drivers; } static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) { const struct hid_device_id *id; int ret; if (!hid_check_device_match(hdev, hdrv, &id)) return -ENODEV; hdev->devres_group_id = devres_open_group(&hdev->dev, NULL, GFP_KERNEL); if (!hdev->devres_group_id) return -ENOMEM; /* reset the quirks that has been previously set */ hdev->quirks = hid_lookup_quirk(hdev); hdev->driver = hdrv; if (hdrv->probe) { ret = hdrv->probe(hdev, id); } else { /* default probe */ Loading @@ -2636,15 +2629,42 @@ static int hid_device_probe(struct device *dev) if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); } /* * Note that we are not closing the devres group opened above so * even resources that were attached to the device after probe is * run are released when hid_device_remove() is executed. This is * needed as some drivers would allocate additional resources, * for example when updating firmware. */ if (ret) { devres_release_group(&hdev->dev, hdev->devres_group_id); hid_close_report(hdev); hdev->driver = NULL; } return ret; } unlock: static int hid_device_probe(struct device *dev) { struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv = to_hid_driver(dev->driver); int ret = 0; if (down_interruptible(&hdev->driver_input_lock)) return -EINTR; hdev->io_started = false; clear_bit(ffs(HID_STAT_REPROBED), &hdev->status); if (!hdev->driver) ret = __hid_device_probe(hdev, hdrv); if (!hdev->io_started) up(&hdev->driver_input_lock); end: return ret; } Loading @@ -2662,6 +2682,10 @@ static void hid_device_remove(struct device *dev) hdrv->remove(hdev); else /* default remove */ hid_hw_stop(hdev); /* Release all devres resources allocated by the driver */ devres_release_group(&hdev->dev, hdev->devres_group_id); hid_close_report(hdev); hdev->driver = NULL; } Loading include/linux/hid.h +1 −0 Original line number Diff line number Diff line Loading @@ -597,6 +597,7 @@ struct hid_device { /* device report descriptor */ struct semaphore driver_input_lock; /* protects the current driver */ struct device dev; /* device */ struct hid_driver *driver; void *devres_group_id; /* ID of probe devres group */ const struct hid_ll_driver *ll_driver; struct mutex ll_open_lock; Loading Loading
drivers/hid/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -1285,7 +1285,7 @@ config HID_MCP2221 config HID_KUNIT_TEST tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS depends on KUNIT=y depends on KUNIT depends on HID_BATTERY_STRENGTH depends on HID_UCLOGIC default KUNIT_ALL_TESTS Loading
drivers/hid/hid-core.c +71 −47 Original line number Diff line number Diff line Loading @@ -2587,48 +2587,41 @@ bool hid_compare_device_paths(struct hid_device *hdev_a, } EXPORT_SYMBOL_GPL(hid_compare_device_paths); static int hid_device_probe(struct device *dev) static bool hid_check_device_match(struct hid_device *hdev, struct hid_driver *hdrv, const struct hid_device_id **id) { struct hid_driver *hdrv = to_hid_driver(dev->driver); struct hid_device *hdev = to_hid_device(dev); const struct hid_device_id *id; int ret = 0; if (down_interruptible(&hdev->driver_input_lock)) { ret = -EINTR; goto end; } hdev->io_started = false; clear_bit(ffs(HID_STAT_REPROBED), &hdev->status); *id = hid_match_device(hdev, hdrv); if (!*id) return false; if (!hdev->driver) { id = hid_match_device(hdev, hdrv); if (id == NULL) { ret = -ENODEV; goto unlock; } if (hdrv->match) return hdrv->match(hdev, hid_ignore_special_drivers); if (hdrv->match) { if (!hdrv->match(hdev, hid_ignore_special_drivers)) { ret = -ENODEV; goto unlock; } } else { /* * hid-generic implements .match(), so if * hid_ignore_special_drivers is set, we can safely * return. * hid-generic implements .match(), so we must be dealing with a * different HID driver here, and can simply check if * hid_ignore_special_drivers is set or not. */ if (hid_ignore_special_drivers) { ret = -ENODEV; goto unlock; } return !hid_ignore_special_drivers; } static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) { const struct hid_device_id *id; int ret; if (!hid_check_device_match(hdev, hdrv, &id)) return -ENODEV; hdev->devres_group_id = devres_open_group(&hdev->dev, NULL, GFP_KERNEL); if (!hdev->devres_group_id) return -ENOMEM; /* reset the quirks that has been previously set */ hdev->quirks = hid_lookup_quirk(hdev); hdev->driver = hdrv; if (hdrv->probe) { ret = hdrv->probe(hdev, id); } else { /* default probe */ Loading @@ -2636,15 +2629,42 @@ static int hid_device_probe(struct device *dev) if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); } /* * Note that we are not closing the devres group opened above so * even resources that were attached to the device after probe is * run are released when hid_device_remove() is executed. This is * needed as some drivers would allocate additional resources, * for example when updating firmware. */ if (ret) { devres_release_group(&hdev->dev, hdev->devres_group_id); hid_close_report(hdev); hdev->driver = NULL; } return ret; } unlock: static int hid_device_probe(struct device *dev) { struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv = to_hid_driver(dev->driver); int ret = 0; if (down_interruptible(&hdev->driver_input_lock)) return -EINTR; hdev->io_started = false; clear_bit(ffs(HID_STAT_REPROBED), &hdev->status); if (!hdev->driver) ret = __hid_device_probe(hdev, hdrv); if (!hdev->io_started) up(&hdev->driver_input_lock); end: return ret; } Loading @@ -2662,6 +2682,10 @@ static void hid_device_remove(struct device *dev) hdrv->remove(hdev); else /* default remove */ hid_hw_stop(hdev); /* Release all devres resources allocated by the driver */ devres_release_group(&hdev->dev, hdev->devres_group_id); hid_close_report(hdev); hdev->driver = NULL; } Loading
include/linux/hid.h +1 −0 Original line number Diff line number Diff line Loading @@ -597,6 +597,7 @@ struct hid_device { /* device report descriptor */ struct semaphore driver_input_lock; /* protects the current driver */ struct device dev; /* device */ struct hid_driver *driver; void *devres_group_id; /* ID of probe devres group */ const struct hid_ll_driver *ll_driver; struct mutex ll_open_lock; Loading