diff options
author | Johan Hovold <johan@kernel.org> | 2014-06-25 13:08:53 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-06-25 18:35:11 -0400 |
commit | b2015ed5eae165372b6762b2d967829ba0254956 (patch) | |
tree | 3bc16c4b40f6fa41c15b6756918c262d1af227c6 /drivers/leds | |
parent | 67bd8eb07eb873fe0b189ee2a9a9ca67f9023270 (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.c | 23 |
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 | ||
220 | static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store); | 220 | static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store); |
221 | 221 | ||
222 | static struct attribute *wm831x_status_attrs[] = { | ||
223 | &dev_attr_src.attr, | ||
224 | NULL | ||
225 | }; | ||
226 | ATTRIBUTE_GROUPS(wm831x_status); | ||
227 | |||
222 | static int wm831x_status_probe(struct platform_device *pdev) | 228 | static 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 | |||
301 | err_led: | ||
302 | led_classdev_unregister(&drvdata->cdev); | ||
303 | err: | ||
304 | return ret; | ||
305 | } | 301 | } |
306 | 302 | ||
307 | static int wm831x_status_remove(struct platform_device *pdev) | 303 | static 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; |