diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-14 13:07:22 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-14 13:07:22 -0700 |
commit | c07b3682cd12a017f976ec63bbd4758dc4c5100e (patch) | |
tree | d158994137113f31a30feadaae80d3c5d7109a26 /drivers/leds/trigger/ledtrig-netdev.c | |
parent | 4d88e3d24905eafa98cef0fc29365649ad8977b5 (diff) | |
parent | 2224f2ff9670b899983ff1b42d85530e889cfea1 (diff) |
Merge tag 'leds-for-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
Pull LED updates from Jacek Anaszewski:
"LED triggers improvements make the biggest part of this pull request.
The most striking ones, that allowed for nice cleanups in the triggers
are:
- centralized handling of creation and removal of trigger sysfs
attributes via attribute group
- addition of module_led_trigger() helper
The other things that need to be mentioned:
New features and improvements to existing LED class drivers:
- lt3593: add DT support, switch to gpiod interface
- lm3692x: support LED sync configuration, change OF calls to fwnode
calls
- apu: modify PC Engines apu/apu2 driver to support apu3
Change in the drivers/net/can/led.c:
- mark led trigger as broken since it's in the way for the further
cleanups. It implements a subset of the netdev trigger and an Ack
is needed from someone who can actually test and confirm that the
netdev trigger works for can devices"
* tag 'leds-for-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: (32 commits)
leds: ns2: Change unsigned to unsigned int
usb: simplify usbport trigger
leds: gpio trigger: simplifications from core changes
leds: backlight trigger: simplifications from core changes
leds: activity trigger: simplifications from core changes
leds: default-on trigger: make use of module_led_trigger()
leds: heartbeat trigger: simplifications from core changes
leds: oneshot trigger: simplifications from core changes
leds: transient trigger: simplifications from core changes
leds: timer trigger: simplifications from core changes
leds: netdev trigger: simplifications from core changes
leds: triggers: new function led_set_trigger_data()
leds: triggers: define module_led_trigger helper
leds: triggers: handle .trigger_data and .activated() in the core
leds: triggers: add device attribute support
leds: triggers: let struct led_trigger::activate() return an error code
leds: triggers: make the MODULE_LICENSE string match the actual license
leds: lm3692x: Support LED sync configuration
dt: bindings: lm3692x: Update binding for LED sync control
leds: lm3692x: Change DT calls to fwnode calls
...
Diffstat (limited to 'drivers/leds/trigger/ledtrig-netdev.c')
-rw-r--r-- | drivers/leds/trigger/ledtrig-netdev.c | 101 |
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) static ssize_t device_name_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_netdev_data *trigger_data = led_cdev->trigger_data; + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); ssize_t len; spin_lock_bh(&trigger_data->lock); @@ -109,8 +108,7 @@ static ssize_t device_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_netdev_data *trigger_data = led_cdev->trigger_data; + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); if (size >= IFNAMSIZ) return -EINVAL; @@ -150,8 +148,7 @@ static DEVICE_ATTR_RW(device_name); static ssize_t netdev_led_attr_show(struct device *dev, char *buf, enum netdev_led_attr attr) { - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_netdev_data *trigger_data = led_cdev->trigger_data; + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); int bit; switch (attr) { @@ -174,8 +171,7 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf, static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, size_t size, enum netdev_led_attr attr) { - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_netdev_data *trigger_data = led_cdev->trigger_data; + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); unsigned long state; int ret; int bit; @@ -255,8 +251,7 @@ static DEVICE_ATTR_RW(rx); static ssize_t interval_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_netdev_data *trigger_data = led_cdev->trigger_data; + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); return sprintf(buf, "%u\n", jiffies_to_msecs(atomic_read(&trigger_data->interval))); @@ -266,8 +261,7 @@ static ssize_t interval_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct led_netdev_data *trigger_data = led_cdev->trigger_data; + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); unsigned long value; int ret; @@ -288,15 +282,23 @@ static ssize_t interval_store(struct device *dev, static DEVICE_ATTR_RW(interval); +static struct attribute *netdev_trig_attrs[] = { + &dev_attr_device_name.attr, + &dev_attr_link.attr, + &dev_attr_rx.attr, + &dev_attr_tx.attr, + &dev_attr_interval.attr, + NULL +}; +ATTRIBUTE_GROUPS(netdev_trig); + static int netdev_trig_notify(struct notifier_block *nb, unsigned long evt, void *dv) { struct net_device *dev = netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv); - struct led_netdev_data *trigger_data = container_of(nb, - struct - led_netdev_data, - notifier); + struct led_netdev_data *trigger_data = + container_of(nb, struct led_netdev_data, notifier); if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER @@ -342,10 +344,8 @@ static int netdev_trig_notify(struct notifier_block *nb, /* here's the real work! */ static void netdev_trig_work(struct work_struct *work) { - struct led_netdev_data *trigger_data = container_of(work, - struct - led_netdev_data, - work.work); + struct led_netdev_data *trigger_data = + container_of(work, struct led_netdev_data, work.work); struct rtnl_link_stats64 *dev_stats; unsigned int new_activity; struct rtnl_link_stats64 temp; @@ -388,14 +388,14 @@ static void netdev_trig_work(struct work_struct *work) (atomic_read(&trigger_data->interval)*2)); } -static void netdev_trig_activate(struct led_classdev *led_cdev) +static int netdev_trig_activate(struct led_classdev *led_cdev) { struct led_netdev_data *trigger_data; int rc; trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); if (!trigger_data) - return; + return -ENOMEM; spin_lock_init(&trigger_data->lock); @@ -412,69 +412,34 @@ static void netdev_trig_activate(struct led_classdev *led_cdev) atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); trigger_data->last_activity = 0; - led_cdev->trigger_data = trigger_data; + led_set_trigger_data(led_cdev, trigger_data); - rc = device_create_file(led_cdev->dev, &dev_attr_device_name); - if (rc) - goto err_out; - rc = device_create_file(led_cdev->dev, &dev_attr_link); - if (rc) - goto err_out_device_name; - rc = device_create_file(led_cdev->dev, &dev_attr_rx); - if (rc) - goto err_out_link; - rc = device_create_file(led_cdev->dev, &dev_attr_tx); - if (rc) - goto err_out_rx; - rc = device_create_file(led_cdev->dev, &dev_attr_interval); - if (rc) - goto err_out_tx; rc = register_netdevice_notifier(&trigger_data->notifier); if (rc) - goto err_out_interval; - return; - -err_out_interval: - device_remove_file(led_cdev->dev, &dev_attr_interval); -err_out_tx: - device_remove_file(led_cdev->dev, &dev_attr_tx); -err_out_rx: - device_remove_file(led_cdev->dev, &dev_attr_rx); -err_out_link: - device_remove_file(led_cdev->dev, &dev_attr_link); -err_out_device_name: - device_remove_file(led_cdev->dev, &dev_attr_device_name); -err_out: - led_cdev->trigger_data = NULL; - kfree(trigger_data); + kfree(trigger_data); + + return rc; } static void netdev_trig_deactivate(struct led_classdev *led_cdev) { - struct led_netdev_data *trigger_data = led_cdev->trigger_data; - - if (trigger_data) { - unregister_netdevice_notifier(&trigger_data->notifier); + struct led_netdev_data *trigger_data = led_get_trigger_data(led_cdev); - device_remove_file(led_cdev->dev, &dev_attr_device_name); - device_remove_file(led_cdev->dev, &dev_attr_link); - device_remove_file(led_cdev->dev, &dev_attr_rx); - device_remove_file(led_cdev->dev, &dev_attr_tx); - device_remove_file(led_cdev->dev, &dev_attr_interval); + unregister_netdevice_notifier(&trigger_data->notifier); - cancel_delayed_work_sync(&trigger_data->work); + cancel_delayed_work_sync(&trigger_data->work); - if (trigger_data->net_dev) - dev_put(trigger_data->net_dev); + if (trigger_data->net_dev) + dev_put(trigger_data->net_dev); - kfree(trigger_data); - } + kfree(trigger_data); } static struct led_trigger netdev_led_trigger = { .name = "netdev", .activate = netdev_trig_activate, .deactivate = netdev_trig_deactivate, + .groups = netdev_trig_groups, }; static int __init netdev_trig_init(void) |