diff options
author | Johan Hovold <johan@kernel.org> | 2014-06-25 13:08:46 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-06-25 18:02:31 -0400 |
commit | 9db9386016c6cfc6a6af3bacc7043cab8ff04ecf (patch) | |
tree | 77f0ca4c8fdd65069d4fb48ed26aeae4f7ea344d /drivers/leds | |
parent | 74c850394394efc0905c22ab9686e8d20e3921eb (diff) |
leds: lm3533: fix attribute-creation race
Use the attribute groups of the led-class to create the attributes
during probe in order to avoid racing with userspace.
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-lm3533.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c index e2c642c1169b..cbf61a40137d 100644 --- a/drivers/leds/leds-lm3533.c +++ b/drivers/leds/leds-lm3533.c | |||
@@ -645,6 +645,11 @@ static struct attribute_group lm3533_led_attribute_group = { | |||
645 | .attrs = lm3533_led_attributes | 645 | .attrs = lm3533_led_attributes |
646 | }; | 646 | }; |
647 | 647 | ||
648 | static const struct attribute_group *lm3533_led_attribute_groups[] = { | ||
649 | &lm3533_led_attribute_group, | ||
650 | NULL | ||
651 | }; | ||
652 | |||
648 | static int lm3533_led_setup(struct lm3533_led *led, | 653 | static int lm3533_led_setup(struct lm3533_led *led, |
649 | struct lm3533_led_platform_data *pdata) | 654 | struct lm3533_led_platform_data *pdata) |
650 | { | 655 | { |
@@ -692,6 +697,7 @@ static int lm3533_led_probe(struct platform_device *pdev) | |||
692 | led->cdev.brightness_get = lm3533_led_get; | 697 | led->cdev.brightness_get = lm3533_led_get; |
693 | led->cdev.blink_set = lm3533_led_blink_set; | 698 | led->cdev.blink_set = lm3533_led_blink_set; |
694 | led->cdev.brightness = LED_OFF; | 699 | led->cdev.brightness = LED_OFF; |
700 | led->cdev.groups = lm3533_led_attribute_groups, | ||
695 | led->id = pdev->id; | 701 | led->id = pdev->id; |
696 | 702 | ||
697 | mutex_init(&led->mutex); | 703 | mutex_init(&led->mutex); |
@@ -715,25 +721,16 @@ static int lm3533_led_probe(struct platform_device *pdev) | |||
715 | 721 | ||
716 | led->cb.dev = led->cdev.dev; | 722 | led->cb.dev = led->cdev.dev; |
717 | 723 | ||
718 | ret = sysfs_create_group(&led->cdev.dev->kobj, | ||
719 | &lm3533_led_attribute_group); | ||
720 | if (ret < 0) { | ||
721 | dev_err(&pdev->dev, "failed to create sysfs attributes\n"); | ||
722 | goto err_unregister; | ||
723 | } | ||
724 | |||
725 | ret = lm3533_led_setup(led, pdata); | 724 | ret = lm3533_led_setup(led, pdata); |
726 | if (ret) | 725 | if (ret) |
727 | goto err_sysfs_remove; | 726 | goto err_unregister; |
728 | 727 | ||
729 | ret = lm3533_ctrlbank_enable(&led->cb); | 728 | ret = lm3533_ctrlbank_enable(&led->cb); |
730 | if (ret) | 729 | if (ret) |
731 | goto err_sysfs_remove; | 730 | goto err_unregister; |
732 | 731 | ||
733 | return 0; | 732 | return 0; |
734 | 733 | ||
735 | err_sysfs_remove: | ||
736 | sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group); | ||
737 | err_unregister: | 734 | err_unregister: |
738 | led_classdev_unregister(&led->cdev); | 735 | led_classdev_unregister(&led->cdev); |
739 | flush_work(&led->work); | 736 | flush_work(&led->work); |
@@ -748,7 +745,6 @@ static int lm3533_led_remove(struct platform_device *pdev) | |||
748 | dev_dbg(&pdev->dev, "%s\n", __func__); | 745 | dev_dbg(&pdev->dev, "%s\n", __func__); |
749 | 746 | ||
750 | lm3533_ctrlbank_disable(&led->cb); | 747 | lm3533_ctrlbank_disable(&led->cb); |
751 | sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group); | ||
752 | led_classdev_unregister(&led->cdev); | 748 | led_classdev_unregister(&led->cdev); |
753 | flush_work(&led->work); | 749 | flush_work(&led->work); |
754 | 750 | ||