aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-06-25 13:08:56 -0400
committerBryan Wu <cooloney@gmail.com>2014-06-27 16:44:05 -0400
commit44a1255b03aeedb56cbe7cf27461458bd4513049 (patch)
tree2203921e8ef397ac30e509be9808a762876318ff /drivers/leds
parent660216bf82e0cd65603c0935193c1f7c4aca04fb (diff)
leds: lp55xx-common: fix attribute-creation race
Use the attribute groups of the led-class to create the LED 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-lp55xx-common.c22
1 files changed, 3 insertions, 19 deletions
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 3fbfb31602c7..77c26bc32eed 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -127,15 +127,12 @@ static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current,
127 lp55xx_store_current); 127 lp55xx_store_current);
128static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL); 128static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL);
129 129
130static struct attribute *lp55xx_led_attributes[] = { 130static struct attribute *lp55xx_led_attrs[] = {
131 &dev_attr_led_current.attr, 131 &dev_attr_led_current.attr,
132 &dev_attr_max_current.attr, 132 &dev_attr_max_current.attr,
133 NULL, 133 NULL,
134}; 134};
135 135ATTRIBUTE_GROUPS(lp55xx_led);
136static struct attribute_group lp55xx_led_attr_group = {
137 .attrs = lp55xx_led_attributes
138};
139 136
140static void lp55xx_set_brightness(struct led_classdev *cdev, 137static void lp55xx_set_brightness(struct led_classdev *cdev,
141 enum led_brightness brightness) 138 enum led_brightness brightness)
@@ -176,6 +173,7 @@ static int lp55xx_init_led(struct lp55xx_led *led,
176 } 173 }
177 174
178 led->cdev.brightness_set = lp55xx_set_brightness; 175 led->cdev.brightness_set = lp55xx_set_brightness;
176 led->cdev.groups = lp55xx_led_groups;
179 177
180 if (pdata->led_config[chan].name) { 178 if (pdata->led_config[chan].name) {
181 led->cdev.name = pdata->led_config[chan].name; 179 led->cdev.name = pdata->led_config[chan].name;
@@ -185,24 +183,12 @@ static int lp55xx_init_led(struct lp55xx_led *led,
185 led->cdev.name = name; 183 led->cdev.name = name;
186 } 184 }
187 185
188 /*
189 * register led class device for each channel and
190 * add device attributes
191 */
192
193 ret = led_classdev_register(dev, &led->cdev); 186 ret = led_classdev_register(dev, &led->cdev);
194 if (ret) { 187 if (ret) {
195 dev_err(dev, "led register err: %d\n", ret); 188 dev_err(dev, "led register err: %d\n", ret);
196 return ret; 189 return ret;
197 } 190 }
198 191
199 ret = sysfs_create_group(&led->cdev.dev->kobj, &lp55xx_led_attr_group);
200 if (ret) {
201 dev_err(dev, "led sysfs err: %d\n", ret);
202 led_classdev_unregister(&led->cdev);
203 return ret;
204 }
205
206 return 0; 192 return 0;
207} 193}
208 194
@@ -520,8 +506,6 @@ void lp55xx_unregister_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)
520 506
521 for (i = 0; i < chip->num_leds; i++) { 507 for (i = 0; i < chip->num_leds; i++) {
522 each = led + i; 508 each = led + i;
523 sysfs_remove_group(&each->cdev.dev->kobj,
524 &lp55xx_led_attr_group);
525 led_classdev_unregister(&each->cdev); 509 led_classdev_unregister(&each->cdev);
526 flush_work(&each->brightness_work); 510 flush_work(&each->brightness_work);
527 } 511 }