summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2017-12-08 09:29:44 -0500
committerJiri Kosina <jkosina@suse.cz>2018-03-06 10:00:51 -0500
commitc17a7476e4c41884d82e3675c25ceae982c07a63 (patch)
tree577796c9bda4e5663207717afdfd79b054764b9c
parent001fab49dd4fcf64b1b8ccecb8656baa3f3f1a9a (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.c35
-rw-r--r--drivers/hid/hid-generic.c33
-rw-r--r--include/linux/hid.h4
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)
2197EXPORT_SYMBOL_GPL(hid_destroy_device); 2197EXPORT_SYMBOL_GPL(hid_destroy_device);
2198 2198
2199 2199
2200static int __bus_add_driver(struct device_driver *drv, void *data) 2200static 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
2211static int __bus_removed_driver(struct device_driver *drv, void *data) 2212static 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
2224static int __bus_removed_driver(struct device_driver *drv, void *data)
2225{
2226 return bus_rescan_devices(&hid_bus_type);
2227}
2228
2222int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, 2229int __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}
2237EXPORT_SYMBOL_GPL(__hid_register_driver); 2250EXPORT_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
27static struct hid_driver hid_generic; 27static struct hid_driver hid_generic;
28 28
29static 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
48static 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
53static void hid_generic_removed_driver(struct hid_driver *hdrv)
54{
55 int ret;
56
57 ret = driver_attach(&hid_generic.driver);
58}
59
60static int __check_hid_generic(struct device_driver *drv, void *data) 29static 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};
103module_hid_driver(hid_generic); 70module_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);