aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/trigger/ledtrig-netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/trigger/ledtrig-netdev.c')
-rw-r--r--drivers/leds/trigger/ledtrig-netdev.c101
1 files changed, 33 insertions, 68 deletions
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index 6df4781a6308..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;
@@ -388,14 +388,14 @@ static void netdev_trig_work(struct work_struct *work)
388 (atomic_read(&trigger_data->interval)*2)); 388 (atomic_read(&trigger_data->interval)*2));
389} 389}
390 390
391static void netdev_trig_activate(struct led_classdev *led_cdev) 391static int netdev_trig_activate(struct led_classdev *led_cdev)
392{ 392{
393 struct led_netdev_data *trigger_data; 393 struct led_netdev_data *trigger_data;
394 int rc; 394 int rc;
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; 398 return -ENOMEM;
399 399
400 spin_lock_init(&trigger_data->lock); 400 spin_lock_init(&trigger_data->lock);
401 401
@@ -412,69 +412,34 @@ static void 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; 420
436 421 return rc;
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} 422}
451 423
452static void netdev_trig_deactivate(struct led_classdev *led_cdev) 424static void netdev_trig_deactivate(struct led_classdev *led_cdev)
453{ 425{
454 struct led_netdev_data *trigger_data = led_cdev->trigger_data; 426 struct led_netdev_data *trigger_data = led_get_trigger_data(led_cdev);
455
456 if (trigger_data) {
457 unregister_netdevice_notifier(&trigger_data->notifier);
458 427
459 device_remove_file(led_cdev->dev, &dev_attr_device_name); 428 unregister_netdevice_notifier(&trigger_data->notifier);
460 device_remove_file(led_cdev->dev, &dev_attr_link);
461 device_remove_file(led_cdev->dev, &dev_attr_rx);
462 device_remove_file(led_cdev->dev, &dev_attr_tx);
463 device_remove_file(led_cdev->dev, &dev_attr_interval);
464 429
465 cancel_delayed_work_sync(&trigger_data->work); 430 cancel_delayed_work_sync(&trigger_data->work);
466 431
467 if (trigger_data->net_dev) 432 if (trigger_data->net_dev)
468 dev_put(trigger_data->net_dev); 433 dev_put(trigger_data->net_dev);
469 434
470 kfree(trigger_data); 435 kfree(trigger_data);
471 }
472} 436}
473 437
474static struct led_trigger netdev_led_trigger = { 438static struct led_trigger netdev_led_trigger = {
475 .name = "netdev", 439 .name = "netdev",
476 .activate = netdev_trig_activate, 440 .activate = netdev_trig_activate,
477 .deactivate = netdev_trig_deactivate, 441 .deactivate = netdev_trig_deactivate,
442 .groups = netdev_trig_groups,
478}; 443};
479 444
480static int __init netdev_trig_init(void) 445static int __init netdev_trig_init(void)