Message ID | 20200914234148.19837-3-marek.behun@nic.cz |
---|---|
State | New |
Headers | show |
Series | None | expand |
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
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"
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(-)