diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c2560aae55420860430b9a5aa1a41f93aa701474..c058bb911ca15d8a487f5b2bc4cfd549a335842b 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) EXPORT_SYMBOL_GPL(hid_destroy_device); -static int __bus_add_driver(struct device_driver *drv, void *data) +static int __hid_bus_reprobe_drivers(struct device *dev, void *data) { - struct hid_driver *added_hdrv = data; - struct hid_driver *hdrv = to_hid_driver(drv); + struct hid_driver *hdrv = data; + struct hid_device *hdev = to_hid_device(dev); - if (hdrv->bus_add_driver) - hdrv->bus_add_driver(added_hdrv); + if (hdev->driver == hdrv && + !hdrv->match(hdev, hid_ignore_special_drivers)) + return device_reprobe(dev); return 0; } -static int __bus_removed_driver(struct device_driver *drv, void *data) +static int __hid_bus_driver_added(struct device_driver *drv, void *data) { - struct hid_driver *removed_hdrv = data; struct hid_driver *hdrv = to_hid_driver(drv); - if (hdrv->bus_removed_driver) - hdrv->bus_removed_driver(removed_hdrv); + if (hdrv->match) { + bus_for_each_dev(&hid_bus_type, NULL, hdrv, + __hid_bus_reprobe_drivers); + } return 0; } +static int __bus_removed_driver(struct device_driver *drv, void *data) +{ + return bus_rescan_devices(&hid_bus_type); +} + int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, const char *mod_name) { + int ret; + hdrv->driver.name = hdrv->name; hdrv->driver.bus = &hid_bus_type; hdrv->driver.owner = owner; @@ -2230,9 +2239,13 @@ int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, INIT_LIST_HEAD(&hdrv->dyn_list); spin_lock_init(&hdrv->dyn_lock); - bus_for_each_drv(&hid_bus_type, NULL, hdrv, __bus_add_driver); + ret = driver_register(&hdrv->driver); + + if (ret == 0) + bus_for_each_drv(&hid_bus_type, NULL, NULL, + __hid_bus_driver_added); - return driver_register(&hdrv->driver); + return ret; } EXPORT_SYMBOL_GPL(__hid_register_driver); diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index 3c0a1bf433d75840cf624e6ec3124494cb01383b..c25b4718de440e403a09c96ea0e161e7ff796a95 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c @@ -26,37 +26,6 @@ static struct hid_driver hid_generic; -static int __unmap_hid_generic(struct device *dev, void *data) -{ - struct hid_driver *hdrv = data; - struct hid_device *hdev = to_hid_device(dev); - - /* only unbind matching devices already bound to hid-generic */ - if (hdev->driver != &hid_generic || - hid_match_device(hdev, hdrv) == NULL) - return 0; - - if (dev->parent) /* Needed for USB */ - device_lock(dev->parent); - device_release_driver(dev); - if (dev->parent) - device_unlock(dev->parent); - - return 0; -} - -static void hid_generic_add_driver(struct hid_driver *hdrv) -{ - bus_for_each_dev(&hid_bus_type, NULL, hdrv, __unmap_hid_generic); -} - -static void hid_generic_removed_driver(struct hid_driver *hdrv) -{ - int ret; - - ret = driver_attach(&hid_generic.driver); -} - static int __check_hid_generic(struct device_driver *drv, void *data) { struct hid_driver *hdrv = to_hid_driver(drv); @@ -97,8 +66,6 @@ static struct hid_driver hid_generic = { .name = "hid-generic", .id_table = hid_table, .match = hid_generic_match, - .bus_add_driver = hid_generic_add_driver, - .bus_removed_driver = hid_generic_removed_driver, }; module_hid_driver(hid_generic); diff --git a/include/linux/hid.h b/include/linux/hid.h index 091a81cf330ff91925c60bb4b32c333b35a49bfe..a62ee4a609acad39fdc304f82f55a895b12f1d2d 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -686,8 +686,6 @@ 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) @@ -742,8 +740,6 @@ 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);