* [PATCH leds + devicetree v1 0/2] Parse DT property `trigger-sources` for netdev LED trigger
@ 2020-09-14 23:41 Marek Behún
2020-09-14 23:41 ` [PATCH leds + devicetree v1 1/2] leds: trigger: add DT `trigger-sources` validating method Marek Behún
2020-09-14 23:41 ` [PATCH leds + devicetree v1 2/2] leds: trigger: netdev: allow parsing `trigger-sources` from device tree Marek Behún
0 siblings, 2 replies; 4+ messages in thread
From: Marek Behún @ 2020-09-14 23:41 UTC (permalink / raw)
To: linux-leds
Cc: Pavel Machek, Dan Murphy, Ondřej Jirman, Russell King,
Andrew Lunn, linux-kernel, Matthias Schiffer, Marek Behún
Hi,
the `trigger-sources` LED DT property is currently only implemented
for ledtrig-usbport.
Lets implement it for the netdev LED trigger.
In this proposal the specific netdev LED trigger mode is determined
from the `function` LED DT property.
Example:
eth0: ethernet@30000 {
compatible = "xyz";
#trigger-source-cells = <0>;
};
led {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LINK;
trigger-sources = <ð0>;
};
When led is registered, the netdev trigger is automatically activated
and set to light the LED on if eth0 is linked.
Please let me know if this binding is OK, or if the binding should
instead of the `function` property determine the trigger settings from
arguments of the `trigger-sources` property :
led {
color = <LED_COLOR_ID_GREEN>;
trigger-sources = <ð0 (NETDEV_ATTR_LINK | NETDEV_ATTR_RX)>;
};
I prefer the first binding, since we already have the `function`
property. Multiple modes can be achieved by string array, but this is
not yet implemented:
led {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LINK, LED_FUNCTION_ACTIVITY;
trigger-sources = <ð0>;
};
Marek
Marek Behún (2):
leds: trigger: add DT `trigger-source` validating method
leds: trigger: netdev: allow parsing `trigger-sources` from device
tree
drivers/leds/led-triggers.c | 26 +++++---
drivers/leds/trigger/ledtrig-netdev.c | 91 ++++++++++++++++++++++++++-
include/dt-bindings/leds/common.h | 1 +
include/linux/leds.h | 6 ++
4 files changed, 115 insertions(+), 9 deletions(-)
--
2.26.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH leds + devicetree v1 1/2] leds: trigger: add DT `trigger-sources` validating method
2020-09-14 23:41 [PATCH leds + devicetree v1 0/2] Parse DT property `trigger-sources` for netdev LED trigger Marek Behún
@ 2020-09-14 23:41 ` Marek Behún
2020-09-14 23:41 ` [PATCH leds + devicetree v1 2/2] leds: trigger: netdev: allow parsing `trigger-sources` from device tree Marek Behún
1 sibling, 0 replies; 4+ messages in thread
From: Marek Behún @ 2020-09-14 23:41 UTC (permalink / raw)
To: linux-leds
Cc: Pavel Machek, Dan Murphy, Ondřej Jirman, Russell King,
Andrew Lunn, linux-kernel, Matthias Schiffer, Marek Behún,
Rob Herring, devicetree
Currently we use the `linux,default-trigger` device tree property of a
LED to define the default trigger which should be activated for a LED.
But the LED device tree binding also documents the `trigger-sources`
property, which specifies the source device which should be triggering
the LED.
The `trigger-sources` property is currently implemented only in
drivers/usb/core/ledtrig-usbport.c.
Lets add a method to struct led_trigger which, if implemented, can check
whether this trigger should be enabled as default. This check shall be
done by checking whether the specified `trigger-sources` refers to a
device compatible with the trigger.
Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
---
drivers/leds/led-triggers.c | 26 ++++++++++++++++++--------
include/linux/leds.h | 6 ++++++
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 91da90cfb11d9..c96577f0bfe97 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -243,18 +243,30 @@ void led_trigger_remove(struct led_classdev *led_cdev)
}
EXPORT_SYMBOL_GPL(led_trigger_remove);
+static bool trigger_is_default(struct led_classdev *led_cdev,
+ struct led_trigger *trig)
+{
+ if (!trigger_relevant(led_cdev, trig))
+ return false;
+
+ if (led_cdev->default_trigger &&
+ !strcmp(led_cdev->default_trigger, trig->name))
+ return true;
+
+ if (trig->has_valid_source && trig->has_valid_source(led_cdev))
+ return true;
+
+ return false;
+}
+
void led_trigger_set_default(struct led_classdev *led_cdev)
{
struct led_trigger *trig;
- if (!led_cdev->default_trigger)
- return;
-
down_read(&triggers_list_lock);
down_write(&led_cdev->trigger_lock);
list_for_each_entry(trig, &trigger_list, next_trig) {
- if (!strcmp(led_cdev->default_trigger, trig->name) &&
- trigger_relevant(led_cdev, trig)) {
+ if (trigger_is_default(led_cdev, trig)) {
led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
led_trigger_set(led_cdev, trig);
break;
@@ -306,9 +318,7 @@ int led_trigger_register(struct led_trigger *trig)
down_read(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
down_write(&led_cdev->trigger_lock);
- if (!led_cdev->trigger && led_cdev->default_trigger &&
- !strcmp(led_cdev->default_trigger, trig->name) &&
- trigger_relevant(led_cdev, trig)) {
+ if (!led_cdev->trigger && trigger_is_default(led_cdev, trig)) {
led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
led_trigger_set(led_cdev, trig);
}
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 6a8d6409c993e..4cbb826e4bec4 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -352,6 +352,12 @@ struct led_trigger {
int (*activate)(struct led_classdev *led_cdev);
void (*deactivate)(struct led_classdev *led_cdev);
+ /*
+ * Check whether LED has defined valid source for this trigger.
+ * If yes, this trigger should be set as default trigger for LED.
+ */
+ bool (*has_valid_source)(struct led_classdev *led_cdev);
+
/* LED-private triggers have this set */
struct led_hw_trigger_type *trigger_type;
--
2.26.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH leds + devicetree v1 2/2] leds: trigger: netdev: allow parsing `trigger-sources` from device tree
2020-09-14 23:41 [PATCH leds + devicetree v1 0/2] Parse DT property `trigger-sources` for netdev LED trigger Marek Behún
2020-09-14 23:41 ` [PATCH leds + devicetree v1 1/2] leds: trigger: add DT `trigger-sources` validating method Marek Behún
@ 2020-09-14 23:41 ` Marek Behún
2020-09-15 11:04 ` kernel test robot
1 sibling, 1 reply; 4+ messages in thread
From: Marek Behún @ 2020-09-14 23:41 UTC (permalink / raw)
To: linux-leds
Cc: Pavel Machek, Dan Murphy, Ondřej Jirman, Russell King,
Andrew Lunn, linux-kernel, Matthias Schiffer, Marek Behún,
Rob Herring, devicetree
Allow setting netdev LED trigger as default when given LED DT node has
the `trigger-sources` property pointing to a node corresponding to a
network device.
The specific netdev trigger mode is determined from the `function` LED
property.
Example:
eth0: ethernet@30000 {
compatible = "xyz";
#trigger-source-cells = <0>;
};
led {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_LINK;
trigger-sources = <ð0>;
};
Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
---
drivers/leds/trigger/ledtrig-netdev.c | 91 ++++++++++++++++++++++++++-
include/dt-bindings/leds/common.h | 1 +
2 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index d5e774d830215..c6dce28dc52ed 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/netdevice.h>
+#include <linux/of_net.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include "../leds.h"
@@ -389,6 +390,81 @@ static void netdev_trig_work(struct work_struct *work)
(atomic_read(&trigger_data->interval)*2));
}
+static bool netdev_trig_of_parse(struct led_classdev *led_cdev,
+ struct led_netdev_data *trigger_data)
+{
+ struct of_phandle_args args;
+ struct net_device *netdev;
+ struct device_node *np;
+ const char *function;
+ unsigned long mode;
+ int count, err;
+
+ np = dev_of_node(led_cdev->dev);
+ if (!np)
+ return -EOPNOTSUPP;
+
+ count = of_count_phandle_with_args(np, "trigger-sources",
+ "#trigger-source-cells");
+ if (count == -ENOENT) {
+ return false;
+ } else if (count < 0) {
+ dev_warn(led_cdev->dev,
+ "Failed parsing trigger sources for %pOF!\n", np);
+ return false;
+ }
+
+ /* netdev trigger can have only one source */
+ if (count != 1)
+ return false;
+
+ err = of_parse_phandle_with_args(np, "trigger-sources",
+ "#trigger-source-cells", 0, &args);
+ if (err)
+ return false;
+
+ netdev = of_find_net_device_by_node(args.np);
+ if (!netdev)
+ return false;
+
+ err = of_property_read_string(np, "function", &function);
+ if (err && err != -ENOENT) {
+ dev_warn(led_cdev->dev, "Failed parsing function for %pOF!\n",
+ np);
+ return false;
+ } else if (err == -ENOENT) {
+ /* default function is link */
+ function = LED_FUNCTION_LINK;
+ }
+
+ mode = 0;
+ if (!strcmp(function, LED_FUNCTION_LINK)) {
+ set_bit(NETDEV_LED_LINK, &mode);
+ } else if (!strcmp(function, LED_FUNCTION_ACTIVITY)) {
+ set_bit(NETDEV_LED_TX, &mode);
+ set_bit(NETDEV_LED_RX, &mode);
+ } else if (!strcmp(function, LED_FUNCTION_RX)) {
+ set_bit(NETDEV_LED_RX, &mode);
+ } else if (!strcmp(function, LED_FUNCTION_TX)) {
+ set_bit(NETDEV_LED_TX, &mode);
+ } else {
+ dev_dbg(led_cdev->dev,
+ "Unsupported netdev trigger function for %pOF!\n", np);
+ return false;
+ }
+
+ if (trigger_data) {
+ dev_hold(netdev);
+ trigger_data->net_dev = netdev;
+ memcpy(trigger_data->device_name, netdev->name, IFNAMSIZ);
+ trigger_data->mode = mode;
+ if (netif_carrier_ok(netdev))
+ set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+ }
+
+ return true;
+}
+
static int netdev_trig_activate(struct led_classdev *led_cdev)
{
struct led_netdev_data *trigger_data;
@@ -414,10 +490,17 @@ static int netdev_trig_activate(struct led_classdev *led_cdev)
trigger_data->last_activity = 0;
led_set_trigger_data(led_cdev, trigger_data);
+ netdev_trig_of_parse(led_cdev, trigger_data);
rc = register_netdevice_notifier(&trigger_data->notifier);
- if (rc)
+ if (rc) {
+ if (trigger_data->net_dev)
+ dev_put(trigger_data->net_dev);
kfree(trigger_data);
+ } else {
+ if (trigger_data->net_dev)
+ set_baseline_state(trigger_data);
+ }
return rc;
}
@@ -436,10 +519,16 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev)
kfree(trigger_data);
}
+static bool netdev_trig_has_valid_source(struct led_classdev *led_cdev)
+{
+ return netdev_trig_of_parse(led_cdev, NULL);
+}
+
static struct led_trigger netdev_led_trigger = {
.name = "netdev",
.activate = netdev_trig_activate,
.deactivate = netdev_trig_deactivate,
+ .has_valid_source = netdev_trig_has_valid_source,
.groups = netdev_trig_groups,
};
diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h
index 52b619d44ba25..c7f9d34d60206 100644
--- a/include/dt-bindings/leds/common.h
+++ b/include/dt-bindings/leds/common.h
@@ -77,6 +77,7 @@
#define LED_FUNCTION_HEARTBEAT "heartbeat"
#define LED_FUNCTION_INDICATOR "indicator"
#define LED_FUNCTION_LAN "lan"
+#define LED_FUNCTION_LINK "link"
#define LED_FUNCTION_MAIL "mail"
#define LED_FUNCTION_MTD "mtd"
#define LED_FUNCTION_PANIC "panic"
--
2.26.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH leds + devicetree v1 2/2] leds: trigger: netdev: allow parsing `trigger-sources` from device tree
2020-09-14 23:41 ` [PATCH leds + devicetree v1 2/2] leds: trigger: netdev: allow parsing `trigger-sources` from device tree Marek Behún
@ 2020-09-15 11:04 ` kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2020-09-15 11:04 UTC (permalink / raw)
To: Marek Behún, linux-leds
Cc: kbuild-all, clang-built-linux, Pavel Machek, Dan Murphy,
Ondřej Jirman, Russell King, Andrew Lunn, linux-kernel,
Matthias Schiffer, Marek Behún, Rob Herring
[-- Attachment #1: Type: text/plain, Size: 5695 bytes --]
Hi "Marek,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on pavel-linux-leds/for-next]
[also build test ERROR on robh/for-next linus/master v5.9-rc5 next-20200915]
[cannot apply to linux/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Marek-Beh-n/Parse-DT-property-trigger-sources-for-netdev-LED-trigger/20200915-074253
base: git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git for-next
config: x86_64-randconfig-a016-20200914 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 3ed89b51da38f081fedb57727076262abb81d149)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> drivers/leds/trigger/ledtrig-netdev.c:396:25: error: variable has incomplete type 'struct of_phandle_args'
struct of_phandle_args args;
^
drivers/leds/trigger/ledtrig-netdev.c:396:9: note: forward declaration of 'struct of_phandle_args'
struct of_phandle_args args;
^
>> drivers/leds/trigger/ledtrig-netdev.c:407:10: error: implicit declaration of function 'of_count_phandle_with_args' [-Werror,-Wimplicit-function-declaration]
count = of_count_phandle_with_args(np, "trigger-sources",
^
>> drivers/leds/trigger/ledtrig-netdev.c:421:8: error: implicit declaration of function 'of_parse_phandle_with_args' [-Werror,-Wimplicit-function-declaration]
err = of_parse_phandle_with_args(np, "trigger-sources",
^
drivers/leds/trigger/ledtrig-netdev.c:421:8: note: did you mean 'of_count_phandle_with_args'?
drivers/leds/trigger/ledtrig-netdev.c:407:10: note: 'of_count_phandle_with_args' declared here
count = of_count_phandle_with_args(np, "trigger-sources",
^
>> drivers/leds/trigger/ledtrig-netdev.c:430:8: error: implicit declaration of function 'of_property_read_string' [-Werror,-Wimplicit-function-declaration]
err = of_property_read_string(np, "function", &function);
^
4 errors generated.
# https://github.com/0day-ci/linux/commit/2055fc3b24bb72ea2569a866ccfb1ee840e0d385
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Marek-Beh-n/Parse-DT-property-trigger-sources-for-netdev-LED-trigger/20200915-074253
git checkout 2055fc3b24bb72ea2569a866ccfb1ee840e0d385
vim +396 drivers/leds/trigger/ledtrig-netdev.c
392
393 static bool netdev_trig_of_parse(struct led_classdev *led_cdev,
394 struct led_netdev_data *trigger_data)
395 {
> 396 struct of_phandle_args args;
397 struct net_device *netdev;
398 struct device_node *np;
399 const char *function;
400 unsigned long mode;
401 int count, err;
402
403 np = dev_of_node(led_cdev->dev);
404 if (!np)
405 return -EOPNOTSUPP;
406
> 407 count = of_count_phandle_with_args(np, "trigger-sources",
408 "#trigger-source-cells");
409 if (count == -ENOENT) {
410 return false;
411 } else if (count < 0) {
412 dev_warn(led_cdev->dev,
413 "Failed parsing trigger sources for %pOF!\n", np);
414 return false;
415 }
416
417 /* netdev trigger can have only one source */
418 if (count != 1)
419 return false;
420
> 421 err = of_parse_phandle_with_args(np, "trigger-sources",
422 "#trigger-source-cells", 0, &args);
423 if (err)
424 return false;
425
426 netdev = of_find_net_device_by_node(args.np);
427 if (!netdev)
428 return false;
429
> 430 err = of_property_read_string(np, "function", &function);
431 if (err && err != -ENOENT) {
432 dev_warn(led_cdev->dev, "Failed parsing function for %pOF!\n",
433 np);
434 return false;
435 } else if (err == -ENOENT) {
436 /* default function is link */
437 function = LED_FUNCTION_LINK;
438 }
439
440 mode = 0;
441 if (!strcmp(function, LED_FUNCTION_LINK)) {
442 set_bit(NETDEV_LED_LINK, &mode);
443 } else if (!strcmp(function, LED_FUNCTION_ACTIVITY)) {
444 set_bit(NETDEV_LED_TX, &mode);
445 set_bit(NETDEV_LED_RX, &mode);
446 } else if (!strcmp(function, LED_FUNCTION_RX)) {
447 set_bit(NETDEV_LED_RX, &mode);
448 } else if (!strcmp(function, LED_FUNCTION_TX)) {
449 set_bit(NETDEV_LED_TX, &mode);
450 } else {
451 dev_dbg(led_cdev->dev,
452 "Unsupported netdev trigger function for %pOF!\n", np);
453 return false;
454 }
455
456 if (trigger_data) {
457 dev_hold(netdev);
458 trigger_data->net_dev = netdev;
459 memcpy(trigger_data->device_name, netdev->name, IFNAMSIZ);
460 trigger_data->mode = mode;
461 if (netif_carrier_ok(netdev))
462 set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
463 }
464
465 return true;
466 }
467
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 37437 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-09-15 11:11 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-14 23:41 [PATCH leds + devicetree v1 0/2] Parse DT property `trigger-sources` for netdev LED trigger Marek Behún
2020-09-14 23:41 ` [PATCH leds + devicetree v1 1/2] leds: trigger: add DT `trigger-sources` validating method Marek Behún
2020-09-14 23:41 ` [PATCH leds + devicetree v1 2/2] leds: trigger: netdev: allow parsing `trigger-sources` from device tree Marek Behún
2020-09-15 11:04 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).