From e04a0442d33b8cf183bba38646447b891bb02123 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 20 Nov 2017 11:48:44 +0100 Subject: HID: core: remove the absolute need of hid_have_special_driver[] Most HID devices behave properly when they are used with hid-generic. Since kernel v4.12, we do not poll for input reports at plug in, so hid-generic should behave properly with all HID devices. There has been a long standing list of HID devices that have a special driver. It used to be just a few, but with time, this list went too big, and we can not ask users to know which HID special driver will pick up their device. We can teach hid-generic to be nice with others. If a device is not explicitly marked with HID_QUIRK_HAVE_SPECIAL_DRIVER, we can allow hid-generic to pick up the device as long as no other loaded HID driver will match the device. When the special driver appears, hid-generic can step back and let the special driver handling the device. In case this special driver is removed, this good old pal of hid-generic will rebind to the device. This basically makes the list hid_have_special_driver[] useless. It still allows to not see a hid-generic driver bound and removed during boot, so we can keep it around. This will also help other people to have a special HID driver without the need of recompiling hid-core. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- include/linux/hid.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux/hid.h') diff --git a/include/linux/hid.h b/include/linux/hid.h index 83df331576a5..39cdeb205caa 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -672,6 +672,7 @@ struct hid_usage_id { * to be called) * @dyn_list: list of dynamically added device ids * @dyn_lock: lock protecting @dyn_list + * @match: check if the given device is handled by this driver * @probe: new device inserted * @remove: device removed (NULL if not a hot-plug capable driver) * @report_table: on which reports to call raw_event (NULL means all) @@ -684,6 +685,8 @@ struct hid_usage_id { * @input_mapped: invoked on input registering after mapping an usage * @input_configured: invoked just before the device is registered * @feature_mapping: invoked on feature registering + * @bus_add_driver: invoked when a HID driver is about to be added + * @bus_removed_driver: invoked when a HID driver has been removed * @suspend: invoked on suspend (NULL means nop) * @resume: invoked on resume if device was not reset (NULL means nop) * @reset_resume: invoked on resume if device was reset (NULL means nop) @@ -712,6 +715,7 @@ struct hid_driver { struct list_head dyn_list; spinlock_t dyn_lock; + bool (*match)(struct hid_device *dev, bool ignore_special_driver); int (*probe)(struct hid_device *dev, const struct hid_device_id *id); void (*remove)(struct hid_device *dev); @@ -737,6 +741,8 @@ struct hid_driver { void (*feature_mapping)(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage); + void (*bus_add_driver)(struct hid_driver *driver); + void (*bus_removed_driver)(struct hid_driver *driver); #ifdef CONFIG_PM int (*suspend)(struct hid_device *hdev, pm_message_t message); int (*resume)(struct hid_device *hdev); @@ -815,6 +821,8 @@ extern bool hid_ignore(struct hid_device *); extern int hid_add_device(struct hid_device *); extern void hid_destroy_device(struct hid_device *); +extern struct bus_type hid_bus_type; + extern int __must_check __hid_register_driver(struct hid_driver *, struct module *, const char *mod_name); @@ -865,6 +873,8 @@ bool hid_match_one_id(const struct hid_device *hdev, const struct hid_device_id *id); const struct hid_device_id *hid_match_id(const struct hid_device *hdev, const struct hid_device_id *id); +const struct hid_device_id *hid_match_device(struct hid_device *hdev, + struct hid_driver *hdrv); s32 hid_snto32(__u32 value, unsigned n); __u32 hid_field_extract(const struct hid_device *hid, __u8 *report, unsigned offset, unsigned n); -- cgit v1.2.3