aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-06-25 13:08:53 -0400
committerBryan Wu <cooloney@gmail.com>2014-06-25 18:35:11 -0400
commitb2015ed5eae165372b6762b2d967829ba0254956 (patch)
tree3bc16c4b40f6fa41c15b6756918c262d1af227c6 /drivers/leds
parent67bd8eb07eb873fe0b189ee2a9a9ca67f9023270 (diff)
leds: wm831x-status: fix attribute-creation race
Use the attribute groups of the led-class to create the src attribute 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-wm831x-status.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index e72c974142d0..1b71e0701002 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -219,6 +219,12 @@ static ssize_t wm831x_status_src_store(struct device *dev,
219 219
220static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store); 220static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store);
221 221
222static struct attribute *wm831x_status_attrs[] = {
223 &dev_attr_src.attr,
224 NULL
225};
226ATTRIBUTE_GROUPS(wm831x_status);
227
222static int wm831x_status_probe(struct platform_device *pdev) 228static int wm831x_status_probe(struct platform_device *pdev)
223{ 229{
224 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 230 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
@@ -232,8 +238,7 @@ static int wm831x_status_probe(struct platform_device *pdev)
232 res = platform_get_resource(pdev, IORESOURCE_REG, 0); 238 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
233 if (res == NULL) { 239 if (res == NULL) {
234 dev_err(&pdev->dev, "No register resource\n"); 240 dev_err(&pdev->dev, "No register resource\n");
235 ret = -EINVAL; 241 return -EINVAL;
236 goto err;
237 } 242 }
238 243
239 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status), 244 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status),
@@ -284,31 +289,21 @@ static int wm831x_status_probe(struct platform_device *pdev)
284 drvdata->cdev.default_trigger = pdata.default_trigger; 289 drvdata->cdev.default_trigger = pdata.default_trigger;
285 drvdata->cdev.brightness_set = wm831x_status_set; 290 drvdata->cdev.brightness_set = wm831x_status_set;
286 drvdata->cdev.blink_set = wm831x_status_blink_set; 291 drvdata->cdev.blink_set = wm831x_status_blink_set;
292 drvdata->cdev.groups = wm831x_status_groups;
287 293
288 ret = led_classdev_register(wm831x->dev, &drvdata->cdev); 294 ret = led_classdev_register(wm831x->dev, &drvdata->cdev);
289 if (ret < 0) { 295 if (ret < 0) {
290 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 296 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
291 goto err_led; 297 return ret;
292 } 298 }
293 299
294 ret = device_create_file(drvdata->cdev.dev, &dev_attr_src);
295 if (ret != 0)
296 dev_err(&pdev->dev,
297 "No source control for LED: %d\n", ret);
298
299 return 0; 300 return 0;
300
301err_led:
302 led_classdev_unregister(&drvdata->cdev);
303err:
304 return ret;
305} 301}
306 302
307static int wm831x_status_remove(struct platform_device *pdev) 303static int wm831x_status_remove(struct platform_device *pdev)
308{ 304{
309 struct wm831x_status *drvdata = platform_get_drvdata(pdev); 305 struct wm831x_status *drvdata = platform_get_drvdata(pdev);
310 306
311 device_remove_file(drvdata->cdev.dev, &dev_attr_src);
312 led_classdev_unregister(&drvdata->cdev); 307 led_classdev_unregister(&drvdata->cdev);
313 308
314 return 0; 309 return 0;