diff options
author | Johan Hovold <johan@kernel.org> | 2014-06-25 13:08:54 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-06-27 16:43:45 -0400 |
commit | f254bea49d05ee80b09d577947bd3b937e3a304a (patch) | |
tree | 1f7cd7ba3bd5d646811e2b826be4e6f65d2a23ac /drivers/input | |
parent | b2015ed5eae165372b6762b2d967829ba0254956 (diff) |
input: lm8323: fix attribute-creation race
Use the attribute groups of the led-class to create the time attribute
during probe in order to avoid racing with userspace.
Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/lm8323.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 0b42118cbf8f..cb32e2b506b7 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
@@ -558,6 +558,12 @@ static ssize_t lm8323_pwm_store_time(struct device *dev, | |||
558 | } | 558 | } |
559 | static DEVICE_ATTR(time, 0644, lm8323_pwm_show_time, lm8323_pwm_store_time); | 559 | static DEVICE_ATTR(time, 0644, lm8323_pwm_show_time, lm8323_pwm_store_time); |
560 | 560 | ||
561 | static struct attribute *lm8323_pwm_attrs[] = { | ||
562 | &dev_attr_time.attr, | ||
563 | NULL | ||
564 | }; | ||
565 | ATTRIBUTE_GROUPS(lm8323_pwm); | ||
566 | |||
561 | static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev, | 567 | static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev, |
562 | const char *name) | 568 | const char *name) |
563 | { | 569 | { |
@@ -580,16 +586,11 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev, | |||
580 | if (name) { | 586 | if (name) { |
581 | pwm->cdev.name = name; | 587 | pwm->cdev.name = name; |
582 | pwm->cdev.brightness_set = lm8323_pwm_set_brightness; | 588 | pwm->cdev.brightness_set = lm8323_pwm_set_brightness; |
589 | pwm->cdev.groups = lm8323_pwm_groups; | ||
583 | if (led_classdev_register(dev, &pwm->cdev) < 0) { | 590 | if (led_classdev_register(dev, &pwm->cdev) < 0) { |
584 | dev_err(dev, "couldn't register PWM %d\n", id); | 591 | dev_err(dev, "couldn't register PWM %d\n", id); |
585 | return -1; | 592 | return -1; |
586 | } | 593 | } |
587 | if (device_create_file(pwm->cdev.dev, | ||
588 | &dev_attr_time) < 0) { | ||
589 | dev_err(dev, "couldn't register time attribute\n"); | ||
590 | led_classdev_unregister(&pwm->cdev); | ||
591 | return -1; | ||
592 | } | ||
593 | pwm->enabled = true; | 594 | pwm->enabled = true; |
594 | } | 595 | } |
595 | 596 | ||
@@ -753,11 +754,8 @@ fail3: | |||
753 | device_remove_file(&client->dev, &dev_attr_disable_kp); | 754 | device_remove_file(&client->dev, &dev_attr_disable_kp); |
754 | fail2: | 755 | fail2: |
755 | while (--pwm >= 0) | 756 | while (--pwm >= 0) |
756 | if (lm->pwm[pwm].enabled) { | 757 | if (lm->pwm[pwm].enabled) |
757 | device_remove_file(lm->pwm[pwm].cdev.dev, | ||
758 | &dev_attr_time); | ||
759 | led_classdev_unregister(&lm->pwm[pwm].cdev); | 758 | led_classdev_unregister(&lm->pwm[pwm].cdev); |
760 | } | ||
761 | fail1: | 759 | fail1: |
762 | input_free_device(idev); | 760 | input_free_device(idev); |
763 | kfree(lm); | 761 | kfree(lm); |
@@ -777,10 +775,8 @@ static int lm8323_remove(struct i2c_client *client) | |||
777 | device_remove_file(&lm->client->dev, &dev_attr_disable_kp); | 775 | device_remove_file(&lm->client->dev, &dev_attr_disable_kp); |
778 | 776 | ||
779 | for (i = 0; i < 3; i++) | 777 | for (i = 0; i < 3; i++) |
780 | if (lm->pwm[i].enabled) { | 778 | if (lm->pwm[i].enabled) |
781 | device_remove_file(lm->pwm[i].cdev.dev, &dev_attr_time); | ||
782 | led_classdev_unregister(&lm->pwm[i].cdev); | 779 | led_classdev_unregister(&lm->pwm[i].cdev); |
783 | } | ||
784 | 780 | ||
785 | kfree(lm); | 781 | kfree(lm); |
786 | 782 | ||