From patchwork Tue May 3 15:16:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 569170 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80E37C433F5 for ; Tue, 3 May 2022 15:18:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238114AbiECPVx (ORCPT ); Tue, 3 May 2022 11:21:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238104AbiECPVv (ORCPT ); Tue, 3 May 2022 11:21:51 -0400 Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [IPv6:2a00:1450:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EE6C3A707; Tue, 3 May 2022 08:18:17 -0700 (PDT) Received: by mail-ej1-x62f.google.com with SMTP id l7so34135150ejn.2; Tue, 03 May 2022 08:18:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YD8HL+QQXXNygErRS0QTa/lYoHOoQ4QJTCFR4YQ1N8I=; b=TTYXsoGmEhS1qQTso+FAAjkTHFgF6JcUqZfrUvYpFQ01dyCmFaXHDoCiny4YkEQ0jr s//mmeL7G0I5GFf0vxAi5v6Xnfcg08003c6Evdoauxc/XFC2/n89iVpJ8LDLiyXcDuVt YkzW1SDLNv2BBVUOzrT+/UHauf0r6dky7pUpaM6FGnCOjd69JzmXSupgSTfWGBb6vHkx Yn4ND+IZHBpLgRIEOt9LvnVl+vom442y3ycD9oqRe380s4F3+6BLEeHe08uAH2zSS/aL dQPw8tNxL4Z1IH8fhwYj9dOzwghQ6K3nlZYkyvZO07TIR8oGbJQsC8Lf+8awD2IWGEWw Y2Yg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YD8HL+QQXXNygErRS0QTa/lYoHOoQ4QJTCFR4YQ1N8I=; b=aDFMyL8bvAMGNCJ9TBUIXS2SFwIY953UiB7g2gA9DAoEe1ID+3OmSn9UEZYanIQhIr rrk3481gfmnV/geVOosnuV/u2X3m2KH6kMLmkaBHcGP++GDGzMAeBe4ZP3XaRUiopv+Z 5roM2GKu11E9dS/Hn3unEPwSdtTHxC9KeWSwabJs699DYpLmncIaeX5cWY91pKEhun7G 4+oSiFlfZCE0cs38QcRXnB1KO44o9tRQicA58WSsZynq/CgTis4KzOIz/wUcLou2vt8d akYbbmvhPUoNS/K9kyZwVaB+vqXHsFPgf5JYOG6Ax8WqZ3AHpqBev65sHkhdlnAtCOee +i9g== X-Gm-Message-State: AOAM533vyYJaefRtKzYJdUF1ypdNZmyjnUAjAl0a5njaCjHDrktrqw+h i4oEQA58a7aqm3vmGXtI+6A= X-Google-Smtp-Source: ABdhPJwA2xn6DxGEBOGePH9Byz9P2IcABI2GcFUx9Fhj8oPtqtxcA3X5rR1lzR4QUXPmFTFz2mfPVQ== X-Received: by 2002:a17:907:97cf:b0:6df:846f:ad0a with SMTP id js15-20020a17090797cf00b006df846fad0amr16000853ejc.286.1651591095745; Tue, 03 May 2022 08:18:15 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:14 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Cc: =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [RFC PATCH v6 01/11] leds: add support for hardware driven LEDs Date: Tue, 3 May 2022 17:16:23 +0200 Message-Id: <20220503151633.18760-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Some LEDs can be driven by hardware (for example a LED connected to an ethernet PHY or an ethernet switch can be configured to blink on activity on the network, which in software is done by the netdev trigger). To do such offloading, LED driver must support this and a supported trigger must be used. LED driver should declare the correct blink_mode supported and should set the blink_mode parameter to one of HARDWARE_CONTROLLED or SOFTWARE_HARDWARE_CONTROLLED. The trigger will check this option and fail to activate if the blink_mode is not supported. By default if a LED driver doesn't declare blink_mode, SOFTWARE_CONTROLLED is assumed. The LED must implement 3 main API: - trigger_offload_status(): This asks the LED driver if offload mode is enabled or not. Triggers will check if the offload mode is supported and will be activated accordingly. If the trigger can't run in software mode, return -EOPNOTSUPP as the blinking can't be simulated by software. - trigger_offload_start(): This will simply enable the offload mode for the LED. With this not declared and trigger_offload_status() returning true, it's assumed that the LED is always in offload mode. - trigger_offload_stop(): This will simply disable the offload mode for the LED. With this not declared and trigger_offload_status() returning true, it's assumed that the LED is always in offload mode. It's advised to the driver to put the LED in the old state but this is not enforcerd and putting the LED off is also accepted. With HARDWARE_CONTROLLED blink_mode trigger_offload_status/start/stop is optional and any software only trigger will reject activation as the LED supports only hardware mode. An additional config CONFIG_LEDS_HARDWARE_CONTROL is added to add support for LEDs that can be controlled by hardware. Cc: Marek BehĂșn Signed-off-by: Ansuel Smith --- Documentation/leds/leds-class.rst | 28 ++++++++++++++++++ drivers/leds/Kconfig | 11 ++++++++ drivers/leds/led-class.c | 27 ++++++++++++++++++ drivers/leds/led-triggers.c | 29 +++++++++++++++++++ include/linux/leds.h | 47 ++++++++++++++++++++++++++++++- 5 files changed, 141 insertions(+), 1 deletion(-) diff --git a/Documentation/leds/leds-class.rst b/Documentation/leds/leds-class.rst index cd155ead8703..645940b78d81 100644 --- a/Documentation/leds/leds-class.rst +++ b/Documentation/leds/leds-class.rst @@ -169,6 +169,34 @@ Setting the brightness to zero with brightness_set() callback function should completely turn off the LED and cancel the previously programmed hardware blinking function, if any. +Hardware driven LEDs +=================================== + +Some LEDs can be driven by hardware (for example a LED connected to +an ethernet PHY or an ethernet switch can be configured to blink on activity on +the network, which in software is done by the netdev trigger). + +To do such offloading, LED driver must support this and a supported trigger must +be used. + +LED driver should declare the correct blink_mode supported and should set the +blink_mode parameter to one of HARDWARE_CONTROLLED or SOFTWARE_HARDWARE_CONTROLLED. +The trigger will check this option and fail to activate if the blink_mode is not +supported. By default if a LED driver doesn't declare blink_mode, SOFTWARE_CONTROLLED +is assumed. + +The LED must implement 3 main API: +- hw_control_status(): This asks the LED driver if hardware mode is enabled + or not. Triggers will check if the hardware mode is active and will try + to offload their triggers if supported by the driver. +- hw_control_start(): This will simply enable the hardware mode for the LED. +- hw_control_stop(): This will simply disable the hardware mode for the LED. + It's advised to the driver to put the LED in the old state but this is not + enforcerd and putting the LED off is also accepted. + +With HARDWARE_CONTROLLED blink_mode hw_control_status/start/stop is optional +and any software only trigger will reject activation as the LED supports only +hardware mode. Known Issues ============ diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 6090e647daee..965aa8ba5164 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -49,6 +49,17 @@ config LEDS_BRIGHTNESS_HW_CHANGED See Documentation/ABI/testing/sysfs-class-led for details. +config LEDS_HARDWARE_CONTROL + bool "LED Hardware Control support" + help + This option enabled Hardware control support used by leds that + can be driven in hardware by using supported triggers. + + Hardware blink modes will be exposed by sysfs class in + /sys/class/leds based on the trigger currently active. + + If unsure, say Y. + comment "LED drivers" config LEDS_88PM860X diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 6a8ea94834fa..3516ae3c4c3c 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -164,6 +164,27 @@ static void led_remove_brightness_hw_changed(struct led_classdev *led_cdev) } #endif +#ifdef CONFIG_LEDS_HARDWARE_CONTROL +static int led_classdev_check_blink_mode_functions(struct led_classdev *led_cdev) +{ + int mode = led_cdev->blink_mode; + + if (mode == SOFTWARE_HARDWARE_CONTROLLED && + (!led_cdev->hw_control_status || + !led_cdev->hw_control_start || + !led_cdev->hw_control_stop)) + return -EINVAL; + + if (mode == SOFTWARE_CONTROLLED && + (led_cdev->hw_control_status || + led_cdev->hw_control_start || + led_cdev->hw_control_stop)) + return -EINVAL; + + return 0; +} +#endif + /** * led_classdev_suspend - suspend an led_classdev. * @led_cdev: the led_classdev to suspend. @@ -367,6 +388,12 @@ int led_classdev_register_ext(struct device *parent, if (ret < 0) return ret; +#ifdef CONFIG_LEDS_HARDWARE_CONTROL + ret = led_classdev_check_blink_mode_functions(led_cdev); + if (ret < 0) + return ret; +#endif + mutex_init(&led_cdev->led_access); mutex_lock(&led_cdev->led_access); led_cdev->dev = device_create_with_groups(leds_class, parent, 0, diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 072491d3e17b..693c5d0fa980 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -154,6 +154,27 @@ ssize_t led_trigger_read(struct file *filp, struct kobject *kobj, } EXPORT_SYMBOL_GPL(led_trigger_read); +static bool led_trigger_is_supported(struct led_classdev *led_cdev, + struct led_trigger *trigger) +{ + switch (led_cdev->blink_mode) { + case SOFTWARE_CONTROLLED: + if (trigger->supported_blink_modes == HARDWARE_ONLY) + return 0; + break; + case HARDWARE_CONTROLLED: + if (trigger->supported_blink_modes == SOFTWARE_ONLY) + return 0; + break; + case SOFTWARE_HARDWARE_CONTROLLED: + break; + default: + return 0; + } + + return 1; +} + /* Caller must ensure led_cdev->trigger_lock held */ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) { @@ -179,6 +200,10 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) cancel_work_sync(&led_cdev->set_brightness_work); led_stop_software_blink(led_cdev); + /* Disable hardware mode on trigger change if supported */ + if (led_cdev->blink_mode != SOFTWARE_CONTROLLED && + led_cdev->hw_control_status(led_cdev)) + led_cdev->hw_control_stop(led_cdev); if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); @@ -188,6 +213,10 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) led_set_brightness(led_cdev, LED_OFF); } if (trig) { + /* Make sure the trigger support the LED blink mode */ + if (!led_trigger_is_supported(led_cdev, trig)) + return -EINVAL; + spin_lock(&trig->leddev_list_lock); list_add_tail_rcu(&led_cdev->trig_list, &trig->led_cdevs); spin_unlock(&trig->leddev_list_lock); diff --git a/include/linux/leds.h b/include/linux/leds.h index ba4861ec73d3..09ff1dc6f48d 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -67,6 +67,12 @@ struct led_hw_trigger_type { int dummy; }; +enum led_blink_modes { + SOFTWARE_CONTROLLED = 0x0, + HARDWARE_CONTROLLED, + SOFTWARE_HARDWARE_CONTROLLED, +}; + struct led_classdev { const char *name; unsigned int brightness; @@ -154,6 +160,32 @@ struct led_classdev { /* LEDs that have private triggers have this set */ struct led_hw_trigger_type *trigger_type; + + /* This report the supported blink_mode. The driver should report the + * correct LED capabilities. + * With this set to HARDWARE_CONTROLLED, LED is always in offload mode + * and triggers can't be simulated by software. + * If the led is HARDWARE_CONTROLLED, status/start/stop function + * are optional. + * By default SOFTWARE_CONTROLLED is set as blink_mode. + */ + enum led_blink_modes blink_mode; +#ifdef CONFIG_LEDS_HARDWARE_CONTROL + /* Ask the LED driver if hardware mode is enabled or not. + * If the option is not declared by the LED driver, SOFTWARE_CONTROLLED + * is assumed. + * Triggers will check if the hardware mode is supported and will be + * activated accordingly. If the trigger can't run in hardware mode, + * return -EOPNOTSUPP as the blinking can't be simulated by software. + */ + bool (*hw_control_status)(struct led_classdev *led_cdev); + /* Set LED in hardware mode */ + int (*hw_control_start)(struct led_classdev *led_cdev); + /* Disable hardware mode for LED. It's advised to the LED driver to put it to + * the old status but that is not mandatory and also putting it off is accepted. + */ + int (*hw_control_stop)(struct led_classdev *led_cdev); +#endif #endif #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED @@ -215,7 +247,6 @@ extern struct led_classdev *of_led_get(struct device_node *np, int index); extern void led_put(struct led_classdev *led_cdev); struct led_classdev *__must_check devm_of_led_get(struct device *dev, int index); - /** * led_blink_set - set blinking with software fallback * @led_cdev: the LED to start blinking @@ -350,12 +381,26 @@ static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev) #define TRIG_NAME_MAX 50 +enum led_trigger_blink_supported_modes { + SOFTWARE_ONLY = SOFTWARE_CONTROLLED, + HARDWARE_ONLY = HARDWARE_CONTROLLED, + SOFTWARE_HARDWARE = SOFTWARE_HARDWARE_CONTROLLED, +}; + struct led_trigger { /* Trigger Properties */ const char *name; int (*activate)(struct led_classdev *led_cdev); void (*deactivate)(struct led_classdev *led_cdev); + /* Declare if the Trigger supports hardware control to + * offload triggers or supports only software control. + * A trigger can also declare support for hardware control + * if its task is to only configure LED blink modes and expose + * them in sysfs. + */ + enum led_trigger_blink_supported_modes supported_blink_modes; + /* LED-private triggers have this set */ struct led_hw_trigger_type *trigger_type; From patchwork Tue May 3 15:16:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 570645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95554C43217 for ; Tue, 3 May 2022 15:18:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238129AbiECPVz (ORCPT ); Tue, 3 May 2022 11:21:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238106AbiECPVv (ORCPT ); Tue, 3 May 2022 11:21:51 -0400 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3B793A5D1; Tue, 3 May 2022 08:18:18 -0700 (PDT) Received: by mail-ej1-x62d.google.com with SMTP id dk23so34087352ejb.8; Tue, 03 May 2022 08:18:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=0NJOjZivHdsEAPSUPe4gZceqMCkKHdM1DQMNmyoIcXA=; b=lfIR5fLXlCnaezJxzcYNVgw8KrAyPD9Rs95FJN8IAch5pJH73kVTI8QMl0OFIAG5eB 2QOY4FbqZYlGQoBriUwsUqKV19PUWUOncdOcFeI373Rbw2E93tzf3Wb1jhYCwT8r9FwW eb3aM6Ff+HB62d97wskvIgADClW8JOL+7Qc1ThLH25VyJgCCHPCEz7b+CbPpognNyTrJ Z6TfaNKG6k9SVdKEhPzWaO+/zuFvZuqSzZ/1Uh45GedEP360SmodEiMDgnoWV9JbaVAW Lb2wN/FFlMXmEkmXZriE/u8v7VeLHSX2X25AOmMLI4RXMLSu+Z569TgAALBnqqt/BKhW COFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0NJOjZivHdsEAPSUPe4gZceqMCkKHdM1DQMNmyoIcXA=; b=bJuklK09TnE3KTyahHV2wHgkapoJu2lvb/Qm8hKncdD5zr8iTZjRDLx7Jx9VR6802F 6T7iV5VcdZh4uZYTZOhuoilDBPdj3g34yHoBebC5Yxk9rWOi4+yzR2cL5j7XZMLYw0fQ zFSc9xDDRcVE08+lVVFt7B3BYaP452Oi/OPp9N7bUAjK7OGYBV7uurEABQgC4BbyeCby pTDP6Rjp5dp5Fuzy3YZa5ipJezj3tSszm1wXkCxJYBGZe1pYzNNXHcQ5M62RPRWzjoLy K0LcW+c6eL+Qoy22Hwnl4eo0FbILlp6T5qv4gOLZveqgJ/H0uZErw23+befGjXopRbtL O1KQ== X-Gm-Message-State: AOAM532DrjjnbgDt8WWuuyhp7hSJQkR+7BaJflRT+T7+P3kqHuTTIR3+ NK6UlbKOSQGN94B3IRndvPs= X-Google-Smtp-Source: ABdhPJw0y+mKwrYFwFmEnp90BLS+xK7XuBP6Wk4nRuznWG7ZLwCvFq6kCAznYEL5zV8bquR/WYG5yQ== X-Received: by 2002:a17:907:2ce3:b0:6f3:a4c4:100a with SMTP id hz3-20020a1709072ce300b006f3a4c4100amr16031507ejc.218.1651591097142; Tue, 03 May 2022 08:18:17 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:16 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 02/11] leds: add function to configure hardware controlled LED Date: Tue, 3 May 2022 17:16:24 +0200 Message-Id: <20220503151633.18760-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add hw_control_configure helper to configure how the LED should work in hardware mode. The function require to support the particular trigger and will use the passed flag to elaborate the data and apply the correct configuration. This function will then be used by the trigger to request and update hardware configuration. Signed-off-by: Ansuel Smith --- Documentation/leds/leds-class.rst | 25 ++++++++++++++++++++ include/linux/leds.h | 39 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/Documentation/leds/leds-class.rst b/Documentation/leds/leds-class.rst index 645940b78d81..efd2f68c46a7 100644 --- a/Documentation/leds/leds-class.rst +++ b/Documentation/leds/leds-class.rst @@ -198,6 +198,31 @@ With HARDWARE_CONTROLLED blink_mode hw_control_status/start/stop is optional and any software only trigger will reject activation as the LED supports only hardware mode. +A trigger once he declared support for hardware controlled blinks, will use the function +hw_control_configure() provided by the driver to check support for a particular blink mode. +This function passes as the first argument (flag) a u32 flag. +The second argument (cmd) of hw_control_configure() method can be used to do various +operations for the specific blink mode. We currently support ENABLE, DISABLE, READ, ZERO +and SUPPORTED to enable, disable, read the state of the blink mode, ask the LED +driver if it does supports the specific blink mode and to reset any blink mode active. + +In ENABLE/DISABLE hw_control_configure() should configure the LED to enable/disable the +requested blink mode (flag). +In READ hw_control_configure() should return 0 or 1 based on the status of the requested +blink mode (flag). +In SUPPORTED hw_control_configure() should return 0 or 1 if the LED driver supports the +requested blink mode (flags) or not. +In ZERO hw_control_configure() should return 0 with success operation or error. + +The unsigned long flag is specific to the trigger and change across them. It's in the LED +driver interest know how to elaborate this flag and to declare support for a +particular trigger. For this exact reason explicit support for the specific +trigger is mandatory or the driver returns -EOPNOTSUPP if asked to enter offload mode +with a not supported trigger. +If the driver returns -EOPNOTSUPP on hw_control_configure(), the trigger activation will +fail as the driver doesn't support that specific offload trigger or doesn't know +how to handle the provided flags. + Known Issues ============ diff --git a/include/linux/leds.h b/include/linux/leds.h index 09ff1dc6f48d..b5aad67fecfb 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -73,6 +73,16 @@ enum led_blink_modes { SOFTWARE_HARDWARE_CONTROLLED, }; +#ifdef CONFIG_LEDS_HARDWARE_CONTROL +enum blink_mode_cmd { + BLINK_MODE_ENABLE, /* Enable the hardware blink mode */ + BLINK_MODE_DISABLE, /* Disable the hardware blink mode */ + BLINK_MODE_READ, /* Read the status of the hardware blink mode */ + BLINK_MODE_SUPPORTED, /* Ask the driver if the hardware blink mode is supported */ + BLINK_MODE_ZERO, /* Disable any hardware blink active */ +}; +#endif + struct led_classdev { const char *name; unsigned int brightness; @@ -185,6 +195,17 @@ struct led_classdev { * the old status but that is not mandatory and also putting it off is accepted. */ int (*hw_control_stop)(struct led_classdev *led_cdev); + /* This will be used to configure the various blink modes LED support in hardware + * mode. + * The LED driver require to support the active trigger and will elaborate the + * unsigned long flag and do the operation based on the provided cmd. + * Current operation are enable,disable,supported and status. + * A trigger will use this to enable or disable the asked blink mode, check the + * status of the blink mode or ask if the blink mode can run in hardware mode. + */ + int (*hw_control_configure)(struct led_classdev *led_cdev, + unsigned long flag, + enum blink_mode_cmd cmd); #endif #endif @@ -454,6 +475,24 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) return led_cdev->trigger_data; } +#ifdef CONFIG_LEDS_HARDWARE_CONTROL +static inline bool led_trigger_blink_mode_is_supported(struct led_classdev *led_cdev, + unsigned long flag) +{ + int ret; + + /* Sanity check: make sure led support hw mode */ + if (led_cdev->blink_mode == SOFTWARE_CONTROLLED) + return false; + + ret = led_cdev->hw_control_configure(led_cdev, flag, BLINK_MODE_SUPPORTED); + if (ret > 0) + return true; + + return false; +} +#endif + /** * led_trigger_rename_static - rename a trigger * @name: the new trigger name From patchwork Tue May 3 15:16:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 570644 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C2D9C433F5 for ; Tue, 3 May 2022 15:18:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238171AbiECPWH (ORCPT ); Tue, 3 May 2022 11:22:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238111AbiECPVx (ORCPT ); Tue, 3 May 2022 11:21:53 -0400 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1C72B3A5D1; Tue, 3 May 2022 08:18:20 -0700 (PDT) Received: by mail-ed1-x52d.google.com with SMTP id g20so20216732edw.6; Tue, 03 May 2022 08:18:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=z8UQ0gwVo42S8MFd7E26z2Xx0d1KX8rCgVDlpW4ge0U=; b=I15PSPUtz97s9sbyUeXPtBKIvBTxCVYMz3hilzJiVMtt9pAjOemVHYQ8Uis0XtxfOT TN8W9PnnD29qFCawu3etc/tM2JeNRofYFyqtdEtK9Kikn+90FV0gdxlkInUFheBLagE7 nvYR3EygB0DclsZmbC+JfPoF07juG9YKo+EgIRF19zudPBsg4VOnr6F2cVF/Hsgxzs50 cMlurb7UAGobryt3LOLpepKlrz8Id6Pi3kr8ZDe0MwzBI71q7t5mfKhyvRJ56WxtJH0L mBIh7q/Wd95tSrP0nHc4lfE3Hklm1jdbRBd6r5k+sjlAde0MvSXMxxeL7HaR92QIqv2D 1skg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=z8UQ0gwVo42S8MFd7E26z2Xx0d1KX8rCgVDlpW4ge0U=; b=kWXVe5WTzVn96ePfmryFLiz+mn+OoTG1ykd8iCHeN2E138mdGOp8/9pElgzDUrVA7g rXVFdEBE/3MXEVBGA6r3ExAafo0zG25B/n7dq85cYLNZw/3dcJqzhiVj2W+n2ZoNBYt3 ltB1ba2sKDQq0RdA7Hd0sNqisV+8BXqTSLmQkHm4ZSOGXcuXS1nB6R21vWdPCGxZQBch IpPyB627CxxkriobEMUsMvTnVEpUTrL0i5YLz5DetegIlo+owIgl1eo81acEvMmXyY59 tmFEpimjC9uM7rHj/U0S59N59s9u7xtvjj9J4yzjo+ozqYq3pT5jrHgGGg3Gkspebw/8 HWow== X-Gm-Message-State: AOAM5318fOiUl8g5gzV5LKjHXDhD9ZWK0kF9QDMP07dOH50Tiacamgc/ xbM++S20SRoz9Gtazola2Ng= X-Google-Smtp-Source: ABdhPJw8PYctsl15p4W9Mjn4kajId/tHVHaGiczNq0Ue9zw8EBCPNN4e2YoBTjoG/vc7j1Q7uWlm9A== X-Received: by 2002:a05:6402:2204:b0:426:34f1:1d2d with SMTP id cq4-20020a056402220400b0042634f11d2dmr18401032edb.335.1651591098520; Tue, 03 May 2022 08:18:18 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:18 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 03/11] leds: trigger: netdev: drop NETDEV_LED_MODE_LINKUP from mode Date: Tue, 3 May 2022 17:16:25 +0200 Message-Id: <20220503151633.18760-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool that will be true or false based on the carrier link. No functional change intended. Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index d5e774d83021..66a81cc9b64d 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -50,10 +50,10 @@ struct led_netdev_data { unsigned int last_activity; unsigned long mode; + bool carrier_link_up; #define NETDEV_LED_LINK 0 #define NETDEV_LED_TX 1 #define NETDEV_LED_RX 2 -#define NETDEV_LED_MODE_LINKUP 3 }; enum netdev_led_attr { @@ -73,9 +73,9 @@ static void set_baseline_state(struct led_netdev_data *trigger_data) if (!led_cdev->blink_brightness) led_cdev->blink_brightness = led_cdev->max_brightness; - if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) + if (!trigger_data->carrier_link_up) { led_set_brightness(led_cdev, LED_OFF); - else { + } else { if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) led_set_brightness(led_cdev, led_cdev->blink_brightness); @@ -131,10 +131,9 @@ static ssize_t device_name_store(struct device *dev, trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name); - clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); + trigger_data->carrier_link_up = false; if (trigger_data->net_dev != NULL) - if (netif_carrier_ok(trigger_data->net_dev)) - set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); + trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); trigger_data->last_activity = 0; @@ -315,7 +314,7 @@ static int netdev_trig_notify(struct notifier_block *nb, spin_lock_bh(&trigger_data->lock); - clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); + trigger_data->carrier_link_up = false; switch (evt) { case NETDEV_CHANGENAME: case NETDEV_REGISTER: @@ -330,8 +329,7 @@ static int netdev_trig_notify(struct notifier_block *nb, break; case NETDEV_UP: case NETDEV_CHANGE: - if (netif_carrier_ok(dev)) - set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); + trigger_data->carrier_link_up = netif_carrier_ok(dev); break; } From patchwork Tue May 3 15:16:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 569169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BF192C43219 for ; Tue, 3 May 2022 15:18:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238175AbiECPWH (ORCPT ); Tue, 3 May 2022 11:22:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238118AbiECPVy (ORCPT ); Tue, 3 May 2022 11:21:54 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59E6C3AA5F; Tue, 3 May 2022 08:18:21 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id l18so34050820ejc.7; Tue, 03 May 2022 08:18:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=YkFrQ4/wi+cqyLXOlhLD4aOJANtZ19orl1Mof8QAy1Y=; b=lGGZDd9wSGMI1R1F9bB93M23m5dMXI46oaQiR62pm0dEOCTJQ5IPsD1vxO9d/emI2q 1KzXBJpqwHYWNKONDA+gsVQ+LP/pE9GBem/IGTFjdgMRgvoE3CjvM3D0Ap9XBvmgormi rvfpnNeeXQSQ2QFkfodCEEzlrbScfBnlE7W2Vy1t5V1yAdeqcj2kOgk8zc3o2Uz0+fMi 3xirS/sVKiWig9rnskwhrpQ0l7UHs8B0LqBHgpArha2mGq6WAfyRaQVlSXd+a4Yarj8g N4OxVhlAmLJeVQxy6p0RPYLB9pbcfCifrIa4kb+BGXlbJjrEJ/ToCJvBZkysE+41CltC HSGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YkFrQ4/wi+cqyLXOlhLD4aOJANtZ19orl1Mof8QAy1Y=; b=eVHla7FeAsup/MKpZkhUDYTGLoe4nWuus2Ffv8Ef5bbGF/seQhwYyd2vQPmBNza5PN wfMViapztqRTfuu1AMQsik3mD2hrhVFU3QAuMvUGbxwUM4nF6Rf4JClU3MhfGdLwr0gL DRDYvkF+Du4k/R5zp0LQlUzv2wlRWv0+DHIj57FQE2BzEDM9V39fXONky0btqY+dDzHK UFQ5uKgMy6ILQgxoRRqaMXU5UfWjLKeeomwxWpqKhmCDryP/+Zr73c7mHvL0xc7igukM 11plqU6330KHewYHoHrnrTfQvovMYAoHqVmBd0TAZRkqxOqT9xlvv3ETVyoNE6ntLEmW j2xw== X-Gm-Message-State: AOAM533u3+bSp/t372O9CAFsXej2E5hySddXfVej8a2vUTz544ul45AP jcQIGA00GWqmDwJiNFpdxDE= X-Google-Smtp-Source: ABdhPJzJs0qkledNmUPM0IohTua8MkFilLH+VBdbuPdbxSmAgFDeHm7Y+dwgF1ovBN670OAHoLZrZw== X-Received: by 2002:a17:906:b286:b0:6f3:b3e4:5f67 with SMTP id q6-20020a170906b28600b006f3b3e45f67mr16067213ejz.148.1651591099814; Tue, 03 May 2022 08:18:19 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:19 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 04/11] leds: trigger: netdev: rename and expose NETDEV trigger enum modes Date: Tue, 3 May 2022 17:16:26 +0200 Message-Id: <20220503151633.18760-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Rename NETDEV trigger enum modes to a more simbolic name and move them in leds.h to make them accessible by any user. Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 53 +++++++++------------------ include/linux/leds.h | 7 ++++ 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 66a81cc9b64d..6872da08676b 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -51,15 +51,6 @@ struct led_netdev_data { unsigned long mode; bool carrier_link_up; -#define NETDEV_LED_LINK 0 -#define NETDEV_LED_TX 1 -#define NETDEV_LED_RX 2 -}; - -enum netdev_led_attr { - NETDEV_ATTR_LINK, - NETDEV_ATTR_TX, - NETDEV_ATTR_RX }; static void set_baseline_state(struct led_netdev_data *trigger_data) @@ -76,7 +67,7 @@ static void set_baseline_state(struct led_netdev_data *trigger_data) if (!trigger_data->carrier_link_up) { led_set_brightness(led_cdev, LED_OFF); } else { - if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) + if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) led_set_brightness(led_cdev, led_cdev->blink_brightness); else @@ -85,8 +76,8 @@ static void set_baseline_state(struct led_netdev_data *trigger_data) /* If we are looking for RX/TX start periodically * checking stats */ - if (test_bit(NETDEV_LED_TX, &trigger_data->mode) || - test_bit(NETDEV_LED_RX, &trigger_data->mode)) + if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) || + test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) schedule_delayed_work(&trigger_data->work, 0); } } @@ -146,20 +137,16 @@ static ssize_t device_name_store(struct device *dev, static DEVICE_ATTR_RW(device_name); static ssize_t netdev_led_attr_show(struct device *dev, char *buf, - enum netdev_led_attr attr) + enum led_trigger_netdev_modes attr) { struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); int bit; switch (attr) { - case NETDEV_ATTR_LINK: - bit = NETDEV_LED_LINK; - break; - case NETDEV_ATTR_TX: - bit = NETDEV_LED_TX; - break; - case NETDEV_ATTR_RX: - bit = NETDEV_LED_RX; + case TRIGGER_NETDEV_LINK: + case TRIGGER_NETDEV_TX: + case TRIGGER_NETDEV_RX: + bit = attr; break; default: return -EINVAL; @@ -169,7 +156,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) + size_t size, enum led_trigger_netdev_modes attr) { struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); unsigned long state; @@ -181,14 +168,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, return ret; switch (attr) { - case NETDEV_ATTR_LINK: - bit = NETDEV_LED_LINK; - break; - case NETDEV_ATTR_TX: - bit = NETDEV_LED_TX; - break; - case NETDEV_ATTR_RX: - bit = NETDEV_LED_RX; + case TRIGGER_NETDEV_LINK: + case TRIGGER_NETDEV_TX: + case TRIGGER_NETDEV_RX: + bit = attr; break; default: return -EINVAL; @@ -358,21 +341,21 @@ static void netdev_trig_work(struct work_struct *work) } /* If we are not looking for RX/TX then return */ - if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) && - !test_bit(NETDEV_LED_RX, &trigger_data->mode)) + if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) && + !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) return; dev_stats = dev_get_stats(trigger_data->net_dev, &temp); new_activity = - (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? + (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ? dev_stats->tx_packets : 0) + - (test_bit(NETDEV_LED_RX, &trigger_data->mode) ? + (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ? dev_stats->rx_packets : 0); if (trigger_data->last_activity != new_activity) { led_stop_software_blink(trigger_data->led_cdev); - invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode); + invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); interval = jiffies_to_msecs( atomic_read(&trigger_data->interval)); /* base state is ON (link present) */ diff --git a/include/linux/leds.h b/include/linux/leds.h index b5aad67fecfb..13862f8b1e07 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -548,6 +548,13 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) #endif /* CONFIG_LEDS_TRIGGERS */ +/* Trigger specific enum */ +enum led_trigger_netdev_modes { + TRIGGER_NETDEV_LINK = 1, + TRIGGER_NETDEV_TX, + TRIGGER_NETDEV_RX, +}; + /* Trigger specific functions */ #ifdef CONFIG_LEDS_TRIGGER_DISK void ledtrig_disk_activity(bool write); From patchwork Tue May 3 15:16:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 570643 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B14B5C4167D for ; Tue, 3 May 2022 15:18:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238186AbiECPWK (ORCPT ); Tue, 3 May 2022 11:22:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238127AbiECPVz (ORCPT ); Tue, 3 May 2022 11:21:55 -0400 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B68223AA6C; Tue, 3 May 2022 08:18:22 -0700 (PDT) Received: by mail-ed1-x52f.google.com with SMTP id b24so20232982edu.10; Tue, 03 May 2022 08:18:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=vZu+dgzlKwppLB3egL+X7UEd+cjxbmEGUvyruw8gqlQ=; b=W6jUVBwWlR6/s9Tqy/8aDQnEZF+1Qw/bTsfTkGk/OCJ6UISFtZOWsm0WLfB6HOutcA wZsP5rCuwEArTcvj+KqPT84LsKegMo9r7mXBz18zn2uN4bLEKEtd17k8hyYkfrQtiCsE A/kbA4vG0AM2d41v/tyBVvToOsjBBbx58qXZn31PUJs+A/rakuB/hs9JGylDlzkUA+N7 9nyF0HPbH/vbuGZXlUGPzNM5UwBVPCKKStpJd+xL3Ey/bp9BYEb94ALlGDokeeijk8cg GhAUdoKlB9H2gclMKblqV0tmbx/LRjOwrjm0JH2XrIl4cAkJ8nUl29Dw7vNE5kT/Vpo8 Srng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vZu+dgzlKwppLB3egL+X7UEd+cjxbmEGUvyruw8gqlQ=; b=i4ZpOMaXfFhYe0qZiVQExU4WWWTqEfk6pOtrSE1XWaFB3MGNHwgfGg580bniTxAkRS sKHe+K8/rX8ffwq/nl8lNKuyA1Ogny5qsMYh4yFNxb+I6LNwO7hMu9vtyn/MpaGQ7FpK 2nM8BUHaX2uL09NMpwvTKSXKifBTBu9n0FWl09Aum/55ToB/grM76fFaHDqeOPgeWCYy +bHNZTpbtf4TWS940REFDOvg+02tXMCrGul/g9Ih9ln79ZiavozdkePdDLqnuaQed/DI tPZaIFTqcglOfK5R+gT1/AscWSUh+3h/VKX0KwhmVpmEki6krrgrL5ml1h3y/srVZpzY H2Mw== X-Gm-Message-State: AOAM533yE4oyI1IUYoBYTXjpc+QsJr+cES3EHt693MbrtBuQXXg1uJbe 8Wtt4d50aDUiQXLFDNVr3ec= X-Google-Smtp-Source: ABdhPJwHfusILH15MfLZeKkPb5tq2Grc5B4Y5QkVzE7S9wkdLcNfzJCCSNXZLbw24BRVN84FlcrRCw== X-Received: by 2002:a05:6402:1254:b0:426:2439:ceb7 with SMTP id l20-20020a056402125400b004262439ceb7mr18461553edw.47.1651591101100; Tue, 03 May 2022 08:18:21 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:20 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 05/11] leds: trigger: netdev: convert device attr to macro Date: Tue, 3 May 2022 17:16:27 +0200 Message-Id: <20220503151633.18760-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Convert link tx and rx device attr to a common macro to reduce common code and in preparation for additional attr. Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 6872da08676b..dd63cadb896e 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -189,47 +189,22 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, return size; } -static ssize_t link_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK); -} - -static ssize_t link_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK); -} - -static DEVICE_ATTR_RW(link); - -static ssize_t tx_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX); -} - -static ssize_t tx_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX); -} - -static DEVICE_ATTR_RW(tx); - -static ssize_t rx_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX); -} - -static ssize_t rx_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX); -} - -static DEVICE_ATTR_RW(rx); +#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \ + static ssize_t trigger_name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ + { \ + return netdev_led_attr_show(dev, buf, trigger); \ + } \ + static ssize_t trigger_name##_store(struct device *dev, \ + struct device_attribute *attr, const char *buf, size_t size) \ + { \ + return netdev_led_attr_store(dev, buf, size, trigger); \ + } \ + static DEVICE_ATTR_RW(trigger_name) + +DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); +DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); +DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); static ssize_t interval_show(struct device *dev, struct device_attribute *attr, char *buf) From patchwork Tue May 3 15:16:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 570642 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C29CC433FE for ; Tue, 3 May 2022 15:18:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238303AbiECPWY (ORCPT ); Tue, 3 May 2022 11:22:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238147AbiECPWG (ORCPT ); Tue, 3 May 2022 11:22:06 -0400 Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FD423B000; Tue, 3 May 2022 08:18:24 -0700 (PDT) Received: by mail-ej1-x62c.google.com with SMTP id n10so16675971ejk.5; Tue, 03 May 2022 08:18:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=9xBC8QcemQoDuhQ3dFhb2siSUhkkrc3HV4gsL2HYukk=; b=L4yRerNUvFCrbYp5gSxBJfo2mGPZDBafCYmcHeVpQx31l796lMMBbpHnKutm3N3Kle 8dtDMd9J47Q78UXxP1iLFLyXJGJmh+P7r10vV18yVh6pwU8So5Xeux5IFiQc7u8bFQsW 8Rv4c6oixe9mQKaToFLMrui9Oabq7VGVKrh+aBQVYHd6KiMmxA50Q2/ehiolx0kCAcYY WAHXWbby4UKc96DnK6ER1rgOMTRbyD5ElRnP+JGI4TigaxaldXohWl2o5B3u+2YzRxgf ud28F1lyMLszyHJu3vVFPRcrZOG78Q1HMu+7VAgCDdaUCMmyr+6YJ11n2oRO3kOrypmV BVjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9xBC8QcemQoDuhQ3dFhb2siSUhkkrc3HV4gsL2HYukk=; b=2FkBr2Cgp4M+rb9pk7k8TD5KdHwNVEK8u/pjavTCEd/seu7KLRGfe1CO3eEaRPbilj h2+eCeb/Kt4SSUGtg30BOVVuX5azB5HJNYIGCig8aQmfctAFoCCsXow8gDTs9x6HiiL/ G1lql0GvMu3AXX40kYjm4ek1sX2uh9ZKSnh1dnkQiJJW0ow/NW95pLciB2TsA2pKsDda ZMjIsrkfT4CGigm6nshT3Uht2i6iNaOI6NQiDxIHJXrNdgd7eeeEH5E5QdD9OlaB6WZQ LB4T+Dy3F8lXjLVf1HLzWyFnN8pMb6nUByjIYQi+wbnEME13WttKqc3rZGZOmm86pZZc 0mYg== X-Gm-Message-State: AOAM531Y8+vgA+zAOQRfYZDo5quuDQ9Fw9lpQiH1BKb2ISZ0zMgGtjDT H56sslY7nNUEaJvlbbJfcT8/1OJE9nY= X-Google-Smtp-Source: ABdhPJw0ltNzg2mVG22fRSShqFtmpKIYd9TRj/yJAjeLukk9uZCPyRQ3njptyNenLIPnA2f+bSATXA== X-Received: by 2002:a17:906:7b82:b0:6f3:ee8d:b959 with SMTP id s2-20020a1709067b8200b006f3ee8db959mr16607654ejo.458.1651591102486; Tue, 03 May 2022 08:18:22 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:22 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 06/11] leds: trigger: netdev: add hardware control support Date: Tue, 3 May 2022 17:16:28 +0200 Message-Id: <20220503151633.18760-7-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add hardware control support for the Netdev trigger. The trigger on config change will check if the requested trigger can set to blink mode using LED hardware mode and if every blink mode is supported, the trigger will enable hardware mode with the requested configuration. If there is at least one trigger that is not supported and can't run in hardware mode, then software mode will be used instead. A validation is done on every value change and on fail the old value is restored and -EINVAL is returned. Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 155 +++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 6 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index dd63cadb896e..ed019cb5867c 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -37,6 +37,7 @@ */ struct led_netdev_data { + enum led_blink_modes blink_mode; spinlock_t lock; struct delayed_work work; @@ -53,11 +54,105 @@ struct led_netdev_data { bool carrier_link_up; }; +struct netdev_led_attr_detail { + char *name; + bool hardware_only; + enum led_trigger_netdev_modes bit; +}; + +static struct netdev_led_attr_detail attr_details[] = { + { .name = "link", .bit = TRIGGER_NETDEV_LINK}, + { .name = "tx", .bit = TRIGGER_NETDEV_TX}, + { .name = "rx", .bit = TRIGGER_NETDEV_RX}, +}; + +static bool validate_baseline_state(struct led_netdev_data *trigger_data) +{ + struct led_classdev *led_cdev = trigger_data->led_cdev; + struct netdev_led_attr_detail *detail; + u32 hw_blink_mode_supported = 0; + bool force_sw = false; + int i; + + for (i = 0; i < ARRAY_SIZE(attr_details); i++) { + detail = &attr_details[i]; + + /* Mode not active, skip */ + if (!test_bit(detail->bit, &trigger_data->mode)) + continue; + + /* Hardware only mode enabled on software controlled led */ + if (led_cdev->blink_mode == SOFTWARE_CONTROLLED && + detail->hardware_only) + return false; + + /* Check if the mode supports hardware mode */ + if (led_cdev->blink_mode != SOFTWARE_CONTROLLED) { + /* With a net dev set, force software mode. + * With modes are handled by hardware, led will blink + * based on his own events and will ignore any event + * from the provided dev. + */ + if (trigger_data->net_dev) { + force_sw = true; + continue; + } + + /* With empty dev, check if the mode is supported */ + if (led_trigger_blink_mode_is_supported(led_cdev, detail->bit)) + hw_blink_mode_supported |= BIT(detail->bit); + } + } + + /* We can't run modes handled by both software and hardware. + * Check if we run hardware modes and check if all the modes + * can be handled by hardware. + */ + if (hw_blink_mode_supported && hw_blink_mode_supported != trigger_data->mode) + return false; + + /* Modes are valid. Decide now the running mode to later + * set the baseline. + * Software mode is enforced with net_dev set. With an empty + * one hardware mode is selected by default (if supported). + */ + if (force_sw || led_cdev->blink_mode == SOFTWARE_CONTROLLED) + trigger_data->blink_mode = SOFTWARE_CONTROLLED; + else + trigger_data->blink_mode = HARDWARE_CONTROLLED; + + return true; +} + static void set_baseline_state(struct led_netdev_data *trigger_data) { + int i; int current_brightness; + struct netdev_led_attr_detail *detail; struct led_classdev *led_cdev = trigger_data->led_cdev; + /* Modes already validated. Directly apply hw trigger modes */ + if (trigger_data->blink_mode == HARDWARE_CONTROLLED) { + /* We are refreshing the blink modes. Reset them */ + led_cdev->hw_control_configure(led_cdev, BIT(TRIGGER_NETDEV_LINK), + BLINK_MODE_ZERO); + + for (i = 0; i < ARRAY_SIZE(attr_details); i++) { + detail = &attr_details[i]; + + if (!test_bit(detail->bit, &trigger_data->mode)) + continue; + + led_cdev->hw_control_configure(led_cdev, BIT(detail->bit), + BLINK_MODE_ENABLE); + } + + led_cdev->hw_control_start(led_cdev); + + return; + } + + /* Handle trigger modes by software */ current_brightness = led_cdev->brightness; if (current_brightness) led_cdev->blink_brightness = current_brightness; @@ -100,10 +195,15 @@ static ssize_t device_name_store(struct device *dev, size_t size) { struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + struct net_device *old_net = trigger_data->net_dev; + char old_device_name[IFNAMSIZ]; if (size >= IFNAMSIZ) return -EINVAL; + /* Backup old device name */ + memcpy(old_device_name, trigger_data->device_name, IFNAMSIZ); + cancel_delayed_work_sync(&trigger_data->work); spin_lock_bh(&trigger_data->lock); @@ -122,6 +222,19 @@ static ssize_t device_name_store(struct device *dev, trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name); + if (!validate_baseline_state(trigger_data)) { + /* Restore old net_dev and device_name */ + if (trigger_data->net_dev) + dev_put(trigger_data->net_dev); + + dev_hold(old_net); + trigger_data->net_dev = old_net; + memcpy(trigger_data->device_name, old_device_name, IFNAMSIZ); + + spin_unlock_bh(&trigger_data->lock); + return -EINVAL; + } + trigger_data->carrier_link_up = false; if (trigger_data->net_dev != NULL) trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); @@ -159,7 +272,7 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, size_t size, enum led_trigger_netdev_modes attr) { struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - unsigned long state; + unsigned long state, old_mode = trigger_data->mode; int ret; int bit; @@ -184,6 +297,12 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, else clear_bit(bit, &trigger_data->mode); + if (!validate_baseline_state(trigger_data)) { + /* Restore old mode on validation fail */ + trigger_data->mode = old_mode; + return -EINVAL; + } + set_baseline_state(trigger_data); return size; @@ -220,6 +339,8 @@ static ssize_t interval_store(struct device *dev, size_t size) { struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + int old_interval = atomic_read(&trigger_data->interval); + u32 old_mode = trigger_data->mode; unsigned long value; int ret; @@ -228,13 +349,22 @@ static ssize_t interval_store(struct device *dev, return ret; /* impose some basic bounds on the timer interval */ - if (value >= 5 && value <= 10000) { - cancel_delayed_work_sync(&trigger_data->work); + if (value < 5 || value > 10000) + return -EINVAL; + + cancel_delayed_work_sync(&trigger_data->work); + + atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); - atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); - set_baseline_state(trigger_data); /* resets timer */ + if (!validate_baseline_state(trigger_data)) { + /* Restore old interval on validation error */ + atomic_set(&trigger_data->interval, old_interval); + trigger_data->mode = old_mode; + return -EINVAL; } + set_baseline_state(trigger_data); /* resets timer */ + return size; } @@ -368,13 +498,25 @@ static int netdev_trig_activate(struct led_classdev *led_cdev) trigger_data->mode = 0; atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); trigger_data->last_activity = 0; + if (led_cdev->blink_mode != SOFTWARE_CONTROLLED) { + /* With hw mode enabled reset any rule set by default */ + if (led_cdev->hw_control_status(led_cdev)) { + rc = led_cdev->hw_control_configure(led_cdev, BIT(TRIGGER_NETDEV_LINK), + BLINK_MODE_ZERO); + if (rc) + goto err; + } + } led_set_trigger_data(led_cdev, trigger_data); rc = register_netdevice_notifier(&trigger_data->notifier); if (rc) - kfree(trigger_data); + goto err; + return 0; +err: + kfree(trigger_data); return rc; } @@ -394,6 +536,7 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev) static struct led_trigger netdev_led_trigger = { .name = "netdev", + .supported_blink_modes = SOFTWARE_HARDWARE, .activate = netdev_trig_activate, .deactivate = netdev_trig_deactivate, .groups = netdev_trig_groups, From patchwork Tue May 3 15:16:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 569168 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AD60C433EF for ; Tue, 3 May 2022 15:18:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238162AbiECPWY (ORCPT ); Tue, 3 May 2022 11:22:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51062 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238156AbiECPWG (ORCPT ); Tue, 3 May 2022 11:22:06 -0400 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 718393B02A; Tue, 3 May 2022 08:18:25 -0700 (PDT) Received: by mail-ed1-x532.google.com with SMTP id y21so20257316edo.2; Tue, 03 May 2022 08:18:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=xNl4nmp4IV8sA0Ju8qo0RZUW9W5BZsaB6Tx1+KaqS3o=; b=ZF247WjkHLXEKtHUKwvhmhMpDqhZRT7GAaj/mb3pM7kvPHZHPXU/6/89C02GQXIgeP UD6ElA2prslnviD7PZiTJFxY5e+N86FRtl8VF4qA4mIsnayFiIxUtPigqtTNgV/w2PNO jCqnTqGlbFLTYxmw7ne9JGekSUfGo5m4hPLBDXw7WyCqPKGOIipzxnINz59FL5TkBBCn Mk/tO0DuIE9jfNp93ITwAC/2DvyqvR3n2BDRlEd1vZVHp2sKzPTeh48izp5I3pZxGEpD mn0e0+mHdr/L0vTyRBbWyhH/6aBe3fwiJKlrZ2RcnWs99utgQidh0gGc6DmB1y7QZhRp RUGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xNl4nmp4IV8sA0Ju8qo0RZUW9W5BZsaB6Tx1+KaqS3o=; b=QTL8g0ZCNE9pWC73mpGNJ60bEqH133MqMvwKtZCJG2mrQ0MIq1FVktMclI29T73zbs Ch6rJqldSCouU/23GE8B4F6N7gWYpU2NSZC8sLFlYt1LakuVm3MwAAuuHpj8w9Jly1yd pkboGoiXlKnzE5Ep/6fiS5wDUL1MYQVO9IPH9Q1CXRiNc+uZ9j6wghOc7FpCkP+z+bu/ 8gzx9SDYh5XAtHKlK/EXglaXBJCQZ8Ads52LhGZwKqp/ULyjOKVQ8PVaWt/dUJJqWfxi VEgkeAhS33H/+UsdzpczoC3PgV8+Rtyl5GnbtEAqhkUvY3cx9xgCq/BrsO2RU54l4quc BAIQ== X-Gm-Message-State: AOAM531hMIw8xDtyONOqfpJk/Ekgnvq5NVPEbREZoNP8D9YpMLREBwCJ Q+lV+3sTw5NfvjXv+PGUpfxSjJZVtxc= X-Google-Smtp-Source: ABdhPJxtS8DIiS2+xg3yYgni5xA7D+vICcNmhMo4bzVa0Y5kAQUWDSDSblXWlO+HvIh8YZBGC4puxQ== X-Received: by 2002:a05:6402:296:b0:427:e497:29ef with SMTP id l22-20020a056402029600b00427e49729efmr3578296edv.399.1651591103741; Tue, 03 May 2022 08:18:23 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:23 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 07/11] leds: trigger: netdev: use mutex instead of spinlocks Date: Tue, 3 May 2022 17:16:29 +0200 Message-Id: <20220503151633.18760-8-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Some LEDs may require to sleep to apply their hardware rules. Convert to mutex lock to fix warning for sleeping unser spinlock softirq. Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index ed019cb5867c..a471e0cde836 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include "../leds.h" @@ -38,7 +38,7 @@ struct led_netdev_data { enum led_blink_modes blink_mode; - spinlock_t lock; + struct mutex lock; struct delayed_work work; struct notifier_block notifier; @@ -183,9 +183,9 @@ static ssize_t device_name_show(struct device *dev, struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); ssize_t len; - spin_lock_bh(&trigger_data->lock); + mutex_lock(&trigger_data->lock); len = sprintf(buf, "%s\n", trigger_data->device_name); - spin_unlock_bh(&trigger_data->lock); + mutex_unlock(&trigger_data->lock); return len; } @@ -206,7 +206,7 @@ static ssize_t device_name_store(struct device *dev, cancel_delayed_work_sync(&trigger_data->work); - spin_lock_bh(&trigger_data->lock); + mutex_lock(&trigger_data->lock); if (trigger_data->net_dev) { dev_put(trigger_data->net_dev); @@ -231,7 +231,7 @@ static ssize_t device_name_store(struct device *dev, trigger_data->net_dev = old_net; memcpy(trigger_data->device_name, old_device_name, IFNAMSIZ); - spin_unlock_bh(&trigger_data->lock); + mutex_unlock(&trigger_data->lock); return -EINVAL; } @@ -242,7 +242,7 @@ static ssize_t device_name_store(struct device *dev, trigger_data->last_activity = 0; set_baseline_state(trigger_data); - spin_unlock_bh(&trigger_data->lock); + mutex_unlock(&trigger_data->lock); return size; } @@ -400,7 +400,7 @@ static int netdev_trig_notify(struct notifier_block *nb, cancel_delayed_work_sync(&trigger_data->work); - spin_lock_bh(&trigger_data->lock); + mutex_lock(&trigger_data->lock); trigger_data->carrier_link_up = false; switch (evt) { @@ -423,7 +423,7 @@ static int netdev_trig_notify(struct notifier_block *nb, set_baseline_state(trigger_data); - spin_unlock_bh(&trigger_data->lock); + mutex_unlock(&trigger_data->lock); return NOTIFY_DONE; } @@ -484,7 +484,7 @@ static int netdev_trig_activate(struct led_classdev *led_cdev) if (!trigger_data) return -ENOMEM; - spin_lock_init(&trigger_data->lock); + mutex_init(&trigger_data->lock); trigger_data->notifier.notifier_call = netdev_trig_notify; trigger_data->notifier.priority = 10; From patchwork Tue May 3 15:16:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 569166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7747C4332F for ; Tue, 3 May 2022 15:20:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238146AbiECPYT (ORCPT ); Tue, 3 May 2022 11:24:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238158AbiECPWG (ORCPT ); Tue, 3 May 2022 11:22:06 -0400 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CCF2F3B032; Tue, 3 May 2022 08:18:26 -0700 (PDT) Received: by mail-ed1-x52f.google.com with SMTP id g23so20213828edy.13; Tue, 03 May 2022 08:18:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=tVF3JHqeXvWfPLghH28nep5cSv0CTb1UsfiA1XgSFqA=; b=UDMJD0kZwKXiiM59N3ej5G5K8KwypCLOpZ4d0p571avKyESowbM9YRnpenSxJfPhI1 6iOSQ/kl+Yhj3Mf8rlOOo02e0SoTZU6fLV92ZKau6wxltvtLyRiRNAWxV2qiAEu5pjbd Oz4nt1uYTYs4B5zWxHgbqzAxsTBftRj4lFZpeH0Xgtziy99bBxQGKqz9NxnooQ4jaiDB ZuQWc49SPJwTJfK10JgBhuguy9QIwkXIj2dgjfWMDv+eBP5GMIl875NAe3FMjXMOezjj VYsKM0sakh5EQaxtSf7ILRTD61WZJ14bDOjrFFxqdgbSTvEbhTB6OG58t3Tck8v4t3kU EOyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tVF3JHqeXvWfPLghH28nep5cSv0CTb1UsfiA1XgSFqA=; b=4PIi6u8fpZEjY/Jv9BbvHFVNxpHpV7VNK4S6vGjGZP8jn1RQEBoPXxTXg0DKk+C4uk CHBKeQTz2kHlVCl8lVZrht+9NkMKw8oGd2WCyyf2bRtUUvjEMYaRSUqxgly22Dn33jsi oPHpRSXzx7IiIU+cuQPJumV9mJjMWXXzHpRDRWQplH/I66HcxIFKwDwHaeozvWw5w39x G7YrRZD79xSvncBH3KFl0KaRymu4dMwIQKcHhd5HvylG9l06/cdOi7kNQ/Q3EQmmNtuo hdk1wt3OkPOY9ozQTmRdXHrb7rNmpHXA+IcGbvOWsElV2nIvmFTP23+3cOUUS/+Dswih KUTw== X-Gm-Message-State: AOAM532PS4skwS/ljspvspxsq0KsQ42SM4TT8/LuAdDHO2+fENwAvFXJ u4dQiek9dkLCuJmw5lM2QBA= X-Google-Smtp-Source: ABdhPJy7Y3NgLHFdEkhOkHD0ngHN0R8VghkVSF2eeoJcxy+lqIB0V3jpm7ftlNWzB/jQW3ars9gXDg== X-Received: by 2002:aa7:d350:0:b0:425:e029:da56 with SMTP id m16-20020aa7d350000000b00425e029da56mr18644619edr.296.1651591105246; Tue, 03 May 2022 08:18:25 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:24 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 08/11] leds: trigger: netdev: add available mode sysfs attr Date: Tue, 3 May 2022 17:16:30 +0200 Message-Id: <20220503151633.18760-9-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add avaiable_mode sysfs attr to show and give some details about the supported modes and how they can be handled by the trigger. This is in preparation for hardware only modes that doesn't support software fallback. Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index a471e0cde836..d88b0c6a910e 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -33,6 +33,8 @@ * (has carrier) or not * tx - LED blinks on transmitted data * rx - LED blinks on receive data + * available_mode - Display available mode and how they can be handled + * by the LED * */ @@ -370,12 +372,42 @@ static ssize_t interval_store(struct device *dev, static DEVICE_ATTR_RW(interval); +static ssize_t available_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); + struct netdev_led_attr_detail *detail; + int i, len = 0; + + for (i = 0; i < ARRAY_SIZE(attr_details); i++) { + detail = &attr_details[i]; + + if (led_trigger_blink_mode_is_supported(trigger_data->led_cdev, detail->bit)) { + if (!trigger_data->net_dev) { + if (detail->hardware_only) + len += sprintf(buf+len, "%s [hardware]\n", + detail->name); + else + len += sprintf(buf+len, "%s [software-hardware]\n", + detail->name); + } + } else { + len += sprintf(buf+len, "%s [software]\n", detail->name); + } + } + + return len; +} + +static DEVICE_ATTR_RO(available_mode); + 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, + &dev_attr_available_mode.attr, NULL }; ATTRIBUTE_GROUPS(netdev_trig); From patchwork Tue May 3 15:16:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 569167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7CFEC43217 for ; Tue, 3 May 2022 15:18:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238307AbiECPWZ (ORCPT ); Tue, 3 May 2022 11:22:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238160AbiECPWG (ORCPT ); Tue, 3 May 2022 11:22:06 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 337E83B018; Tue, 3 May 2022 08:18:28 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id p18so20219417edr.7; Tue, 03 May 2022 08:18:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=tR8IRWH0xQBqVx+xXwpjUsHhcTEL0yAEgJc1yrKzhxk=; b=R4bOOQCZ1zDudeP2d/a3ERHdfnM/No7BIv3UC7sgI44lAz8JuT0xZI4wlYdSWq6MbM 2FHUrhiuDfpNbIIo8JL4HTUGahP0SXeS4ZFnN+Nq39UIg/ALC3475+7Du2wwfPqZoPCS uFIEs7VCcUYJCyjtM3LY+MNy4r/5agitYnUIp+sA5hvifHOz3DJjeERXUcMH5IhxewTT dD79aBVvXIEVCvk2BQ4FhplNpPHQVOmZw33Son3Cz2eQsAYPV+G/cxnfe8vS+VN9+DWx 1zOdTgODZ9RbQ0opp+AipX5K6QXcuAul/nOzkn4d+va/5p6r/2GM3oaGegm9wAR4n8Vl RnSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tR8IRWH0xQBqVx+xXwpjUsHhcTEL0yAEgJc1yrKzhxk=; b=T4+adFXXUHgY3RieW+xlYhLYxMVmR66cl8sqv/0o86g401MUT9Qx3SOkPQOqcwKjhs 9f7SboDBoo2dHZf4sXW6sTF4kIIhfHK2f7VowCy3eDviCjuOCyFlxErhW+1ccGqpp5Pf 5gVd2ZrGWSO0Kn/rEuEaeiD7eNWoBFn0nQNr8F+Uzzs7ujMxObwNFj//chKbef6FCbPT XWuCBPl8/6JmaeMdDmERvFEgQIeI3VciKAduRf178Mtgdy9XVEH0FQl0W55OqyBpPjk/ kh7/6+hzLtCtzG5gpUntKw/SKzli315AMDkZoG3R3fj8o8CvRgoIH/O8v4sHH7h7S38P HeNQ== X-Gm-Message-State: AOAM5339deki3n1WVRqhh7U6D3YWHptk2DQklsOkyzzp8GJbOEeS+7R2 jN58PvxxbzO/5cCpkYNceGk= X-Google-Smtp-Source: ABdhPJyM/DXKKPyfASY7GZhfHVYG8hE5CdiRrdrFvNXqwhpWDJxzDev6qxXbRaDL6lSIrrHmMsBoRQ== X-Received: by 2002:aa7:d393:0:b0:425:a8f8:663a with SMTP id x19-20020aa7d393000000b00425a8f8663amr18269119edq.323.1651591106568; Tue, 03 May 2022 08:18:26 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:26 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 09/11] leds: trigger: netdev: add additional hardware only triggers Date: Tue, 3 May 2022 17:16:31 +0200 Message-Id: <20220503151633.18760-10-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add additional hardware only triggers commonly supported by switch LEDs. Additional modes: link_10: LED on with link up AND speed 10mbps link_100: LED on with link up AND speed 100mbps link_1000: LED on with link up AND speed 1000mbps half_duplex: LED on with link up AND half_duplex mode full_duplex: LED on with link up AND full duplex mode Additional blink interval modes: blink_2hz: LED blink on any even at 2Hz (250ms) blink_4hz: LED blink on any even at 4Hz (125ms) blink_8hz: LED blink on any even at 8Hz (62ms) Signed-off-by: Ansuel Smith --- drivers/leds/trigger/ledtrig-netdev.c | 58 +++++++++++++++++++++++++++ include/linux/leds.h | 10 +++++ 2 files changed, 68 insertions(+) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index d88b0c6a910e..bced05fafb1c 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -29,8 +29,20 @@ * * device_name - network device name to monitor * interval - duration of LED blink, in milliseconds + * (in hardware mode 2hz (62ms), 4hz (125ms) or 8hz (250ms) + * are supported) * link - LED's normal state reflects whether the link is up * (has carrier) or not + * link_10 - LED's normal state reflects whether the link is + * up and at 10mbps speed (hardware only) + * link_100 - LED's normal state reflects whether the link is + * up and at 100mbps speed (hardware only) + * link_1000 - LED's normal state reflects whether the link is + * up and at 1000mbps speed (hardware only) + * half_duplex - LED's normal state reflects whether the link is + * up and hafl duplex (hardware only) + * full_duplex - LED's normal state reflects whether the link is + * up and full duplex (hardware only) * tx - LED blinks on transmitted data * rx - LED blinks on receive data * available_mode - Display available mode and how they can be handled @@ -64,8 +76,19 @@ struct netdev_led_attr_detail { static struct netdev_led_attr_detail attr_details[] = { { .name = "link", .bit = TRIGGER_NETDEV_LINK}, + { .name = "link_10", .hardware_only = true, .bit = TRIGGER_NETDEV_LINK_10}, + { .name = "link_100", .hardware_only = true, .bit = TRIGGER_NETDEV_LINK_100}, + { .name = "link_1000", .hardware_only = true, .bit = TRIGGER_NETDEV_LINK_1000}, + { .name = "half_duplex", .hardware_only = true, .bit = TRIGGER_NETDEV_HALF_DUPLEX}, + { .name = "full_duplex", .hardware_only = true, .bit = TRIGGER_NETDEV_FULL_DUPLEX}, { .name = "tx", .bit = TRIGGER_NETDEV_TX}, { .name = "rx", .bit = TRIGGER_NETDEV_RX}, + { .name = "hw blink 2hz (interval set to 62)", .hardware_only = true, + .bit = TRIGGER_NETDEV_BLINK_2HZ}, + { .name = "hw blink 4hz (interval set to 125)", .hardware_only = true, + .bit = TRIGGER_NETDEV_BLINK_4HZ}, + { .name = "hw blink 8hz (interval set to 250)", .hardware_only = true, + .bit = TRIGGER_NETDEV_BLINK_8HZ}, }; static bool validate_baseline_state(struct led_netdev_data *trigger_data) @@ -259,6 +282,11 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf, switch (attr) { case TRIGGER_NETDEV_LINK: + case TRIGGER_NETDEV_LINK_10: + case TRIGGER_NETDEV_LINK_100: + case TRIGGER_NETDEV_LINK_1000: + case TRIGGER_NETDEV_HALF_DUPLEX: + case TRIGGER_NETDEV_FULL_DUPLEX: case TRIGGER_NETDEV_TX: case TRIGGER_NETDEV_RX: bit = attr; @@ -284,6 +312,11 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, switch (attr) { case TRIGGER_NETDEV_LINK: + case TRIGGER_NETDEV_LINK_10: + case TRIGGER_NETDEV_LINK_100: + case TRIGGER_NETDEV_LINK_1000: + case TRIGGER_NETDEV_HALF_DUPLEX: + case TRIGGER_NETDEV_FULL_DUPLEX: case TRIGGER_NETDEV_TX: case TRIGGER_NETDEV_RX: bit = attr; @@ -324,6 +357,11 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, static DEVICE_ATTR_RW(trigger_name) DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); +DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10); +DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100); +DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000); +DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX); +DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX); DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); @@ -356,6 +394,21 @@ static ssize_t interval_store(struct device *dev, cancel_delayed_work_sync(&trigger_data->work); + if (trigger_data->blink_mode == HARDWARE_CONTROLLED) { + /* Interval are handled as triggers. Reset them. */ + trigger_data->mode &= ~(BIT(TRIGGER_NETDEV_BLINK_8HZ) | + BIT(TRIGGER_NETDEV_BLINK_4HZ) | + BIT(TRIGGER_NETDEV_BLINK_2HZ)); + + /* Support a common value of 2Hz, 4Hz and 8Hz. */ + if (value > 5 && value <= 62) /* 8Hz */ + trigger_data->mode |= BIT(TRIGGER_NETDEV_BLINK_8HZ); + else if (value > 63 && value <= 125) /* 4Hz */ + trigger_data->mode |= BIT(TRIGGER_NETDEV_BLINK_4HZ); + else /* 2Hz */ + trigger_data->mode |= BIT(TRIGGER_NETDEV_BLINK_2HZ); + } + atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); if (!validate_baseline_state(trigger_data)) { @@ -404,6 +457,11 @@ static DEVICE_ATTR_RO(available_mode); static struct attribute *netdev_trig_attrs[] = { &dev_attr_device_name.attr, &dev_attr_link.attr, + &dev_attr_link_10.attr, + &dev_attr_link_100.attr, + &dev_attr_link_1000.attr, + &dev_attr_half_duplex.attr, + &dev_attr_full_duplex.attr, &dev_attr_rx.attr, &dev_attr_tx.attr, &dev_attr_interval.attr, diff --git a/include/linux/leds.h b/include/linux/leds.h index 13862f8b1e07..5fcc6d233757 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -551,8 +551,18 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) /* Trigger specific enum */ enum led_trigger_netdev_modes { TRIGGER_NETDEV_LINK = 1, + TRIGGER_NETDEV_LINK_10, + TRIGGER_NETDEV_LINK_100, + TRIGGER_NETDEV_LINK_1000, + TRIGGER_NETDEV_HALF_DUPLEX, + TRIGGER_NETDEV_FULL_DUPLEX, TRIGGER_NETDEV_TX, TRIGGER_NETDEV_RX, + + /* Hardware Interval options */ + TRIGGER_NETDEV_BLINK_2HZ, + TRIGGER_NETDEV_BLINK_4HZ, + TRIGGER_NETDEV_BLINK_8HZ, }; /* Trigger specific functions */ From patchwork Tue May 3 15:16:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 570641 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36561C4332F for ; Tue, 3 May 2022 15:18:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238318AbiECPW1 (ORCPT ); Tue, 3 May 2022 11:22:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238126AbiECPWL (ORCPT ); Tue, 3 May 2022 11:22:11 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91C823B037; Tue, 3 May 2022 08:18:29 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id y21so20257606edo.2; Tue, 03 May 2022 08:18:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=qWeRBSAuPZGLs4sbYjchUhwhQ1cr8p5mhxScwOV6V9s=; b=F3O3swQokHF7rJy+uTUEWaWRNp+sI3ifyExXf+T9jaoRnb9sM8qZ43oj+z1IQO3VN5 cdggIPkTraaZP8+XluiVTLra2bY8zCGBubz3ykZW+SzCEw62tE4CVxBo7kVmwjyAqwLN 9OIziKGOdlNVqDpH4bkoxe5iRG687wR+IsnpSNNS05xfvluPv8kk1c6rbP+BGxG+Ng5e YAj+kM+cyCJSixUCossGz2VO8goVq01idpOaw+5UYGSbzjv39GhNaMYZeQulyraBt85F KNJYajymnUQXRMAOKtUZTIyCNGE3g0XXoz4cNBrpt0zp5uWZGZU7JixeDwj95j9nD6cU Y+Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qWeRBSAuPZGLs4sbYjchUhwhQ1cr8p5mhxScwOV6V9s=; b=PnYVd43a8nU29DiQvxLxRx/YCIVy4eRkj9JsrZ8fWhDr0nFrCfDrphc44oh4ZwDE8a NLTyTgDJUkxwt/OeUa15Jt/1LxjOF1zEOaZ/fCswjsVNHt64XTTnE+Que170fLyhlO/G qKZC/RbO8M0YCCzkVsYfinJedmG3jPQa21rDt78LZvGAiO64TdFdGp+EzNiCLyBl0WvX tAlR05fUC/NihVXJfZwHe47ZmxLwsQTAB2FnpaHfFj32C+ZQWl15J6te46aij7jHPCwF kjZidK3PsHj25mhdj/85kgn4quuRZzak+IlgKv50uCX31XVoUJuJXsfB03DbRIugxbFz HXwg== X-Gm-Message-State: AOAM530dlEEIIwQUlasaBiCOTfSw/Vgi7ehtNxkqb871dDsLljFLsid8 ggj6d/KMCwH2cujpalZF3K0= X-Google-Smtp-Source: ABdhPJwbOzuFAAUEYviqJb0KYowRVRMSPG+4iFmhWDY+SZItoq+dxEThm0+GEedrm5OzFf/+PlYXDQ== X-Received: by 2002:a05:6402:492:b0:404:c4bf:8b7e with SMTP id k18-20020a056402049200b00404c4bf8b7emr18247260edv.318.1651591107912; Tue, 03 May 2022 08:18:27 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:27 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 10/11] net: dsa: qca8k: add LEDs support Date: Tue, 3 May 2022 17:16:32 +0200 Message-Id: <20220503151633.18760-11-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add LEDs support for qca8k Switch Family. This will provide the LEDs hardware API to permit the PHY LED to support hardware mode. Each port have at least 3 LEDs and they can HW blink, set on/off or follow blink modes configured with the LED in hardware mode.. This adds support for 2 hardware trigger netdev and hardware-phy-activity. Signed-off-by: Ansuel Smith --- drivers/net/dsa/Kconfig | 9 + drivers/net/dsa/Makefile | 1 + drivers/net/dsa/qca8k-leds.c | 408 +++++++++++++++++++++++++++++++++++ drivers/net/dsa/qca8k.c | 4 + drivers/net/dsa/qca8k.h | 61 ++++++ 5 files changed, 483 insertions(+) create mode 100644 drivers/net/dsa/qca8k-leds.c diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 37a3dabdce31..6e9d730c5e00 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -68,6 +68,15 @@ config NET_DSA_QCA8K This enables support for the Qualcomm Atheros QCA8K Ethernet switch chips. +config NET_DSA_QCA8K_LEDS_SUPPORT + tristate "Qualcomm Atheros QCA8K Ethernet switch family LEDs support" + select NET_DSA_QCA8K + select LEDS_OFFLOAD_TRIGGERS + help + This enabled support for LEDs present on the Qualcomm Atheros + QCA8K Ethernet switch chips. This require the LEDs offload + triggers support as it can run in offload mode. + source "drivers/net/dsa/realtek/Kconfig" config NET_DSA_SMSC_LAN9303 diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index e73838c12256..5965b59e1ff7 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o +obj-$(CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT) += qca8k-leds.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o diff --git a/drivers/net/dsa/qca8k-leds.c b/drivers/net/dsa/qca8k-leds.c new file mode 100644 index 000000000000..261888ad95a9 --- /dev/null +++ b/drivers/net/dsa/qca8k-leds.c @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +#include "qca8k.h" + +static int +qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) +{ + int shift; + + switch (port_num) { + case 0: + reg_info->reg = QCA8K_LED_CTRL_REG(led_num); + reg_info->shift = 14; + break; + case 1: + case 2: + case 3: + reg_info->reg = QCA8K_LED_CTRL_REG(3); + shift = 2 * led_num + (6 * (port_num - 1)); + + reg_info->shift = 8 + shift; + + break; + case 4: + reg_info->reg = QCA8K_LED_CTRL_REG(led_num); + reg_info->shift = 30; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int +qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) +{ + reg_info->reg = QCA8K_LED_CTRL_REG(led_num); + + /* 6 total control rule: + * 3 control rules for phy0-3 that applies to all their leds + * 3 control rules for phy4 + */ + if (port_num == 4) + reg_info->shift = 16; + else + reg_info->shift = 0; + + return 0; +} + +static int +qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger, u32 *mask) +{ + /* Parsing specific to netdev trigger */ + if (test_bit(TRIGGER_NETDEV_LINK, &rules)) + *offload_trigger = QCA8K_LED_LINK_10M_EN_MASK | + QCA8K_LED_LINK_100M_EN_MASK | + QCA8K_LED_LINK_1000M_EN_MASK; + if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) + *offload_trigger = QCA8K_LED_LINK_10M_EN_MASK; + if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) + *offload_trigger = QCA8K_LED_LINK_100M_EN_MASK; + if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) + *offload_trigger = QCA8K_LED_LINK_1000M_EN_MASK; + if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) + *offload_trigger = QCA8K_LED_HALF_DUPLEX_MASK; + if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) + *offload_trigger = QCA8K_LED_FULL_DUPLEX_MASK; + if (test_bit(TRIGGER_NETDEV_TX, &rules)) + *offload_trigger = QCA8K_LED_TX_BLINK_MASK; + if (test_bit(TRIGGER_NETDEV_RX, &rules)) + *offload_trigger = QCA8K_LED_RX_BLINK_MASK; + if (test_bit(TRIGGER_NETDEV_BLINK_2HZ, &rules)) + *offload_trigger = QCA8K_LED_BLINK_2HZ; + if (test_bit(TRIGGER_NETDEV_BLINK_4HZ, &rules)) + *offload_trigger = QCA8K_LED_BLINK_4HZ; + if (test_bit(TRIGGER_NETDEV_BLINK_8HZ, &rules)) + *offload_trigger = QCA8K_LED_BLINK_8HZ; + + pr_info("OFFLOAD TRIGGER %x\n", *offload_trigger); + + if (!*offload_trigger) + return -EOPNOTSUPP; + + if (test_bit(TRIGGER_NETDEV_BLINK_2HZ, &rules) || + test_bit(TRIGGER_NETDEV_BLINK_4HZ, &rules) || + test_bit(TRIGGER_NETDEV_BLINK_8HZ, &rules)) { + *mask = QCA8K_LED_BLINK_FREQ_MASK; + } else { + *mask = *offload_trigger; + } + + return 0; +} + +static int +qca8k_cled_hw_control_configure(struct led_classdev *ldev, unsigned long rules, + enum blink_mode_cmd cmd) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + struct led_trigger *trigger = ldev->trigger; + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + u32 offload_trigger = 0, mask, val; + int ret; + + /* Check trigger compatibility */ + if (strcmp(trigger->name, "netdev")) + return -EOPNOTSUPP; + + if (!strcmp(trigger->name, "netdev")) + ret = qca8k_parse_netdev(rules, &offload_trigger, &mask); + + if (ret) + return ret; + + qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); + + switch (cmd) { + case BLINK_MODE_SUPPORTED: + /* We reach this point, we are sure the trigger is supported */ + return 1; + case BLINK_MODE_ZERO: + /* We set 4hz by default */ + u32 default_reg = QCA8K_LED_BLINK_4HZ; + + ret = regmap_update_bits(priv->regmap, reg_info.reg, + QCA8K_LED_RULE_MASK << reg_info.shift, + default_reg << reg_info.shift); + break; + case BLINK_MODE_ENABLE: + ret = regmap_update_bits(priv->regmap, reg_info.reg, + mask << reg_info.shift, + offload_trigger << reg_info.shift); + break; + case BLINK_MODE_DISABLE: + ret = regmap_update_bits(priv->regmap, reg_info.reg, + mask << reg_info.shift, + 0); + break; + case BLINK_MODE_READ: + ret = regmap_read(priv->regmap, reg_info.reg, &val); + if (ret) + return ret; + + val >>= reg_info.shift; + val &= offload_trigger; + + /* Special handling for LED_BLINK_2HZ */ + if (!val && offload_trigger == QCA8K_LED_BLINK_2HZ) + val = 1; + + return val; + default: + return -EOPNOTSUPP; + } + + return ret; +} + +static void +qca8k_led_brightness_set(struct qca8k_led *led, + enum led_brightness b) +{ + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + u32 val = QCA8K_LED_ALWAYS_OFF; + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + if (b) + val = QCA8K_LED_ALWAYS_ON; + + regmap_update_bits(priv->regmap, reg_info.reg, + GENMASK(1, 0) << reg_info.shift, + val << reg_info.shift); +} + +static void +qca8k_cled_brightness_set(struct led_classdev *ldev, + enum led_brightness b) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + + return qca8k_led_brightness_set(led, b); +} + +static enum led_brightness +qca8k_led_brightness_get(struct qca8k_led *led) +{ + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + u32 val; + int ret; + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + ret = regmap_read(priv->regmap, reg_info.reg, &val); + if (ret) + return 0; + + val >>= reg_info.shift; + val &= GENMASK(1, 0); + + return val > 0 ? 1 : 0; +} + +static enum led_brightness +qca8k_cled_brightness_get(struct led_classdev *ldev) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + + return qca8k_led_brightness_get(led); +} + +static int +qca8k_cled_blink_set(struct led_classdev *ldev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + + if (*delay_on == 0 && *delay_off == 0) { + *delay_on = 125; + *delay_off = 125; + } + + if (*delay_on != 125 || *delay_off != 125) { + /* The hardware only supports blinking at 4Hz. Fall back + * to software implementation in other cases. + */ + return -EINVAL; + } + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + regmap_update_bits(priv->regmap, reg_info.reg, + GENMASK(1, 0) << reg_info.shift, + QCA8K_LED_ALWAYS_BLINK_4HZ << reg_info.shift); + + return 0; +} + +static int +qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + u32 val = QCA8K_LED_ALWAYS_OFF; + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + if (enable) + val = QCA8K_LED_RULE_CONTROLLED; + + return regmap_update_bits(priv->regmap, reg_info.reg, + GENMASK(1, 0) << reg_info.shift, + val << reg_info.shift); +} + +static int +qca8k_cled_hw_control_start(struct led_classdev *led_cdev) +{ + return qca8k_cled_trigger_offload(led_cdev, true); +} + +static int +qca8k_cled_hw_control_stop(struct led_classdev *led_cdev) +{ + return qca8k_cled_trigger_offload(led_cdev, false); +} + +static bool +qca8k_cled_hw_control_status(struct led_classdev *ldev) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + u32 val; + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + regmap_read(priv->regmap, reg_info.reg, &val); + + val >>= reg_info.shift; + val &= GENMASK(1, 0); + + return val == QCA8K_LED_RULE_CONTROLLED; +} + +static int +qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) +{ + struct fwnode_handle *led = NULL, *leds = NULL; + struct led_init_data init_data = { }; + struct qca8k_led *port_led; + int led_num, port_index; + const char *state; + int ret; + + leds = fwnode_get_named_child_node(port, "leds"); + if (!leds) { + dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n", + port_num); + return 0; + } + + fwnode_for_each_child_node(leds, led) { + /* Reg represent the led number of the port. + * Each port can have at least 3 leds attached + * Commonly: + * 1. is gigabit led + * 2. is mbit led + * 3. additional status led + */ + if (fwnode_property_read_u32(led, "reg", &led_num)) + continue; + + if (led_num >= QCA8K_LED_PORT_COUNT) { + dev_warn(priv->dev, "Invalid LED reg defined %d", port_num); + continue; + } + + port_index = 3 * port_num + led_num; + + port_led = &priv->ports_led[port_index]; + port_led->port_num = port_num; + port_led->led_num = led_num; + port_led->priv = priv; + + ret = fwnode_property_read_string(led, "default-state", &state); + if (!ret) { + if (!strcmp(state, "on")) { + port_led->cdev.brightness = 1; + qca8k_led_brightness_set(port_led, 1); + } else if (!strcmp(state, "off")) { + port_led->cdev.brightness = 0; + qca8k_led_brightness_set(port_led, 0); + } else if (!strcmp(state, "keep")) { + port_led->cdev.brightness = + qca8k_led_brightness_get(port_led); + } + } + + /* 3 brightness settings can be applied from Documentation: + * 0 always off + * 1 blink at 4Hz + * 2 always on + * 3 rule controlled + * Suppots only 2 mode: (pcb limitation, with always on and blink + * only the last led is set to this mode) + * 0 always off (sets all leds off) + * 3 rule controlled + */ + port_led->cdev.blink_mode = SOFTWARE_HARDWARE_CONTROLLED; + port_led->cdev.max_brightness = 1; + port_led->cdev.brightness_set = qca8k_cled_brightness_set; + port_led->cdev.brightness_get = qca8k_cled_brightness_get; + port_led->cdev.blink_set = qca8k_cled_blink_set; + port_led->cdev.hw_control_start = qca8k_cled_hw_control_start; + port_led->cdev.hw_control_stop = qca8k_cled_hw_control_stop; + port_led->cdev.hw_control_status = qca8k_cled_hw_control_status; + port_led->cdev.hw_control_configure = qca8k_cled_hw_control_configure; + init_data.default_label = ":port"; + init_data.devicename = "qca8k"; + init_data.fwnode = led; + + ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data); + if (ret) + dev_warn(priv->dev, "Failed to int led"); + } + + return 0; +} + +int +qca8k_setup_led_ctrl(struct qca8k_priv *priv) +{ + struct fwnode_handle *mdio, *port; + int port_num; + int ret; + + mdio = device_get_named_child_node(priv->dev, "mdio"); + if (!mdio) { + dev_info(priv->dev, "No MDIO node specified in device tree!\n"); + return 0; + } + + fwnode_for_each_child_node(mdio, port) { + if (fwnode_property_read_u32(port, "reg", &port_num)) + continue; + + /* Each port can have at least 3 different leds attached */ + ret = qca8k_parse_port_leds(priv, port, port_num); + if (ret) + return ret; + } + + return 0; +} diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index d3ed0a7f8077..ea658f1c586a 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -2889,6 +2889,10 @@ qca8k_setup(struct dsa_switch *ds) if (ret) return ret; + ret = qca8k_setup_led_ctrl(priv); + if (ret) + return ret; + qca8k_setup_pcs(priv, &priv->pcs_port_0, 0); qca8k_setup_pcs(priv, &priv->pcs_port_6, 6); diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index f375627174c8..92c5ae12e4b0 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #define QCA8K_ETHERNET_MDIO_PRIORITY 7 @@ -85,6 +86,43 @@ #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) #define QCA8K_MDIO_MASTER_MAX_PORTS 5 #define QCA8K_MDIO_MASTER_MAX_REG 32 + +/* LED control register */ +#define QCA8K_LED_COUNT 15 +#define QCA8K_LED_PORT_COUNT 3 +#define QCA8K_LED_RULE_COUNT 6 +#define QCA8K_LED_RULE_MAX 11 +#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4) +#define QCA8K_LED_CTRL0_REG 0x50 +#define QCA8K_LED_CTRL1_REG 0x54 +#define QCA8K_LED_CTRL2_REG 0x58 +#define QCA8K_LED_CTRL3_REG 0x5C +#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16) +#define QCA8K_LED_CTRL_MASK GENMASK(15, 0) +#define QCA8K_LED_RULE_MASK GENMASK(13, 0) +#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0) +#define QCA8K_LED_BLINK_FREQ_SHITF 0 +#define QCA8K_LED_BLINK_2HZ 0 +#define QCA8K_LED_BLINK_4HZ 1 +#define QCA8K_LED_BLINK_8HZ 2 +#define QCA8K_LED_BLINK_AUTO 3 +#define QCA8K_LED_LINKUP_OVER_MASK BIT(2) +#define QCA8K_LED_TX_BLINK_MASK BIT(4) +#define QCA8K_LED_RX_BLINK_MASK BIT(5) +#define QCA8K_LED_COL_BLINK_MASK BIT(7) +#define QCA8K_LED_LINK_10M_EN_MASK BIT(8) +#define QCA8K_LED_LINK_100M_EN_MASK BIT(9) +#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10) +#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11) +#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12) +#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13) +#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14) +#define QCA8K_LED_PATTERN_EN_SHIFT 14 +#define QCA8K_LED_ALWAYS_OFF 0 +#define QCA8K_LED_ALWAYS_BLINK_4HZ 1 +#define QCA8K_LED_ALWAYS_ON 2 +#define QCA8K_LED_RULE_CONTROLLED 3 + #define QCA8K_GOL_MAC_ADDR0 0x60 #define QCA8K_GOL_MAC_ADDR1 0x64 #define QCA8K_MAX_FRAME_SIZE 0x78 @@ -382,6 +420,19 @@ struct qca8k_pcs { int port; }; +struct qca8k_led_pattern_en { + u32 reg; + u8 shift; +}; + +struct qca8k_led { + u8 port_num; + u8 led_num; + u16 old_rule; + struct qca8k_priv *priv; + struct led_classdev cdev; +}; + struct qca8k_priv { u8 switch_id; u8 switch_revision; @@ -405,6 +456,7 @@ struct qca8k_priv { struct qca8k_mdio_cache mdio_cache; struct qca8k_pcs pcs_port_0; struct qca8k_pcs pcs_port_6; + struct qca8k_led ports_led[QCA8K_LED_COUNT]; }; struct qca8k_mib_desc { @@ -420,4 +472,13 @@ struct qca8k_fdb { u8 mac[6]; }; +#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT +int qca8k_setup_led_ctrl(struct qca8k_priv *priv); +#else +static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv) +{ + return 0; +} +#endif + #endif /* __QCA8K_H */ From patchwork Tue May 3 15:16:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 570640 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C06AEC433EF for ; Tue, 3 May 2022 15:20:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238201AbiECPYT (ORCPT ); Tue, 3 May 2022 11:24:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238198AbiECPWL (ORCPT ); Tue, 3 May 2022 11:22:11 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3D0F3B284; Tue, 3 May 2022 08:18:30 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id p18so20219595edr.7; Tue, 03 May 2022 08:18:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=4CKD+DKMQd1ZEVY0/Od89OuEu7h6AxtbdaBQHqft0yE=; b=HKihauhgQX2IKgIzKLB0B3T94583zUyrC5ZwDOufzBh1kiCDtyzDhz4oGrE5BVXib0 mt/8qujzN+FR+2oAwGydwXS2FXNkBJcww/w3VY8UZtodzt8CB/26N3Vd1gPyP/SMlGUf /4Qgqg51j2lLfcjHYrZTSBA04QEe4SOZQh8NxeUOy84luKqxWpdz26B16/HeCqCdv8Cw jBtURTZVZiUGTqkQnMYuwEhR4hfFrheL1l8NUnNeN5CkGra4D1M65+tLE0/NnAkD/GyW M/vK3eVnoilumQkuDbAvvLhtB3aBXUH56Im+FGuo81WwO8fv+K50j8ObbDVVsGZOo3wT GPyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4CKD+DKMQd1ZEVY0/Od89OuEu7h6AxtbdaBQHqft0yE=; b=e6keluzVr8CeVS+CiQgRrYyKw6LSHcFv5Gj2H8HrpPrZA0op46xp2pd4GQzTo2EAtC FbOBblO3ylx5F+QIhCjwqBu7zroupEE9ymUu2BY6jbP4zwd4Jk6nilkiA2T10cIZECbR ym0vpNFRXCQWMyqsh+1mYUVdYJLnq4oizscMHvfkdaKbS3S3r5hP44cgwQ8EejlZynRn uYe+GiLpiEm1hnLAnkSJuRvaPQ6VBzb2Wn/1jNCsoNWsYn6tbaiqcilt8lADHIz8jLG3 Zow3xIcrfRmPuL8OOB9Z4zaI7YuNIiJew0avXyDpKuaoRs4qpvSRa7idKSsv1XmecTPw D1Tg== X-Gm-Message-State: AOAM530H5S45Z5E43K3TGuCjv7r5dhaFJAdFPJkkSC/S1t1UxeMnzlp3 MRYW7V3ZAU+G5xZl/pMyysE= X-Google-Smtp-Source: ABdhPJwNPlohltAOl9bRzLdnMWY8egRON0HXgwdFSqhhIXHwaosoUIwMHnQDOIRpRY8cy3iEWVPrwQ== X-Received: by 2002:a05:6402:3586:b0:427:b16e:a191 with SMTP id y6-20020a056402358600b00427b16ea191mr15097225edc.137.1651591109212; Tue, 03 May 2022 08:18:29 -0700 (PDT) Received: from localhost.localdomain (93-42-70-190.ip85.fastwebnet.it. [93.42.70.190]) by smtp.googlemail.com with ESMTPSA id v3-20020aa7d9c3000000b0042617ba63cesm7947507eds.88.2022.05.03.08.18.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 May 2022 08:18:28 -0700 (PDT) From: Ansuel Smith To: Andrew Lunn , Vivien Didelot , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Ansuel Smith , John Crispin , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-leds@vger.kernel.org Subject: [RFC PATCH v6 11/11] dt-bindings: net: dsa: qca8k: add LEDs definition example Date: Tue, 3 May 2022 17:16:33 +0200 Message-Id: <20220503151633.18760-12-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220503151633.18760-1-ansuelsmth@gmail.com> References: <20220503151633.18760-1-ansuelsmth@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add LEDs definition example for qca8k using the offload trigger as the default trigger and add all the supported offload triggers by the switch. Signed-off-by: Ansuel Smith --- .../devicetree/bindings/net/dsa/qca8k.yaml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.yaml b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml index f3c88371d76c..9b46ef645a2d 100644 --- a/Documentation/devicetree/bindings/net/dsa/qca8k.yaml +++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml @@ -65,6 +65,8 @@ properties: internal mdio access is used. With the legacy mapping the reg corresponding to the internal mdio is the switch reg with an offset of -1. + Each phy have at least 3 LEDs connected and can be declared + using the standard LEDs structure. patternProperties: "^(ethernet-)?ports$": @@ -287,6 +289,24 @@ examples: internal_phy_port1: ethernet-phy@0 { reg = <0>; + + leds { + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + linux,default-trigger = "netdev"; + }; + + led@1 { + reg = <1>; + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + linux,default-trigger = "netdev"; + }; + }; }; internal_phy_port2: ethernet-phy@1 {