From patchwork Wed Dec 14 23:54:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 634044 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 1DF7CC4167B for ; Wed, 14 Dec 2022 23:59:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229938AbiLNX66 (ORCPT ); Wed, 14 Dec 2022 18:58:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229937AbiLNX6f (ORCPT ); Wed, 14 Dec 2022 18:58:35 -0500 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 69CEB5C77D; Wed, 14 Dec 2022 15:55:40 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id y16so1475639wrm.2; Wed, 14 Dec 2022 15:55:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hSDIT5ag90Nh6sLPPU0LfNfXfC5EyDn5AXJFiDZJ1Ew=; b=Owd7ZjM2tg6I4/iYJ2yBFvCSLEhRb+uGZxZHoiYke/omnbxXf4kNgoG9jM5+Coc68h neHikIdhRiAQdwsltDuAdRTyJbvSB0sNbbehpFQFu3J11sHvIovlbHVGez/S55gq7AfQ bhv0aMVV9L2BupW1ADSvDQVqyuFWYFJzux3NGRe4TEePfCchczjkC6f0KDVwqkpyY7dB YF7G9ppFZJYo0PZfkRpFdH9AoXL8mgT8f5K0+tvstUFcjJdHDoc/pQFGHJDwZukz4BWj I9N9EPYN0P/b7l4AAH3gcizA6uFriMAAaFnQAZvOja+S5Spvrx5gQV7nTKt2LNRnH/Wh Vt4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hSDIT5ag90Nh6sLPPU0LfNfXfC5EyDn5AXJFiDZJ1Ew=; b=rOaiJcXB7y0RpHZhLfHUY8tSVK5zrU7cGe57gPJBPm1whIv83QUDlONJ6N3TY3nXWC CVZTLdAiUsFfEKi4qeAZILrVHWYcj1dBXuoY/eWIrnpMmdIjl8BnkRfqRSAX/Rj64rdw idS8YYV8hRzQtq3l23MmDHWCrNdLHn1LeI5r9OUkq3qh4wMBO6xmO2TtT29Tp6KLbI6Y 1RNKRrEgcYi+qiSmIOmjWiyCXjItGVzhzHgGt8JiuhWc62fmzoNYqUE8VLo2fj1NhA99 HaJAncdZ/xhC65m6rOloXEEfwKCFihYRWdSbA10A63LeA7OY94J0F5hpYfIcch3xv5gE RmRQ== X-Gm-Message-State: ANoB5pl8TiXz9zsy/tw4TylLtwnR2i6w9NWHA/hVXkko04QiwiL5Io2H js/PYNDlqqtUMvdTsRl8Va0= X-Google-Smtp-Source: AA0mqf7UT5urptFMJBCSSyO0aCy3wTeHq9tmFsu1KENoU4r/3a5v+tG9wtYigU9ZcEZk94TlY5FwqQ== X-Received: by 2002:adf:f809:0:b0:242:4576:b6eb with SMTP id s9-20020adff809000000b002424576b6ebmr17366151wrp.7.1671062108431; Wed, 14 Dec 2022 15:55:08 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:07 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Cc: =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH v7 01/11] leds: add support for hardware driven LEDs Date: Thu, 15 Dec 2022 00:54:28 +0100 Message-Id: <20221214235438.30271-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: - hw_control_status(): This asks the LED driver if hardware 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. - hw_control_start(): This will simply enable the hardware mode for the LED. With this not declared and hw_control_status() returning true, it's assumed that the LED is always in hardware mode. - hw_control_stop(): This will simply disable the hardware mode for the LED. With this not declared and hw_control_status() returning true, it's assumed that the LED is always in hardware 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 hw_control_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: Christian Marangi --- 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 499d0f215a8b..891f4821b2c8 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 Wed Dec 14 23:54: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: 634325 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 EFC76C4167B for ; Wed, 14 Dec 2022 23:59:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230097AbiLNX71 (ORCPT ); Wed, 14 Dec 2022 18:59:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44576 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229632AbiLNX6m (ORCPT ); Wed, 14 Dec 2022 18:58:42 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 93C1D5D68A; Wed, 14 Dec 2022 15:55:42 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id k22-20020a05600c1c9600b003d1ee3a6289so661750wms.2; Wed, 14 Dec 2022 15:55:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=HIQLn3R4SCs99bjDVoXYTRZNozVoU+CdDZgHxRak2QU=; b=D1IVLz6ghcphn0qXbSkoviXQk8a5Nq6Dx10LVz7QkVtci/Yopy1+R7vF9AvYj8ClAw uC6SIeQNcRUSSl0BOihVFP+w1kyvlBzB6YIe1NuYQZSg6+gEhe4VG5qlrJX7jQ9K1/mW NtU5S0gKPScM42Y+5FEkH4g+MfkZQxQFLPwASkQ/G4EQRChc8yVirs4XlcYWc120a+C+ sb09itbejdAU4i4eHpGsy/IKkX43ADU5cYxU+PmHi3PVgDHICMNyizctspmN5BM29uVv pLJY9OY+ZIgQgYMMD5sezSn7unXZtU+4MtFbUZu1SBb6JCpAH+/hKO4ntqrwZQQ8asTm /oAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HIQLn3R4SCs99bjDVoXYTRZNozVoU+CdDZgHxRak2QU=; b=mIcqYbQ2z28YnvSCnGS1p4SiVXqimD35vbNbc/X2ZFqix6485H7+isgf5VedbXcA9W dQ51WyzqP/jBq4HXci5p69sFJQ5R2ZYA24VStMVGos5toXBiOfXIfDERdffo634y0UvF 3rU2mGh6U0m5D6J9i5hux35Wn7G2ZpGwatMLT+MuhNqh4jYdA5Ho8aVGw7Ov0FbmIJYU CyIVVrK8OkQBbuTXVLGiEiJ6AHhaosFCXVQLMgrr9ujN/TXXFEEUIi13YJYPhssJOjso nSIJ+K1xLEJdmGuD/i5EZGNz4daqQfUvYK16rUq22kVssc4ziSTUHzpqdrsDfQkXRos8 gdFQ== X-Gm-Message-State: ANoB5pkhQ7wAxK7gjCHL+QLS8Ff6SOD/p6kSP9NvsIZZL7oGqaGpyVAm d65wnRXtGyGe0FrlqXx7C6k= X-Google-Smtp-Source: AA0mqf40/1dqaBUxgU46CXTg4yXTNXGHB92WAaHnahd38QVj9oZVlYFRJ1gC9PPRPhU8YMTyEFasug== X-Received: by 2002:a05:600c:19c7:b0:3d0:8722:a145 with SMTP id u7-20020a05600c19c700b003d08722a145mr20479827wmq.40.1671062110084; Wed, 14 Dec 2022 15:55:10 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:09 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 02/11] leds: add function to configure hardware controlled LED Date: Thu, 15 Dec 2022 00:54:29 +0100 Message-Id: <20221214235438.30271-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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 Wed Dec 14 23:54: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: 634043 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 662B4C2D0CB for ; Wed, 14 Dec 2022 23:59:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230171AbiLNX73 (ORCPT ); Wed, 14 Dec 2022 18:59:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229724AbiLNX6n (ORCPT ); Wed, 14 Dec 2022 18:58:43 -0500 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B4725D695; Wed, 14 Dec 2022 15:55:43 -0800 (PST) Received: by mail-wr1-x429.google.com with SMTP id o5so1477939wrm.1; Wed, 14 Dec 2022 15:55:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=AM6Sy+u27cRKYcUzXWKt9kLEw6zGEH9U/Yts/6M0SW0=; b=DxxSA8R18AgPUYSN71xPuAxxUi18sylXJl5SnQO65+6qhmYsAJdaEHI12mlMqzT3rE u1KLSnYpirb0+3AQI3m++t36S6DCth/0DbvdfJfwLnDUi+ONwHIBhUhNBx3bCuIVli7M dVounvqZRHn/eP6BXkKo0E7FODkoXVmy2b+SrLSIwOVyh36UpGL6zSJysjHeF9A8ds3m riLKuh9D6apfTVO8hiKUcAN7URzzVMeZDVRc7Y726Cgh3IVS1gydxwgZ5TyCgCgdmLO1 x6zi9wNM77V/TC860cfkct/XU5/VEYU2nKm4ynImYKndlFujNkh9DGo3kZ7ZNsp1gYO3 ltGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AM6Sy+u27cRKYcUzXWKt9kLEw6zGEH9U/Yts/6M0SW0=; b=QkrZ0WKodYW6KS+1IpwLWCUKVONpABgq3vBhERq4EvJErKDP5whG8kHUI6kva6bzdZ WlAvX3so3mvH9PDdU59zOnpqSdAhd9QDv8Mj8k97XEuCY4cfdEzg6PrBWVjtXZTqydgy H3e2fZ1XWxZpVz7beeowlduQ1E7qIv6KjtZaPTkw8kdJzKBnkLJN+yw7vYy6QIvLfvyb J5rXZ7UuI6H+FAX/f2fDYbVEjH0WIHTsdyRrbl6BWnkB8D2w+uyVlz+kP/JGAHrdlfiE wB0NYq7Hj9UvQXETaTqwpcz6X8C05xkdzKZW9j13kKIthptPo7swgJiBSpGbDBIuE0C+ Uq3g== X-Gm-Message-State: ANoB5pl00MPKBT+5oLugOovfb3MR5W6jcnbIJ26atT/gbnuIFJO27J43 Y7COo5UyJalTHktr6MjOXhw= X-Google-Smtp-Source: AA0mqf6TMHJlRLvpVfuGxfWdLdTWGdGPX/HSkD9/ya9h2pPu+tbfd9zeukjLn4mzk9k3ASMWHg7rbA== X-Received: by 2002:a5d:654c:0:b0:242:65d:c401 with SMTP id z12-20020a5d654c000000b00242065dc401mr17724702wrv.6.1671062111732; Wed, 14 Dec 2022 15:55:11 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:11 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 03/11] leds: trigger: netdev: drop NETDEV_LED_MODE_LINKUP from mode Date: Thu, 15 Dec 2022 00:54:30 +0100 Message-Id: <20221214235438.30271-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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 Wed Dec 14 23:54: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: 634324 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 94776C4332F for ; Wed, 14 Dec 2022 23:59:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230188AbiLNX7a (ORCPT ); Wed, 14 Dec 2022 18:59:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230011AbiLNX6q (ORCPT ); Wed, 14 Dec 2022 18:58:46 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 079385D69B; Wed, 14 Dec 2022 15:55:43 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id h11so1415834wrw.13; Wed, 14 Dec 2022 15:55:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=GIse2mS6EUrosfauTgonOKCy80Gj0M+YuBtbKf2QcRU=; b=opBxg9Aw+zpzwjImlK0YP8I0L/gsointpa3zlGLwVw0yi63IsTRCjZR+Dov9f18XO5 3QQpM2xhUoESahtUFdJZWA8DQdp6TDExOs22zdVcOgWCmkTcQvTIzuEi2v52f7xV0Fvu 4jNoHZAozweRJY+tJ7UsYP/nSoEY/6gWY17Q4ZASLcUkBKG+gdhNhFNhSrkVsVGzFXsO 3enqERpLTgSUHxE0HhcZ/hE7dWdMGKom+tfteA6nvwTtP9Cytdrr2ZL/Lc+92CiLctai lIL/+dwZ0FZFehzBRfH1G/I5Lhx2lxKWAvj5UzLpFSyDTn1k+Yop3j+f/vxn7tNv7ElX TU6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GIse2mS6EUrosfauTgonOKCy80Gj0M+YuBtbKf2QcRU=; b=iOFcIZicy9ssLvHBrFsYToAxMEBjDZcLxcN+w6gka4YUvF0Td8AfTSpyU88yX9o+cU AMXsrLax8B0f50KxhAswo49qbsKvuEO8qC9CyBZWwUCPX7LOHvu3IE6VRPtf57VYcCPY SEAzCVD49xjYK9u4x2SdYAYLBPx5eHWfBFQ0YSurGzUv9IFNci1AqpmAUPb8Y/v5F2gE vPkebuCareU4QWkXF9Bth/j/ET7TN9KqOkybzuHIeLoZRA2W57APcghFgkIcqk9ps8hp /UmkqLahWJ50Z76MHVyVUhjriGbmqHbKrcWH5p5LdMLpyxren5TCSqvk9EXjpyWMEAwu VgPA== X-Gm-Message-State: AFqh2ko5MfuOhPzzBbVrVQ2gx6btpa7on+qbb1JyjdX1xvGOFbZGKmFp XiI0mLWMMDzEhZ+bFf9PZlo= X-Google-Smtp-Source: AMrXdXs7kkdKEgQh9iyjXfbOEio2vB9D9Eli1VL8wBpvPO9jgGdq5kbhmb2RMtEgO7w0wNQRTQKkwQ== X-Received: by 2002:adf:e410:0:b0:254:9b64:8883 with SMTP id g16-20020adfe410000000b002549b648883mr4902381wrm.21.1671062113315; Wed, 14 Dec 2022 15:55:13 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:12 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 04/11] leds: trigger: netdev: rename and expose NETDEV trigger enum modes Date: Thu, 15 Dec 2022 00:54:31 +0100 Message-Id: <20221214235438.30271-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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 Wed Dec 14 23:54: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: 634323 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 0CE6DC3DA6E for ; Wed, 14 Dec 2022 23:59:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229732AbiLNX7k (ORCPT ); Wed, 14 Dec 2022 18:59:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229913AbiLNX6t (ORCPT ); Wed, 14 Dec 2022 18:58:49 -0500 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE74A5D6A8; Wed, 14 Dec 2022 15:55:45 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id u12so1427819wrr.11; Wed, 14 Dec 2022 15:55:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ERnunlg4Are2RjzI+mRhVTdhmnhLu7rf9W2UfAXj16A=; b=Y5c1IhUoOOWervZyFKkPlyf3ICr6PsF7TStOeqbI7ka4EtTbxdISRWxmia6va6VoVz aH9sxUTaGNziC4i8fyV6SDtgbFhnwbamFZmDP4QESPZLoCaF+4fcGuf4Xcj3QqHpIwIP Rs3XRlVQKHd5qI7HOmqaVPrELXMYZwL6OrQBC8RGTCtRwqGAN9XXLUXyi4kU6uJEWuSd nA9xwruhPfwGZUkFtALC3fYsap7QZ2ckrXHK6zb28SF76pRomJJ/MgTRduwWDntrOL5S eaO+LDRuNMecENWWEUcjP2rBydr6jlI+l3UCqOdjTlvi9C/LUB53DGTMjJmMO5/BEzpI mpag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ERnunlg4Are2RjzI+mRhVTdhmnhLu7rf9W2UfAXj16A=; b=zAwl59Y1RDs/zz3sXNeA7886IS7GFuAu9+yy7+vy926NnElG/NxFbAyiYBp3C61Cmx 2YOMOLmKF6+CAEWgDKin6nOA0WWc/OQPLLyVdvFXw8NhBvTRZE+hL3mHPGKntTVQT9ml GB/j/sxjOoLUaLfNfKdGbsvrDOurpfTkuS19jg077gcGJAIa6mx71K58jN4tsQmWAW53 BWdHcgOjBLV9UXJ+YAuYS1HgtloBAJBYcgJ1rZeasl12g9udmYa6boi1PJ53jr2AkRh9 7wCSFCLrmTh/L2x49aCujw87Ne9mO71GcvNZyg27llLAHn6KyESa80yyLTAwMBE/kyfg bYfA== X-Gm-Message-State: ANoB5plUdD2Kl04TbXxWglLce1Cxzt1P/KwF4AqDb1W1kOiYfQrhwCRe gnbfa82+9h17qrHPznZoOnw= X-Google-Smtp-Source: AA0mqf4GXLQZX1ebAeL145nIzjkfwLXs43y5ktVVWt+Z3d+aqkhYIKbFZY9Vemcm3a+rJoRtw3vmYQ== X-Received: by 2002:adf:ea0d:0:b0:242:b6a:1c9b with SMTP id q13-20020adfea0d000000b002420b6a1c9bmr15565115wrm.59.1671062114938; Wed, 14 Dec 2022 15:55:14 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:14 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 05/11] leds: trigger: netdev: convert device attr to macro Date: Thu, 15 Dec 2022 00:54:32 +0100 Message-Id: <20221214235438.30271-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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 Wed Dec 14 23:54: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: 634042 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 6F149C3DA6D for ; Wed, 14 Dec 2022 23:59:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229780AbiLNX7i (ORCPT ); Wed, 14 Dec 2022 18:59:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229768AbiLNX6w (ORCPT ); Wed, 14 Dec 2022 18:58:52 -0500 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BA935D6B3; Wed, 14 Dec 2022 15:55:46 -0800 (PST) Received: by mail-wr1-x42f.google.com with SMTP id h12so1433839wrv.10; Wed, 14 Dec 2022 15:55:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=O8VEqn1f9hQgSk4zsH0ZS+dGwOqygrQKRIv4lYmvhVU=; b=HzwsZtHoobMLXGAbSQ8GEDfHllAQlen6Y6PPe7Dxc005ffypjDa8cGh/iqjubLfUX6 9BVEq1IY6BZwZJVbJVuFo/8s/wLB/hW3ic55AIpAKm3dTYQtejTvKtTfFZnfBuWqF+cY 3iY0YCSWskVjPuusL+y31yLF9FQK9Iv5219JY7DbdSyH+M1xH2UhtdCKGY+Epzx6CFm3 xpjoAA7IMWGKOj7gJT0EkAA3v4lQtQRCpKLBaFtCK4EV6L0qWiBWtxwUayBQAR1itkPq REmposvouSyy4OuRTBIqd4O4vCDlKQ+gTa97FzeUHlT4CK2cv2PhJFiooOhPcPg3BYJK qNMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=O8VEqn1f9hQgSk4zsH0ZS+dGwOqygrQKRIv4lYmvhVU=; b=i61QlZXSzHf7axItnAyv+6ZnlRqVhGfOk8d5vlFo8OBtTe72SESajrI2+bEzv5x7cd veGAEdkwSyd6kKEtwaRT9XTbis71DJWY56qLp6kOiZwEcglIRGkASItfbzu99N3A8VvX p+HvTzdzFeZyQWl880tsWZSY0cIwydHR+eUnTOTjZ6q7lgmtg41gt/5KTAvaDpHB7c1H mrBfj7DlYKYI6cCkdVrYPay3C+hVJzk6Rz1f2UE+mZcy7XVlmt1UMX2bPMoh+27sWF08 uziZIlWdOuqXqtoFzdhcNDi3twycHSxD9ZhttpPBkXXUaGIvkT/BWh/ZxOjX67qffHi6 dEQg== X-Gm-Message-State: ANoB5pkqebG3o2gYJnhm4SfFnqWRpe/b99+NoR6jXZ8G4gEf/osxD3Ev 36GrmU3loU012XvMdufXK/w= X-Google-Smtp-Source: AA0mqf6Uvus+C+C/boDPbm3QySVMtQ/MtZA5vgX/JPaeM5upf4K54TbeFCXocEwVlHj0L9MfGgze7g== X-Received: by 2002:a5d:4d4c:0:b0:24e:79f2:a5bd with SMTP id a12-20020a5d4d4c000000b0024e79f2a5bdmr12280368wru.47.1671062116688; Wed, 14 Dec 2022 15:55:16 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:16 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 06/11] leds: trigger: netdev: add hardware control support Date: Thu, 15 Dec 2022 00:54:33 +0100 Message-Id: <20221214235438.30271-7-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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 Wed Dec 14 23:54:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 634322 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 007B3C4332F for ; Thu, 15 Dec 2022 00:00:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230138AbiLOAAo (ORCPT ); Wed, 14 Dec 2022 19:00:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230194AbiLNX7a (ORCPT ); Wed, 14 Dec 2022 18:59:30 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D4902AF0; Wed, 14 Dec 2022 15:55:53 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id ay2-20020a05600c1e0200b003d22e3e796dso702444wmb.0; Wed, 14 Dec 2022 15:55:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=3SLBazAEXX8c9aNBWqHC2LBtXZiu/faWpD9Dr8HQgfw=; b=Sd5w+zrgozdOgXZu3CYRiWzYFIYHBJRZlWErRQTWRVQ1H/7gIk7kbasFVgObvrIF8D UYXyf8SnqpjvzX43aWNnKVzJifB7JBhFevkYlwY6TD46RhEglensBZVsmOv290lLgxFX ABzeuYgT/bGs4JalWs5pFUOygX/yX0qeJBJKB7RrGztMtuTYZ/TWJPh+SPq2c/pi4Jq5 0Q6GmQ1pPaP9pvG+CWw/sZ4M2E6bms/rCe5X2nbgg41S9G8YXI9H727cDitLzpAuE4fG ye6e/KEG/5rI4RjQZ7xjaRxBiSULOLxGa9YWRAck/aKKPfTZV6P8pb1orgIKvyCycn/k v59g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3SLBazAEXX8c9aNBWqHC2LBtXZiu/faWpD9Dr8HQgfw=; b=uJChWfZCX1nzYrUsBlW8HoPeBO2si51K/WEdzm0CS3rQUd8Ob9w5SP1x1zr3z8VlTF Wfxo5gtTss0QM/m8DNMsJJtFRqWDZLdNSb9L2aIUKatruar+cw2LSmuCAc1iQVUp0S0t RrtGQwGnFHFLgdGpRDPd0HDU0bKIOB5xWRdX6X6/p5bC4vuU+hRElhw+9Uo6LWVY6zy4 jtoA7tDBK5Xps1GPGavQekiyywTfjeer5oA/pE2jTXIYkqwML754CIeHnSfOW2ZFwgEp C4ndahp8j7WKqlFLt4w/uEPV9DhcLwFpoir0IdeHSQStao0SNavQELGBMI6qpZLxHQqx f3VQ== X-Gm-Message-State: ANoB5pniqz7nE84XvqKgyfQNaSiy8r0FLJ/7rb90yNNZ5waZqohqSHQi MNcEzr2aDqpQp0G8w4TU3Ks= X-Google-Smtp-Source: AA0mqf4HhPWe4wji4lvvDsBpMmP2ENS+uedHUEMV7XB4XaA9lxnWMhH5PvaIhmvQeJo2RK9RqKmAtg== X-Received: by 2002:a05:600c:795:b0:3d1:cee0:46d0 with SMTP id z21-20020a05600c079500b003d1cee046d0mr20434927wmo.25.1671062118403; Wed, 14 Dec 2022 15:55:18 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:17 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 07/11] leds: trigger: netdev: use mutex instead of spinlocks Date: Thu, 15 Dec 2022 00:54:34 +0100 Message-Id: <20221214235438.30271-8-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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 under spinlock softirq. Signed-off-by: Christian Marangi --- 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 Wed Dec 14 23:54:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 634041 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 1A5A0C10F31 for ; Thu, 15 Dec 2022 00:00:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230017AbiLOAAg (ORCPT ); Wed, 14 Dec 2022 19:00:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229614AbiLNX71 (ORCPT ); Wed, 14 Dec 2022 18:59:27 -0500 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84E5EFCED; Wed, 14 Dec 2022 15:55:56 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id h16so1420268wrz.12; Wed, 14 Dec 2022 15:55:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=9MMLnTteUrqIxH9MlpZEihuzNBu6Jv5Ux8kWMNNeLhU=; b=CrDS8suCiCLiSApldYHkNJ+1wtFo6lr4JJPQz5VoMWHZs9D6CTZgBtF4OlJz8Ud5ya 2WF+NYj2sT6AnHKaDPVhyoGUi8qHDcuK2lFrGKKo1DvBdKWWadt3IkM1T4EFgIb+HVIN j6TLXcYr0Pf2fiJE9v8cPKuuTlbpPyPezXCuxcK3FlQEolAj3fr1TZ79YzF19dXeFVr8 vy0dVJ9Xw2N0LVnwqVBEEpKoKSUBYFqqqAJ77o1aFKnvafR/ASU7tJosZNhoowkaZY03 Rl+Abn1keOOLj0fWgroz8ylRmPPsm/7XRTtwc2eKBdXMLb8PwHCczJ5j6HW0Nk/ogExc UinA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9MMLnTteUrqIxH9MlpZEihuzNBu6Jv5Ux8kWMNNeLhU=; b=H1MOk6fTFK34FYlo9JpJHPLrCJceJ2uu0uG4pEYrMsPzQxEK8LJyO/ZrH+Zqa8lbUO JOxvMftUu8GdH8wDs6Fh6n9XtVIlNNP1eBXkhhEYbQDGI6NJxl9191zFXvrSZttsmHJM vay2+z4S7/jK8hxp29B79rXGdj2eZGtzLTOqJo+/k24PWK/o0uoL/Gok8cZlhGvx+EY2 1YlKSo05AOS2Ov2BQBM2UphmFSJog6MMTscTnJxY3RR3Xxd5WrlcRvGRQwGPDqdNTg7j NbKSipf8Dz04f575R79ZEAkAw1EkEkGthc0S5t4eZYBEU8QEQDl8+rX0Yu15MCkbfvx7 diCg== X-Gm-Message-State: ANoB5plzZcsRDlUGpnBLhCGUtNWlasKlJ9roQbLDAKrp4HVRpbPuYfpW CUGbsCbBqyaa2DWVU9boZLM= X-Google-Smtp-Source: AA0mqf5Lkgg/dpJOYekqqk1uqf9OtMA0S0/LY06DpNjzTwpWpcoCyaCWhMtE0+2jpAlCx+WxnORkUw== X-Received: by 2002:adf:ec05:0:b0:242:5ceb:fafa with SMTP id x5-20020adfec05000000b002425cebfafamr16573139wrn.34.1671062120107; Wed, 14 Dec 2022 15:55:20 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:19 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 08/11] leds: trigger: netdev: add available mode sysfs attr Date: Thu, 15 Dec 2022 00:54:35 +0100 Message-Id: <20221214235438.30271-9-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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..3a3b77bb41fb 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 Wed Dec 14 23:54:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 634040 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 90BFEC46467 for ; Thu, 15 Dec 2022 00:01:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230212AbiLOABD (ORCPT ); Wed, 14 Dec 2022 19:01:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53414 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230156AbiLNX7e (ORCPT ); Wed, 14 Dec 2022 18:59:34 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C2D3396D7; Wed, 14 Dec 2022 15:56:00 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id i7so1445083wrv.8; Wed, 14 Dec 2022 15:56:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=rRwDJXgAmTfDMJnqkydYiAsYVO0tTqwWRPMDyDIA3K4=; b=fki68Ia+FHYPxe5KSFHG4ZjHvDoY8LUNbwK9p7N5AMGZYRw0nW1KjM/GAYgCcujIvN eescXs/vUIgtGcv2weVmwRzY9DqIcm+zGdJEQhGcPGfFh3fTi0/tAedkCWrRgumPP9dQ 1yKNsfeuov6HOc9H8uVzSZE5+Yj0wFW8H9ILKGa1IDJM+wUxR5c3GP8zPXpR+PIj5dZd wDDauc93bwVQ9L3YD1/JImPPk7hgyUVAMpaJ3RuJpesJIimxywaYpVyPXt0XKC+Ufhtw +aGE1LePuRBl0itX9n0JWicfmH53CDqkm/y3QKQ/A9pH6dgFwJbWP6trS7u2ahtY91fg 5jaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rRwDJXgAmTfDMJnqkydYiAsYVO0tTqwWRPMDyDIA3K4=; b=JPh1Y+/rg1nFlqTq+jxCh7GwWe7wi3fnBdk90jHSvLNFcZ3guPcsLv2a7zVZVMAIxR XrzxqhFix7d78Q7Px7keqI4SA8FMShJUs2hc7eTE/9HTELkACSQj+aKVymeKSgdosU4k mL+VC0mWnN/wnedUlcJMcKuAc+c25dD/HCtPxhlPiUm0Evmd//DIDyNoPAAblAkTHf/t KvAu5PZ2n9UribaJ10D8jy8bJbQP6vhpBJRkYEA2m86P/jQ6pz0eWG5N8YzPXlJueqpW mPxZxIxcl80UE07Fr0tUFIa8+/9UgL2ctqHe03DbTXFH2W8F4fUQinDywFnltl4VuS0N CoSA== X-Gm-Message-State: ANoB5pk0Webvg2DSfxA6ppd/uQqDLlDhEhDhU/H0xqr2xDQtkgYMY2Bn cm9EG4TDwDs68P4zv05J0Ak= X-Google-Smtp-Source: AA0mqf4q39KC0NfaDQJFlVPhEulQbgvCtjW9TEL4j/IONO5+Q9je33aEi0Z2YYL8pOJv+mcjUxUC3g== X-Received: by 2002:a05:6000:234:b0:242:29fc:ad51 with SMTP id l20-20020a056000023400b0024229fcad51mr17235558wrz.20.1671062121916; Wed, 14 Dec 2022 15:55:21 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:21 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 09/11] leds: trigger: netdev: add additional hardware only triggers Date: Thu, 15 Dec 2022 00:54:36 +0100 Message-Id: <20221214235438.30271-10-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- 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 3a3b77bb41fb..880d5e65f7a2 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 Wed Dec 14 23:54:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 634321 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 8281FC4332F for ; Thu, 15 Dec 2022 00:01:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229974AbiLOABZ (ORCPT ); Wed, 14 Dec 2022 19:01:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229991AbiLOAAg (ORCPT ); Wed, 14 Dec 2022 19:00:36 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A87DC4AF17; Wed, 14 Dec 2022 15:56:05 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id co23so1462559wrb.4; Wed, 14 Dec 2022 15:56:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=FYpcQA640PQ5mpbbGU92H19eoMYr3sS0AwuQTVM+e1c=; b=YbY4F7PXT2e/bp/Qa5NZgruRVCW+yWDkxF9o7BFQg93Row2e4EfZmnAtyYv8psF6wp e4o+6jLSjbkGm82nf+74U1T3r/Sq6jI68qom7GWvNODEWwhEkO32Gozbjz48no3L3YST k6CPe/DiagP1LpxvRx9ROwthcrfhRLkC/LvL/k3mrw891bAyawCWk9tTmMg6EKZaF7O/ rEywHszxGduhcDGvztmKNidWB+Q74wsYxJJSHB1/2vLhyTsUj01f9aogF+x6YfwZQEzs XJG2v/LT7dcUeQ8M5DM2Q/J3oMvwy9YBYfG/iypNlCFmCCSNDaM1jJg45dTRluyeqEVF bcbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FYpcQA640PQ5mpbbGU92H19eoMYr3sS0AwuQTVM+e1c=; b=LXltQMnhqD+CrBw7qo4pAmU4H3/H9CUGkgFHf+kgaIkbRrQ0ei+tGTIYL/fx142t3+ yfgM4+ose0Xq7x6wpx4+3+aAYfpojKyzhX5b+ziXwjbdwWwwUNwZsISKTLEgE7Le06WA 2IeRCftEY2QlkeLCjC7eT0nrBsQlN6ULpTM6DN9GSiwvG1+Zj/IYvUPRJwKkDCdIp4T7 LbcGiyrMNnLZsLf4Z8Njaeg02LzCxvlDjzasdjtKlS08Dfj7b4Ve/ocyn91mSegVyY89 Pekxg/VAn1ntARackyXdsjrl9vtkn6GQpr6LKIff4rFpNJyep3Fs6qguFJMuViUU9/8f VCng== X-Gm-Message-State: ANoB5pmcehn1evGdpysq0ruYJnDjDudLdJdME41FllmU0eogGNaRV9aS I71PpHXYLcBMxJZoFVVnu30= X-Google-Smtp-Source: AA0mqf6x04gxvCam644zOrIjNk84E93UZvN9O1amRz15LAyB7/tvAUbq9pbFTLA91uzKehchWWSUKg== X-Received: by 2002:adf:e590:0:b0:242:880:20d2 with SMTP id l16-20020adfe590000000b00242088020d2mr16274314wrm.48.1671062123598; Wed, 14 Dec 2022 15:55:23 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:23 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 10/11] net: dsa: qca8k: add LEDs support Date: Thu, 15 Dec 2022 00:54:37 +0100 Message-Id: <20221214235438.30271-11-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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. Adds support for leds netdev trigger to support hardware triggers. Signed-off-by: Christian Marangi --- drivers/net/dsa/qca/Kconfig | 9 + drivers/net/dsa/qca/Makefile | 1 + drivers/net/dsa/qca/qca8k-8xxx.c | 4 + drivers/net/dsa/qca/qca8k-leds.c | 406 +++++++++++++++++++++++++++++++ drivers/net/dsa/qca/qca8k.h | 62 +++++ 5 files changed, 482 insertions(+) create mode 100644 drivers/net/dsa/qca/qca8k-leds.c diff --git a/drivers/net/dsa/qca/Kconfig b/drivers/net/dsa/qca/Kconfig index ba339747362c..be67164a444e 100644 --- a/drivers/net/dsa/qca/Kconfig +++ b/drivers/net/dsa/qca/Kconfig @@ -15,3 +15,12 @@ config NET_DSA_QCA8K help 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" + depends on 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. diff --git a/drivers/net/dsa/qca/Makefile b/drivers/net/dsa/qca/Makefile index 701f1d199e93..330ae389e489 100644 --- a/drivers/net/dsa/qca/Makefile +++ b/drivers/net/dsa/qca/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o qca8k-y += qca8k-common.o qca8k-8xxx.o +obj-$(CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT) += qca8k-leds.o diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c index c5c3b4e92f28..90916d8d8afe 100644 --- a/drivers/net/dsa/qca/qca8k-8xxx.c +++ b/drivers/net/dsa/qca/qca8k-8xxx.c @@ -1690,6 +1690,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/qca/qca8k-leds.c b/drivers/net/dsa/qca/qca8k-leds.c new file mode 100644 index 000000000000..b51cdcae31b2 --- /dev/null +++ b/drivers/net/dsa/qca/qca8k-leds.c @@ -0,0 +1,406 @@ +// 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; + + 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/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h index 0b7a5cb12321..5c535baa7139 100644 --- a/drivers/net/dsa/qca/qca8k.h +++ b/drivers/net/dsa/qca/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 @@ -388,6 +426,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; @@ -412,6 +463,7 @@ struct qca8k_priv { struct qca8k_pcs pcs_port_0; struct qca8k_pcs pcs_port_6; const struct qca8k_match_data *info; + struct qca8k_led ports_led[QCA8K_LED_COUNT]; }; struct qca8k_mib_desc { @@ -517,4 +569,14 @@ int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct dsa_lag lag, int qca8k_port_lag_leave(struct dsa_switch *ds, int port, struct dsa_lag lag); +/* Leds Support function */ +#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 Wed Dec 14 23:54:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 634039 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 DCFA4C4332F for ; Thu, 15 Dec 2022 00:01:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230111AbiLOABt (ORCPT ); Wed, 14 Dec 2022 19:01:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230118AbiLOAAj (ORCPT ); Wed, 14 Dec 2022 19:00:39 -0500 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B231C5FB9B; Wed, 14 Dec 2022 15:56:10 -0800 (PST) Received: by mail-wr1-x433.google.com with SMTP id f18so1459965wrj.5; Wed, 14 Dec 2022 15:56:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=nUaYB4mYM1gCXOfo+68xcCeBFVZGQ3PaFqb+K6GJCtg=; b=HEkM75XnY1gKLBNPSXMywD87ktVghvhjnMNiIPF3v+daRENgBk5tmBqIZfv6NfsAS+ crGaojmo67uH4di/kyoTFvSXE9g2U1/YAXwZri37aUh1CfhmjV+W4BqFWrlYBAEprcMY v56VIwXrcycWiUTbg/yeKA20NNsX3vVVRYq8RO43cx5iSymYBM71JxvYWLX88uRIQ0UP nYee0ET/0g58lSVZK8emyXw3sCx/6MgJywAAa495kgT+NWzNs1N4bXHBrMoBubMJkOwR 9fXtdMTl4p1eWGiRxu5UvAx/I/hJJIjyCIG8G5r5cOMC1zU0FTv/06ugeJJkYa48RMtj d2RQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nUaYB4mYM1gCXOfo+68xcCeBFVZGQ3PaFqb+K6GJCtg=; b=M95cUJHDMUMlPXYNtDbwVWwhZhECUZis8mWUmrQnxHEpH6m82obF+/iMOvcU9vI8G9 Jt58BXbA/1jU7ck/kQGCCbjY1khrzJmvCGJkWNrh4JVG18HR1OtbUKGoNbT/RJUGvuB8 oJaliSK1KR5glcKh/VwJvmV+aXGtNaeI96NCCH2pZykSHAyPRJgHOBY7D1XtcOLp+WNo XZZwO1FXnQMby0zcy7vqRYjF2Lzbv51Gk2T1FBV+GfFdhFvSKkeXfdIbMd8EqSapjcr1 8zlsl3xtJhbWVHYaFu9a3wbpVpufa70Mic2f0Um3wkPVzbFBm8UqoYsw6mOwAbof/1FD 68eg== X-Gm-Message-State: ANoB5pmpaiqN30cCWwTSKE5zLhEyEtFGqwMvMCMqKD54TWdsV075uDne Am71nDLF41NOupsyYyD4sc4= X-Google-Smtp-Source: AA0mqf5aeoHs4hzEeRyaOmqpYUikvH6DDBAW6xVPEu0JqDYRI8a+6BmkteGHz5LGP2KZZpxAcuCsxw== X-Received: by 2002:a5d:5b1d:0:b0:24b:b74d:8012 with SMTP id bx29-20020a5d5b1d000000b0024bb74d8012mr6793734wrb.18.1671062125288; Wed, 14 Dec 2022 15:55:25 -0800 (PST) Received: from localhost.localdomain (93-42-71-18.ip85.fastwebnet.it. [93.42.71.18]) by smtp.googlemail.com with ESMTPSA id u2-20020adff882000000b00241d21d4652sm4163549wrp.21.2022.12.14.15.55.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 15:55:24 -0800 (PST) From: Christian Marangi To: Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Jonathan Corbet , Pavel Machek , Christian Marangi , "Russell King (Oracle)" , 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, Tim Harvey , Alexander Stein , Rasmus Villemoes Subject: [PATCH v7 11/11] dt-bindings: net: dsa: qca8k: add LEDs definition example Date: Thu, 15 Dec 2022 00:54:38 +0100 Message-Id: <20221214235438.30271-12-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221214235438.30271-1-ansuelsmth@gmail.com> References: <20221214235438.30271-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: Christian Marangi --- .../devicetree/bindings/net/dsa/qca8k.yaml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.yaml b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml index 978162df51f7..4090cf65c41c 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$": @@ -202,6 +204,7 @@ examples: }; - | #include + #include mdio { #address-cells = <1>; @@ -284,6 +287,27 @@ examples: internal_phy_port1: ethernet-phy@0 { reg = <0>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + 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 {