diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2017-12-08 09:29:44 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-03-06 10:00:51 -0500 |
commit | c17a7476e4c41884d82e3675c25ceae982c07a63 (patch) | |
tree | 577796c9bda4e5663207717afdfd79b054764b9c | |
parent | 001fab49dd4fcf64b1b8ccecb8656baa3f3f1a9a (diff) |
HID: core: rewrite the hid-generic automatic unbind
We actually can have the unbind/rebind logic in hid-core.c, leaving
only the match function in hid-generic.
This makes hid-generic simpler and the whole logic simpler too.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-core.c | 35 | ||||
-rw-r--r-- | drivers/hid/hid-generic.c | 33 | ||||
-rw-r--r-- | include/linux/hid.h | 4 |
3 files changed, 24 insertions, 48 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c2560aae5542..c058bb911ca1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -2197,31 +2197,40 @@ void hid_destroy_device(struct hid_device *hdev) | |||
2197 | EXPORT_SYMBOL_GPL(hid_destroy_device); | 2197 | EXPORT_SYMBOL_GPL(hid_destroy_device); |
2198 | 2198 | ||
2199 | 2199 | ||
2200 | static int __bus_add_driver(struct device_driver *drv, void *data) | 2200 | static int __hid_bus_reprobe_drivers(struct device *dev, void *data) |
2201 | { | 2201 | { |
2202 | struct hid_driver *added_hdrv = data; | 2202 | struct hid_driver *hdrv = data; |
2203 | struct hid_driver *hdrv = to_hid_driver(drv); | 2203 | struct hid_device *hdev = to_hid_device(dev); |
2204 | 2204 | ||
2205 | if (hdrv->bus_add_driver) | 2205 | if (hdev->driver == hdrv && |
2206 | hdrv->bus_add_driver(added_hdrv); | 2206 | !hdrv->match(hdev, hid_ignore_special_drivers)) |
2207 | return device_reprobe(dev); | ||
2207 | 2208 | ||
2208 | return 0; | 2209 | return 0; |
2209 | } | 2210 | } |
2210 | 2211 | ||
2211 | static int __bus_removed_driver(struct device_driver *drv, void *data) | 2212 | static int __hid_bus_driver_added(struct device_driver *drv, void *data) |
2212 | { | 2213 | { |
2213 | struct hid_driver *removed_hdrv = data; | ||
2214 | struct hid_driver *hdrv = to_hid_driver(drv); | 2214 | struct hid_driver *hdrv = to_hid_driver(drv); |
2215 | 2215 | ||
2216 | if (hdrv->bus_removed_driver) | 2216 | if (hdrv->match) { |
2217 | hdrv->bus_removed_driver(removed_hdrv); | 2217 | bus_for_each_dev(&hid_bus_type, NULL, hdrv, |
2218 | __hid_bus_reprobe_drivers); | ||
2219 | } | ||
2218 | 2220 | ||
2219 | return 0; | 2221 | return 0; |
2220 | } | 2222 | } |
2221 | 2223 | ||
2224 | static int __bus_removed_driver(struct device_driver *drv, void *data) | ||
2225 | { | ||
2226 | return bus_rescan_devices(&hid_bus_type); | ||
2227 | } | ||
2228 | |||
2222 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, | 2229 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, |
2223 | const char *mod_name) | 2230 | const char *mod_name) |
2224 | { | 2231 | { |
2232 | int ret; | ||
2233 | |||
2225 | hdrv->driver.name = hdrv->name; | 2234 | hdrv->driver.name = hdrv->name; |
2226 | hdrv->driver.bus = &hid_bus_type; | 2235 | hdrv->driver.bus = &hid_bus_type; |
2227 | hdrv->driver.owner = owner; | 2236 | hdrv->driver.owner = owner; |
@@ -2230,9 +2239,13 @@ int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, | |||
2230 | INIT_LIST_HEAD(&hdrv->dyn_list); | 2239 | INIT_LIST_HEAD(&hdrv->dyn_list); |
2231 | spin_lock_init(&hdrv->dyn_lock); | 2240 | spin_lock_init(&hdrv->dyn_lock); |
2232 | 2241 | ||
2233 | bus_for_each_drv(&hid_bus_type, NULL, hdrv, __bus_add_driver); | 2242 | ret = driver_register(&hdrv->driver); |
2243 | |||
2244 | if (ret == 0) | ||
2245 | bus_for_each_drv(&hid_bus_type, NULL, NULL, | ||
2246 | __hid_bus_driver_added); | ||
2234 | 2247 | ||
2235 | return driver_register(&hdrv->driver); | 2248 | return ret; |
2236 | } | 2249 | } |
2237 | EXPORT_SYMBOL_GPL(__hid_register_driver); | 2250 | EXPORT_SYMBOL_GPL(__hid_register_driver); |
2238 | 2251 | ||
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index 3c0a1bf433d7..c25b4718de44 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c | |||
@@ -26,37 +26,6 @@ | |||
26 | 26 | ||
27 | static struct hid_driver hid_generic; | 27 | static struct hid_driver hid_generic; |
28 | 28 | ||
29 | static int __unmap_hid_generic(struct device *dev, void *data) | ||
30 | { | ||
31 | struct hid_driver *hdrv = data; | ||
32 | struct hid_device *hdev = to_hid_device(dev); | ||
33 | |||
34 | /* only unbind matching devices already bound to hid-generic */ | ||
35 | if (hdev->driver != &hid_generic || | ||
36 | hid_match_device(hdev, hdrv) == NULL) | ||
37 | return 0; | ||
38 | |||
39 | if (dev->parent) /* Needed for USB */ | ||
40 | device_lock(dev->parent); | ||
41 | device_release_driver(dev); | ||
42 | if (dev->parent) | ||
43 | device_unlock(dev->parent); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static void hid_generic_add_driver(struct hid_driver *hdrv) | ||
49 | { | ||
50 | bus_for_each_dev(&hid_bus_type, NULL, hdrv, __unmap_hid_generic); | ||
51 | } | ||
52 | |||
53 | static void hid_generic_removed_driver(struct hid_driver *hdrv) | ||
54 | { | ||
55 | int ret; | ||
56 | |||
57 | ret = driver_attach(&hid_generic.driver); | ||
58 | } | ||
59 | |||
60 | static int __check_hid_generic(struct device_driver *drv, void *data) | 29 | static int __check_hid_generic(struct device_driver *drv, void *data) |
61 | { | 30 | { |
62 | struct hid_driver *hdrv = to_hid_driver(drv); | 31 | struct hid_driver *hdrv = to_hid_driver(drv); |
@@ -97,8 +66,6 @@ static struct hid_driver hid_generic = { | |||
97 | .name = "hid-generic", | 66 | .name = "hid-generic", |
98 | .id_table = hid_table, | 67 | .id_table = hid_table, |
99 | .match = hid_generic_match, | 68 | .match = hid_generic_match, |
100 | .bus_add_driver = hid_generic_add_driver, | ||
101 | .bus_removed_driver = hid_generic_removed_driver, | ||
102 | }; | 69 | }; |
103 | module_hid_driver(hid_generic); | 70 | module_hid_driver(hid_generic); |
104 | 71 | ||
diff --git a/include/linux/hid.h b/include/linux/hid.h index 091a81cf330f..a62ee4a609ac 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -686,8 +686,6 @@ struct hid_usage_id { | |||
686 | * @input_mapped: invoked on input registering after mapping an usage | 686 | * @input_mapped: invoked on input registering after mapping an usage |
687 | * @input_configured: invoked just before the device is registered | 687 | * @input_configured: invoked just before the device is registered |
688 | * @feature_mapping: invoked on feature registering | 688 | * @feature_mapping: invoked on feature registering |
689 | * @bus_add_driver: invoked when a HID driver is about to be added | ||
690 | * @bus_removed_driver: invoked when a HID driver has been removed | ||
691 | * @suspend: invoked on suspend (NULL means nop) | 689 | * @suspend: invoked on suspend (NULL means nop) |
692 | * @resume: invoked on resume if device was not reset (NULL means nop) | 690 | * @resume: invoked on resume if device was not reset (NULL means nop) |
693 | * @reset_resume: invoked on resume if device was reset (NULL means nop) | 691 | * @reset_resume: invoked on resume if device was reset (NULL means nop) |
@@ -742,8 +740,6 @@ struct hid_driver { | |||
742 | void (*feature_mapping)(struct hid_device *hdev, | 740 | void (*feature_mapping)(struct hid_device *hdev, |
743 | struct hid_field *field, | 741 | struct hid_field *field, |
744 | struct hid_usage *usage); | 742 | struct hid_usage *usage); |
745 | void (*bus_add_driver)(struct hid_driver *driver); | ||
746 | void (*bus_removed_driver)(struct hid_driver *driver); | ||
747 | #ifdef CONFIG_PM | 743 | #ifdef CONFIG_PM |
748 | int (*suspend)(struct hid_device *hdev, pm_message_t message); | 744 | int (*suspend)(struct hid_device *hdev, pm_message_t message); |
749 | int (*resume)(struct hid_device *hdev); | 745 | int (*resume)(struct hid_device *hdev); |