aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/trigger/ledtrig-netdev.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2018-07-02 16:05:26 -0400
committerJacek Anaszewski <jacek.anaszewski@gmail.com>2018-07-05 17:21:12 -0400
commitf8112a1de1a728ffef0dd9f6c3005490c5f79ab1 (patch)
tree2013461f5b4180fc422705ec8220761a967de30e /drivers/leds/trigger/ledtrig-netdev.c
parent9acc560de2aac73ef99c54f0fdfb86b4684296b5 (diff)
leds: netdev trigger: simplifications from core changes
The trigger core learned error handling for the activate callback and can handle device attributes now. This allows simplifying the driver considerably. Note that .deactivate() is only called when .activate() succeeded, so the check for trigger_data being non-NULL can go away. (It was broken before because the core didn't clear .trigger_data, so it might have been non-NULL even if .activate() failed before.) Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Diffstat (limited to 'drivers/leds/trigger/ledtrig-netdev.c')
-rw-r--r--drivers/leds/trigger/ledtrig-netdev.c99
1 files changed, 31 insertions, 68 deletions
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index bb05937255de..3dd3ed46d473 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -94,8 +94,7 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
94static ssize_t device_name_show(struct device *dev, 94static ssize_t device_name_show(struct device *dev,
95 struct device_attribute *attr, char *buf) 95 struct device_attribute *attr, char *buf)
96{ 96{
97 struct led_classdev *led_cdev = dev_get_drvdata(dev); 97 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
98 struct led_netdev_data *trigger_data = led_cdev->trigger_data;
99 ssize_t len; 98 ssize_t len;
100 99
101 spin_lock_bh(&trigger_data->lock); 100 spin_lock_bh(&trigger_data->lock);
@@ -109,8 +108,7 @@ static ssize_t device_name_store(struct device *dev,
109 struct device_attribute *attr, const char *buf, 108 struct device_attribute *attr, const char *buf,
110 size_t size) 109 size_t size)
111{ 110{
112 struct led_classdev *led_cdev = dev_get_drvdata(dev); 111 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
113 struct led_netdev_data *trigger_data = led_cdev->trigger_data;
114 112
115 if (size >= IFNAMSIZ) 113 if (size >= IFNAMSIZ)
116 return -EINVAL; 114 return -EINVAL;
@@ -150,8 +148,7 @@ static DEVICE_ATTR_RW(device_name);
150static ssize_t netdev_led_attr_show(struct device *dev, char *buf, 148static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
151 enum netdev_led_attr attr) 149 enum netdev_led_attr attr)
152{ 150{
153 struct led_classdev *led_cdev = dev_get_drvdata(dev); 151 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
154 struct led_netdev_data *trigger_data = led_cdev->trigger_data;
155 int bit; 152 int bit;
156 153
157 switch (attr) { 154 switch (attr) {
@@ -174,8 +171,7 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
174static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, 171static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
175 size_t size, enum netdev_led_attr attr) 172 size_t size, enum netdev_led_attr attr)
176{ 173{
177 struct led_classdev *led_cdev = dev_get_drvdata(dev); 174 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
178 struct led_netdev_data *trigger_data = led_cdev->trigger_data;
179 unsigned long state; 175 unsigned long state;
180 int ret; 176 int ret;
181 int bit; 177 int bit;
@@ -255,8 +251,7 @@ static DEVICE_ATTR_RW(rx);
255static ssize_t interval_show(struct device *dev, 251static ssize_t interval_show(struct device *dev,
256 struct device_attribute *attr, char *buf) 252 struct device_attribute *attr, char *buf)
257{ 253{
258 struct led_classdev *led_cdev = dev_get_drvdata(dev); 254 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
259 struct led_netdev_data *trigger_data = led_cdev->trigger_data;
260 255
261 return sprintf(buf, "%u\n", 256 return sprintf(buf, "%u\n",
262 jiffies_to_msecs(atomic_read(&trigger_data->interval))); 257 jiffies_to_msecs(atomic_read(&trigger_data->interval)));
@@ -266,8 +261,7 @@ static ssize_t interval_store(struct device *dev,
266 struct device_attribute *attr, const char *buf, 261 struct device_attribute *attr, const char *buf,
267 size_t size) 262 size_t size)
268{ 263{
269 struct led_classdev *led_cdev = dev_get_drvdata(dev); 264 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
270 struct led_netdev_data *trigger_data = led_cdev->trigger_data;
271 unsigned long value; 265 unsigned long value;
272 int ret; 266 int ret;
273 267
@@ -288,15 +282,23 @@ static ssize_t interval_store(struct device *dev,
288 282
289static DEVICE_ATTR_RW(interval); 283static DEVICE_ATTR_RW(interval);
290 284
285static struct attribute *netdev_trig_attrs[] = {
286 &dev_attr_device_name.attr,
287 &dev_attr_link.attr,
288 &dev_attr_rx.attr,
289 &dev_attr_tx.attr,
290 &dev_attr_interval.attr,
291 NULL
292};
293ATTRIBUTE_GROUPS(netdev_trig);
294
291static int netdev_trig_notify(struct notifier_block *nb, 295static int netdev_trig_notify(struct notifier_block *nb,
292 unsigned long evt, void *dv) 296 unsigned long evt, void *dv)
293{ 297{
294 struct net_device *dev = 298 struct net_device *dev =
295 netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv); 299 netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv);
296 struct led_netdev_data *trigger_data = container_of(nb, 300 struct led_netdev_data *trigger_data =
297 struct 301 container_of(nb, struct led_netdev_data, notifier);
298 led_netdev_data,
299 notifier);
300 302
301 if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE 303 if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE
302 && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER 304 && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER
@@ -342,10 +344,8 @@ static int netdev_trig_notify(struct notifier_block *nb,
342/* here's the real work! */ 344/* here's the real work! */
343static void netdev_trig_work(struct work_struct *work) 345static void netdev_trig_work(struct work_struct *work)
344{ 346{
345 struct led_netdev_data *trigger_data = container_of(work, 347 struct led_netdev_data *trigger_data =
346 struct 348 container_of(work, struct led_netdev_data, work.work);
347 led_netdev_data,
348 work.work);
349 struct rtnl_link_stats64 *dev_stats; 349 struct rtnl_link_stats64 *dev_stats;
350 unsigned int new_activity; 350 unsigned int new_activity;
351 struct rtnl_link_stats64 temp; 351 struct rtnl_link_stats64 temp;
@@ -395,7 +395,7 @@ static int netdev_trig_activate(struct led_classdev *led_cdev)
395 395
396 trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); 396 trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
397 if (!trigger_data) 397 if (!trigger_data)
398 return 0; 398 return -ENOMEM;
399 399
400 spin_lock_init(&trigger_data->lock); 400 spin_lock_init(&trigger_data->lock);
401 401
@@ -412,71 +412,34 @@ static int netdev_trig_activate(struct led_classdev *led_cdev)
412 atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); 412 atomic_set(&trigger_data->interval, msecs_to_jiffies(50));
413 trigger_data->last_activity = 0; 413 trigger_data->last_activity = 0;
414 414
415 led_cdev->trigger_data = trigger_data; 415 led_set_trigger_data(led_cdev, trigger_data);
416 416
417 rc = device_create_file(led_cdev->dev, &dev_attr_device_name);
418 if (rc)
419 goto err_out;
420 rc = device_create_file(led_cdev->dev, &dev_attr_link);
421 if (rc)
422 goto err_out_device_name;
423 rc = device_create_file(led_cdev->dev, &dev_attr_rx);
424 if (rc)
425 goto err_out_link;
426 rc = device_create_file(led_cdev->dev, &dev_attr_tx);
427 if (rc)
428 goto err_out_rx;
429 rc = device_create_file(led_cdev->dev, &dev_attr_interval);
430 if (rc)
431 goto err_out_tx;
432 rc = register_netdevice_notifier(&trigger_data->notifier); 417 rc = register_netdevice_notifier(&trigger_data->notifier);
433 if (rc) 418 if (rc)
434 goto err_out_interval; 419 kfree(trigger_data);
435 return 0;
436
437err_out_interval:
438 device_remove_file(led_cdev->dev, &dev_attr_interval);
439err_out_tx:
440 device_remove_file(led_cdev->dev, &dev_attr_tx);
441err_out_rx:
442 device_remove_file(led_cdev->dev, &dev_attr_rx);
443err_out_link:
444 device_remove_file(led_cdev->dev, &dev_attr_link);
445err_out_device_name:
446 device_remove_file(led_cdev->dev, &dev_attr_device_name);
447err_out:
448 led_cdev->trigger_data = NULL;
449 kfree(trigger_data);
450 420
451 return 0; 421 return rc;
452} 422}
453 423
454static void netdev_trig_deactivate(struct led_classdev *led_cdev) 424static void netdev_trig_deactivate(struct led_classdev *led_cdev)
455{ 425{
456 struct led_netdev_data *trigger_data = led_cdev->trigger_data; 426 struct led_netdev_data *trigger_data = led_get_trigger_data(led_cdev);
457 427
458 if (trigger_data) { 428 unregister_netdevice_notifier(&trigger_data->notifier);
459 unregister_netdevice_notifier(&trigger_data->notifier);
460 429
461 device_remove_file(led_cdev->dev, &dev_attr_device_name); 430 cancel_delayed_work_sync(&trigger_data->work);
462 device_remove_file(led_cdev->dev, &dev_attr_link);
463 device_remove_file(led_cdev->dev, &dev_attr_rx);
464 device_remove_file(led_cdev->dev, &dev_attr_tx);
465 device_remove_file(led_cdev->dev, &dev_attr_interval);
466
467 cancel_delayed_work_sync(&trigger_data->work);
468 431
469 if (trigger_data->net_dev) 432 if (trigger_data->net_dev)
470 dev_put(trigger_data->net_dev); 433 dev_put(trigger_data->net_dev);
471 434
472 kfree(trigger_data); 435 kfree(trigger_data);
473 }
474} 436}
475 437
476static struct led_trigger netdev_led_trigger = { 438static struct led_trigger netdev_led_trigger = {
477 .name = "netdev", 439 .name = "netdev",
478 .activate = netdev_trig_activate, 440 .activate = netdev_trig_activate,
479 .deactivate = netdev_trig_deactivate, 441 .deactivate = netdev_trig_deactivate,
442 .groups = netdev_trig_groups,
480}; 443};
481 444
482static int __init netdev_trig_init(void) 445static int __init netdev_trig_init(void)