Skip to content

Commit 1639f98

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.5/core' into for-linus
- more bullet-proof handling of devres-managed resources in HID core (Dmitry Torokhov) - kunit test Kconfig dependency fix (Geert Uytterhoeven)
2 parents e80b500 + 49904a0 commit 1639f98

File tree

3 files changed

+73
-48
lines changed

3 files changed

+73
-48
lines changed

drivers/hid/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,7 @@ config HID_MCP2221
12851285

12861286
config HID_KUNIT_TEST
12871287
tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS
1288-
depends on KUNIT=y
1288+
depends on KUNIT
12891289
depends on HID_BATTERY_STRENGTH
12901290
depends on HID_UCLOGIC
12911291
default KUNIT_ALL_TESTS

drivers/hid/hid-core.c

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,64 +2587,84 @@ bool hid_compare_device_paths(struct hid_device *hdev_a,
25872587
}
25882588
EXPORT_SYMBOL_GPL(hid_compare_device_paths);
25892589

2590+
static bool hid_check_device_match(struct hid_device *hdev,
2591+
struct hid_driver *hdrv,
2592+
const struct hid_device_id **id)
2593+
{
2594+
*id = hid_match_device(hdev, hdrv);
2595+
if (!*id)
2596+
return false;
2597+
2598+
if (hdrv->match)
2599+
return hdrv->match(hdev, hid_ignore_special_drivers);
2600+
2601+
/*
2602+
* hid-generic implements .match(), so we must be dealing with a
2603+
* different HID driver here, and can simply check if
2604+
* hid_ignore_special_drivers is set or not.
2605+
*/
2606+
return !hid_ignore_special_drivers;
2607+
}
2608+
2609+
static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
2610+
{
2611+
const struct hid_device_id *id;
2612+
int ret;
2613+
2614+
if (!hid_check_device_match(hdev, hdrv, &id))
2615+
return -ENODEV;
2616+
2617+
hdev->devres_group_id = devres_open_group(&hdev->dev, NULL, GFP_KERNEL);
2618+
if (!hdev->devres_group_id)
2619+
return -ENOMEM;
2620+
2621+
/* reset the quirks that has been previously set */
2622+
hdev->quirks = hid_lookup_quirk(hdev);
2623+
hdev->driver = hdrv;
2624+
2625+
if (hdrv->probe) {
2626+
ret = hdrv->probe(hdev, id);
2627+
} else { /* default probe */
2628+
ret = hid_open_report(hdev);
2629+
if (!ret)
2630+
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
2631+
}
2632+
2633+
/*
2634+
* Note that we are not closing the devres group opened above so
2635+
* even resources that were attached to the device after probe is
2636+
* run are released when hid_device_remove() is executed. This is
2637+
* needed as some drivers would allocate additional resources,
2638+
* for example when updating firmware.
2639+
*/
2640+
2641+
if (ret) {
2642+
devres_release_group(&hdev->dev, hdev->devres_group_id);
2643+
hid_close_report(hdev);
2644+
hdev->driver = NULL;
2645+
}
2646+
2647+
return ret;
2648+
}
2649+
25902650
static int hid_device_probe(struct device *dev)
25912651
{
2592-
struct hid_driver *hdrv = to_hid_driver(dev->driver);
25932652
struct hid_device *hdev = to_hid_device(dev);
2594-
const struct hid_device_id *id;
2653+
struct hid_driver *hdrv = to_hid_driver(dev->driver);
25952654
int ret = 0;
25962655

2597-
if (down_interruptible(&hdev->driver_input_lock)) {
2598-
ret = -EINTR;
2599-
goto end;
2600-
}
2601-
hdev->io_started = false;
2656+
if (down_interruptible(&hdev->driver_input_lock))
2657+
return -EINTR;
26022658

2659+
hdev->io_started = false;
26032660
clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
26042661

2605-
if (!hdev->driver) {
2606-
id = hid_match_device(hdev, hdrv);
2607-
if (id == NULL) {
2608-
ret = -ENODEV;
2609-
goto unlock;
2610-
}
2611-
2612-
if (hdrv->match) {
2613-
if (!hdrv->match(hdev, hid_ignore_special_drivers)) {
2614-
ret = -ENODEV;
2615-
goto unlock;
2616-
}
2617-
} else {
2618-
/*
2619-
* hid-generic implements .match(), so if
2620-
* hid_ignore_special_drivers is set, we can safely
2621-
* return.
2622-
*/
2623-
if (hid_ignore_special_drivers) {
2624-
ret = -ENODEV;
2625-
goto unlock;
2626-
}
2627-
}
2662+
if (!hdev->driver)
2663+
ret = __hid_device_probe(hdev, hdrv);
26282664

2629-
/* reset the quirks that has been previously set */
2630-
hdev->quirks = hid_lookup_quirk(hdev);
2631-
hdev->driver = hdrv;
2632-
if (hdrv->probe) {
2633-
ret = hdrv->probe(hdev, id);
2634-
} else { /* default probe */
2635-
ret = hid_open_report(hdev);
2636-
if (!ret)
2637-
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
2638-
}
2639-
if (ret) {
2640-
hid_close_report(hdev);
2641-
hdev->driver = NULL;
2642-
}
2643-
}
2644-
unlock:
26452665
if (!hdev->io_started)
26462666
up(&hdev->driver_input_lock);
2647-
end:
2667+
26482668
return ret;
26492669
}
26502670

@@ -2662,6 +2682,10 @@ static void hid_device_remove(struct device *dev)
26622682
hdrv->remove(hdev);
26632683
else /* default remove */
26642684
hid_hw_stop(hdev);
2685+
2686+
/* Release all devres resources allocated by the driver */
2687+
devres_release_group(&hdev->dev, hdev->devres_group_id);
2688+
26652689
hid_close_report(hdev);
26662690
hdev->driver = NULL;
26672691
}

include/linux/hid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ struct hid_device { /* device report descriptor */
597597
struct semaphore driver_input_lock; /* protects the current driver */
598598
struct device dev; /* device */
599599
struct hid_driver *driver;
600+
void *devres_group_id; /* ID of probe devres group */
600601

601602
const struct hid_ll_driver *ll_driver;
602603
struct mutex ll_open_lock;

0 commit comments

Comments
 (0)