diff options
Diffstat (limited to 'drivers/usb/core/ledtrig-usbport.c')
| -rw-r--r-- | drivers/usb/core/ledtrig-usbport.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index aa1d51458da7..dc7f7fd71684 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c | |||
| @@ -113,11 +113,17 @@ static ssize_t usbport_trig_port_store(struct device *dev, | |||
| 113 | static struct attribute *ports_attrs[] = { | 113 | static struct attribute *ports_attrs[] = { |
| 114 | NULL, | 114 | NULL, |
| 115 | }; | 115 | }; |
| 116 | |||
| 116 | static const struct attribute_group ports_group = { | 117 | static const struct attribute_group ports_group = { |
| 117 | .name = "ports", | 118 | .name = "ports", |
| 118 | .attrs = ports_attrs, | 119 | .attrs = ports_attrs, |
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 122 | static const struct attribute_group *ports_groups[] = { | ||
| 123 | &ports_group, | ||
| 124 | NULL | ||
| 125 | }; | ||
| 126 | |||
| 121 | /*************************************** | 127 | /*************************************** |
| 122 | * Adding & removing ports | 128 | * Adding & removing ports |
| 123 | ***************************************/ | 129 | ***************************************/ |
| @@ -301,59 +307,44 @@ static int usbport_trig_notify(struct notifier_block *nb, unsigned long action, | |||
| 301 | static int usbport_trig_activate(struct led_classdev *led_cdev) | 307 | static int usbport_trig_activate(struct led_classdev *led_cdev) |
| 302 | { | 308 | { |
| 303 | struct usbport_trig_data *usbport_data; | 309 | struct usbport_trig_data *usbport_data; |
| 304 | int err; | ||
| 305 | 310 | ||
| 306 | usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); | 311 | usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); |
| 307 | if (!usbport_data) | 312 | if (!usbport_data) |
| 308 | return 0; | 313 | return -ENOMEM; |
| 309 | usbport_data->led_cdev = led_cdev; | 314 | usbport_data->led_cdev = led_cdev; |
| 310 | 315 | ||
| 311 | /* List of ports */ | 316 | /* List of ports */ |
| 312 | INIT_LIST_HEAD(&usbport_data->ports); | 317 | INIT_LIST_HEAD(&usbport_data->ports); |
| 313 | err = sysfs_create_group(&led_cdev->dev->kobj, &ports_group); | ||
| 314 | if (err) | ||
| 315 | goto err_free; | ||
| 316 | usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports); | 318 | usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports); |
| 317 | usbport_trig_update_count(usbport_data); | 319 | usbport_trig_update_count(usbport_data); |
| 318 | 320 | ||
| 319 | /* Notifications */ | 321 | /* Notifications */ |
| 320 | usbport_data->nb.notifier_call = usbport_trig_notify, | 322 | usbport_data->nb.notifier_call = usbport_trig_notify; |
| 321 | led_cdev->trigger_data = usbport_data; | 323 | led_set_trigger_data(led_cdev, usbport_data); |
| 322 | usb_register_notify(&usbport_data->nb); | 324 | usb_register_notify(&usbport_data->nb); |
| 323 | 325 | ||
| 324 | led_cdev->activated = true; | ||
| 325 | return 0; | ||
| 326 | |||
| 327 | err_free: | ||
| 328 | kfree(usbport_data); | ||
| 329 | return 0; | 326 | return 0; |
| 330 | } | 327 | } |
| 331 | 328 | ||
| 332 | static void usbport_trig_deactivate(struct led_classdev *led_cdev) | 329 | static void usbport_trig_deactivate(struct led_classdev *led_cdev) |
| 333 | { | 330 | { |
| 334 | struct usbport_trig_data *usbport_data = led_cdev->trigger_data; | 331 | struct usbport_trig_data *usbport_data = led_get_trigger_data(led_cdev); |
| 335 | struct usbport_trig_port *port, *tmp; | 332 | struct usbport_trig_port *port, *tmp; |
| 336 | 333 | ||
| 337 | if (!led_cdev->activated) | ||
| 338 | return; | ||
| 339 | |||
| 340 | list_for_each_entry_safe(port, tmp, &usbport_data->ports, list) { | 334 | list_for_each_entry_safe(port, tmp, &usbport_data->ports, list) { |
| 341 | usbport_trig_remove_port(usbport_data, port); | 335 | usbport_trig_remove_port(usbport_data, port); |
| 342 | } | 336 | } |
| 343 | 337 | ||
| 344 | usb_unregister_notify(&usbport_data->nb); | 338 | usb_unregister_notify(&usbport_data->nb); |
| 345 | 339 | ||
| 346 | sysfs_remove_group(&led_cdev->dev->kobj, &ports_group); | ||
| 347 | |||
| 348 | kfree(usbport_data); | 340 | kfree(usbport_data); |
| 349 | |||
| 350 | led_cdev->activated = false; | ||
| 351 | } | 341 | } |
| 352 | 342 | ||
| 353 | static struct led_trigger usbport_led_trigger = { | 343 | static struct led_trigger usbport_led_trigger = { |
| 354 | .name = "usbport", | 344 | .name = "usbport", |
| 355 | .activate = usbport_trig_activate, | 345 | .activate = usbport_trig_activate, |
| 356 | .deactivate = usbport_trig_deactivate, | 346 | .deactivate = usbport_trig_deactivate, |
| 347 | .groups = ports_groups, | ||
| 357 | }; | 348 | }; |
| 358 | 349 | ||
| 359 | static int __init usbport_trig_init(void) | 350 | static int __init usbport_trig_init(void) |
