diff options
author | Johan Hovold <johan@kernel.org> | 2014-06-25 13:08:50 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-06-25 18:27:37 -0400 |
commit | 588a6a99286ae30afb1339d8bc2163517b1b7dd1 (patch) | |
tree | db8477424fcb782db0fdbe4705faa5a109ad0639 /drivers/leds | |
parent | 35c164998eede9e3d49f51541fcf2e639670fe72 (diff) |
leds: netxbig: fix attribute-creation race
Use the attribute groups of the led-class to create the sata attribute
during probe in order to avoid racing with userspace.
[cooloney@gmail.com: clean up return led_classdev_register()]
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-netxbig.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index e97f443a6e07..64fde485dcaa 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c | |||
@@ -293,10 +293,14 @@ static ssize_t netxbig_led_sata_show(struct device *dev, | |||
293 | 293 | ||
294 | static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); | 294 | static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); |
295 | 295 | ||
296 | static struct attribute *netxbig_led_attrs[] = { | ||
297 | &dev_attr_sata.attr, | ||
298 | NULL | ||
299 | }; | ||
300 | ATTRIBUTE_GROUPS(netxbig_led); | ||
301 | |||
296 | static void delete_netxbig_led(struct netxbig_led_data *led_dat) | 302 | static void delete_netxbig_led(struct netxbig_led_data *led_dat) |
297 | { | 303 | { |
298 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) | ||
299 | device_remove_file(led_dat->cdev.dev, &dev_attr_sata); | ||
300 | led_classdev_unregister(&led_dat->cdev); | 304 | led_classdev_unregister(&led_dat->cdev); |
301 | } | 305 | } |
302 | 306 | ||
@@ -306,7 +310,6 @@ create_netxbig_led(struct platform_device *pdev, | |||
306 | const struct netxbig_led *template) | 310 | const struct netxbig_led *template) |
307 | { | 311 | { |
308 | struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev); | 312 | struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev); |
309 | int ret; | ||
310 | 313 | ||
311 | spin_lock_init(&led_dat->lock); | 314 | spin_lock_init(&led_dat->lock); |
312 | led_dat->gpio_ext = pdata->gpio_ext; | 315 | led_dat->gpio_ext = pdata->gpio_ext; |
@@ -327,6 +330,12 @@ create_netxbig_led(struct platform_device *pdev, | |||
327 | led_dat->sata = 0; | 330 | led_dat->sata = 0; |
328 | led_dat->cdev.brightness = LED_OFF; | 331 | led_dat->cdev.brightness = LED_OFF; |
329 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 332 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; |
333 | /* | ||
334 | * If available, expose the SATA activity blink capability through | ||
335 | * a "sata" sysfs attribute. | ||
336 | */ | ||
337 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) | ||
338 | led_dat->cdev.groups = netxbig_led_groups; | ||
330 | led_dat->mode_addr = template->mode_addr; | 339 | led_dat->mode_addr = template->mode_addr; |
331 | led_dat->mode_val = template->mode_val; | 340 | led_dat->mode_val = template->mode_val; |
332 | led_dat->bright_addr = template->bright_addr; | 341 | led_dat->bright_addr = template->bright_addr; |
@@ -334,21 +343,7 @@ create_netxbig_led(struct platform_device *pdev, | |||
334 | led_dat->timer = pdata->timer; | 343 | led_dat->timer = pdata->timer; |
335 | led_dat->num_timer = pdata->num_timer; | 344 | led_dat->num_timer = pdata->num_timer; |
336 | 345 | ||
337 | ret = led_classdev_register(&pdev->dev, &led_dat->cdev); | 346 | return led_classdev_register(&pdev->dev, &led_dat->cdev); |
338 | if (ret < 0) | ||
339 | return ret; | ||
340 | |||
341 | /* | ||
342 | * If available, expose the SATA activity blink capability through | ||
343 | * a "sata" sysfs attribute. | ||
344 | */ | ||
345 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) { | ||
346 | ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata); | ||
347 | if (ret) | ||
348 | led_classdev_unregister(&led_dat->cdev); | ||
349 | } | ||
350 | |||
351 | return ret; | ||
352 | } | 347 | } |
353 | 348 | ||
354 | static int netxbig_led_probe(struct platform_device *pdev) | 349 | static int netxbig_led_probe(struct platform_device *pdev) |