From patchwork Tue Jun 1 00:51:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 451632 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C200DC47080 for ; Tue, 1 Jun 2021 00:52:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A5F6E6135D for ; Tue, 1 Jun 2021 00:52:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232268AbhFAAxn (ORCPT ); Mon, 31 May 2021 20:53:43 -0400 Received: from mail.kernel.org ([198.145.29.99]:45844 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231714AbhFAAxm (ORCPT ); Mon, 31 May 2021 20:53:42 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 74A1F61263; Tue, 1 Jun 2021 00:52:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508722; bh=QP6yKnzoGT0PCjP+hekaoYcOmX1Hc7jwPEsvbRqOPPs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DdtfAmfgkWKifFokiGoLBYW2/VFrZt7i66X0WQctXEiXPykBxPFcSfIJUdK44J23h 1Et63P4yKjVaWhnhKtzP89mW+2G1Kakb9KOPdaIvCoZ88MCmKjTU64HhNTGfwDBjPP hMDBf+ADS+NPo/FYsqtx8J8lN5XiL/nBsHRWkOsj9sqBwIFr+P0ka5lIEHjzw68AVQ pOGJpbYGM3tWzkEyF1+gjN1dvJsSu29Tt7+N6/qECaAgSSRgnd+o/ERS1w+9WthyZY YQcaFnwQ6rwywcxwCjVkRQDabIt+DqDP1PLm9ce2BEA+iDqHG9hWvjJ7OGElFFLerf QXmxBq6w+PjLQ== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 01/10] leds: trigger: netdev: don't explicitly zero kzalloced data Date: Tue, 1 Jun 2021 02:51:46 +0200 Message-Id: <20210601005155.27997-2-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org The trigger_data struct is allocated with kzalloc, so we do not need to explicitly set members to zero. Signed-off-by: Marek Behún Acked-by: Pavel Machek Reviewed-by: Andrew Lunn --- drivers/leds/trigger/ledtrig-netdev.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index d5e774d83021..4f6b73e3b491 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -406,12 +406,8 @@ static int netdev_trig_activate(struct led_classdev *led_cdev) INIT_DELAYED_WORK(&trigger_data->work, netdev_trig_work); trigger_data->led_cdev = led_cdev; - trigger_data->net_dev = NULL; - trigger_data->device_name[0] = 0; - trigger_data->mode = 0; atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); - trigger_data->last_activity = 0; led_set_trigger_data(led_cdev, trigger_data); From patchwork Tue Jun 1 00:51:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 452849 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 352D9C47083 for ; Tue, 1 Jun 2021 00:52:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 18A7461376 for ; Tue, 1 Jun 2021 00:52:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232480AbhFAAxp (ORCPT ); Mon, 31 May 2021 20:53:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:45910 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232437AbhFAAxo (ORCPT ); Mon, 31 May 2021 20:53:44 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9232861375; Tue, 1 Jun 2021 00:52:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508724; bh=bFOrxpR/PUGl/FkcGxVH/b9ufR5syYBjPvKhU1yW9Hg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jZ6ilhjolG8h4EH0OD/Ktew9w+fq0TQV8zKloE3rzbq8QStJA50QeO22n7vpSTctE QsjxhdtpcTKl1PQwVE0A0mooCv3SpJa/aAWjQZcIJk5Hk9RExc1oML3aEd2l697cdX AbwpFITEQnKiJPljIyqyQFfD9qDlu5GJVqcFgVtw8uO+WnFu24W3FSGgZtVDpAXOT+ OekCwCLH7UxblqrsylvuyylZVeLeiAWbZIcETCJ7BJ+3Uv4a0ZEiku12wKeG5a++ct yCX0JqujlE4R0qMJ29YUpzpSvRtPNvcqRcLtK42+zZvQjiU9XqRqsNX8ErUC7Jjrh5 8sP8jCCg+RPaQ== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 02/10] leds: trigger: add API for HW offloading of triggers Date: Tue, 1 Jun 2021 02:51:47 +0200 Message-Id: <20210601005155.27997-3-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add method trigger_offload() and member variable `offloaded` to struct led_classdev. Add helper functions led_trigger_offload() and led_trigger_offload_stop(). The trigger_offload() method, when implemented by the LED driver, should be called (via led_trigger_offload() function) from trigger code wanting to be offloaded at the moment when configuration of the trigger changes. If the trigger is successfully offloaded, this method returns 0 and the trigger does not have to blink the LED in software. If the trigger with given configuration cannot be offloaded, the method should return -EOPNOTSUPP, in which case the trigger must blink the LED in SW. The second argument to trigger_offload() being false means that the offloading is being disabled. In this case the function must return 0, errors are not permitted. Signed-off-by: Marek Behún --- Documentation/leds/leds-class.rst | 22 ++++++++++++++++++++++ drivers/leds/led-triggers.c | 1 + include/linux/leds.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/Documentation/leds/leds-class.rst b/Documentation/leds/leds-class.rst index cd155ead8703..15fa05c14afe 100644 --- a/Documentation/leds/leds-class.rst +++ b/Documentation/leds/leds-class.rst @@ -169,6 +169,28 @@ 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 offloading of LED triggers +=================================== + +Some LEDs can offload SW triggers to 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, both the trigger code and LED driver must support this. +The LED must implement the trigger_offload() method and the trigger code must +try to call this method (via led_trigger_offload() function) when configuration +of the trigger (trigger_data) changes. + +The implementation of the trigger_offload() method by the LED driver must return +0 if the offload is successful and -EOPNOTSUPP if the requested trigger +configuration is not supported and the trigger should be executed in software. +If trigger_offload() returns negative value, the triggering will be done in +software, so any active offloading must also be disabled. + +If the second argument (enable) to the trigger_offload() method is false, any +active HW offloading must be deactivated. In this case errors are not permitted +in the trigger_offload() method. + Known Issues ============ diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 4e7b78a84149..372980791b87 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -177,6 +177,7 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) flags); cancel_work_sync(&led_cdev->set_brightness_work); led_stop_software_blink(led_cdev); + led_trigger_offload_stop(led_cdev); if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); diff --git a/include/linux/leds.h b/include/linux/leds.h index 329fd914cf24..b331e7bceac3 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -148,6 +148,11 @@ struct led_classdev { /* LEDs that have private triggers have this set */ struct led_hw_trigger_type *trigger_type; + + /* some LEDs may be able to offload some SW triggers to HW */ + int (*trigger_offload)(struct led_classdev *led_cdev, + bool enable); + bool offloaded; #endif #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED @@ -403,6 +408,30 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) return led_cdev->trigger_data; } +static inline int led_trigger_offload(struct led_classdev *led_cdev) +{ + int ret; + + if (!led_cdev->trigger_offload) + return -EOPNOTSUPP; + + ret = led_cdev->trigger_offload(led_cdev, true); + led_cdev->offloaded = !ret; + + return ret; +} + +static inline void led_trigger_offload_stop(struct led_classdev *led_cdev) +{ + if (!led_cdev->trigger_offload) + return; + + if (led_cdev->offloaded) { + led_cdev->trigger_offload(led_cdev, false); + led_cdev->offloaded = false; + } +} + /** * led_trigger_rename_static - rename a trigger * @name: the new trigger name From patchwork Tue Jun 1 00:51:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 451631 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D4FBC47083 for ; Tue, 1 Jun 2021 00:52:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 384A06139A for ; Tue, 1 Jun 2021 00:52:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232513AbhFAAxs (ORCPT ); Mon, 31 May 2021 20:53:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:45962 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232448AbhFAAxq (ORCPT ); Mon, 31 May 2021 20:53:46 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id B1A0361378; Tue, 1 Jun 2021 00:52:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508726; bh=Ki2jGCnqGAph6ha7Ohk+RDeT3gTHa2qj3aSUzC9cNX8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t/JKgmMU/UNqulRBTa9IQIhDEvJlq7P3D+Qd47vzMebIhknhxwd6vkug2TzXMHnej eIWGNSea2Sp7fHMWKeLufc0MIc5qWTjWKPmC9CVw1+U5JpZ7/im2RaxYHpqrkImOh0 a/Hfv2RLqyeKlhuUu7dXUsM0UkUeqmMXxSSttlb8rQACX9YepF+sXE2oVEpT1U4egc 4xPP8L6skUHh3trz36iC91ruG1celxbcUcG0AgEJLEKsUSgJ0c5c1VIy24Z0pN7GH6 wvv0TaSUQ1pyE22lwUGFqLJOJcNcd2dsfLPQSg4YcM1ILlNLTHRqv6wDsUJAgCVeAk LyKK/FKidZ5rg== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 03/10] leds: trigger: netdev: move trigger data structure to global include dir Date: Tue, 1 Jun 2021 02:51:48 +0200 Message-Id: <20210601005155.27997-4-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org In preparation for HW offloading of netdev trigger, move struct led_netdev_data into global include directory, into file linux/ledtrig-netdev.h, so that drivers wanting to offload the trigger can see the requested settings. Signed-off-by: Marek Behún --- drivers/leds/trigger/ledtrig-netdev.c | 23 +----------------- include/linux/ledtrig-netdev.h | 34 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 include/linux/ledtrig-netdev.h diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 4f6b73e3b491..9a98f9c5b8d0 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -10,17 +10,16 @@ // Copyright 2005-2006 Openedhand Ltd. // Author: Richard Purdie -#include #include #include #include #include #include #include +#include #include #include #include -#include #include #include "../leds.h" @@ -36,26 +35,6 @@ * */ -struct led_netdev_data { - spinlock_t lock; - - struct delayed_work work; - struct notifier_block notifier; - - struct led_classdev *led_cdev; - struct net_device *net_dev; - - char device_name[IFNAMSIZ]; - atomic_t interval; - unsigned int last_activity; - - unsigned long mode; -#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 { NETDEV_ATTR_LINK, NETDEV_ATTR_TX, diff --git a/include/linux/ledtrig-netdev.h b/include/linux/ledtrig-netdev.h new file mode 100644 index 000000000000..d6be039e1247 --- /dev/null +++ b/include/linux/ledtrig-netdev.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * LED trigger shared structures + */ + +#ifndef __LINUX_LEDTRIG_NETDEV_H__ +#define __LINUX_LEDTRIG_NETDEV_H__ + +#include +#include +#include +#include + +struct led_netdev_data { + spinlock_t lock; + + struct delayed_work work; + struct notifier_block notifier; + + struct led_classdev *led_cdev; + struct net_device *net_dev; + + char device_name[IFNAMSIZ]; + atomic_t interval; + unsigned int last_activity; + + unsigned long mode; +#define NETDEV_LED_LINK 0 +#define NETDEV_LED_TX 1 +#define NETDEV_LED_RX 2 +#define NETDEV_LED_MODE_LINKUP 3 +}; + +#endif /* __LINUX_LEDTRIG_NETDEV_H__ */ From patchwork Tue Jun 1 00:51:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 452848 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84D8BC47082 for ; Tue, 1 Jun 2021 00:52:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5FFA361377 for ; Tue, 1 Jun 2021 00:52:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232515AbhFAAxz (ORCPT ); Mon, 31 May 2021 20:53:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:46020 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232516AbhFAAxt (ORCPT ); Mon, 31 May 2021 20:53:49 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id CF74A6136E; Tue, 1 Jun 2021 00:52:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508728; bh=zhw273xMoQcDBrWZhOAv58cvBFsHXq8mkER13wTIyW0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d6Ui0IpJubSyEyqovq/YjQ5ougb/os0g5Jso19mzpUH9b/ZhmOnN6TLXgl6r8Zvn5 TgIS2NQnUm7LCJLSF4FPmXwJmLhrG76K16IErOFryY5FhNE+C45KmCOBAmo+hFnGbg Y00zy4Ro/CSYr1AdqxqnEYZcT3qFh+jYC9arxmn/9PzynWfs1yruTQrcxWWiFikfOU Mto3L2UZptPABUwQZVWUhVRSLIbQMJ5w8pOgcaNv6YxCzdCZcfYrZWkFdQNivlSoRQ h1VAijVTUQoXB/Y5XJ8RSC5lsPpnRQAmI4yjDcS+xrTe9eN+CAeHfPg1EDpkmXXmiB AfFvTxPbg9JLA== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 04/10] leds: trigger: netdev: support HW offloading Date: Tue, 1 Jun 2021 02:51:49 +0200 Message-Id: <20210601005155.27997-5-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add support for HW offloading of the netdev trigger. We are only offloading if the link is up and rx/tx blinking is requested. Signed-off-by: Marek Behún --- drivers/leds/trigger/ledtrig-netdev.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 9a98f9c5b8d0..1f1b63d5a78d 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -52,9 +52,17 @@ 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 (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) { + led_trigger_offload_stop(led_cdev); led_set_brightness(led_cdev, LED_OFF); - else { + } else { + bool blink = test_bit(NETDEV_LED_TX, &trigger_data->mode) || + test_bit(NETDEV_LED_RX, &trigger_data->mode); + /* Try offload to HW only if RX/TX blinking is requested */ + if (blink) + if (!led_trigger_offload(led_cdev)) + return; + if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) led_set_brightness(led_cdev, led_cdev->blink_brightness); @@ -64,8 +72,7 @@ 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 (blink) schedule_delayed_work(&trigger_data->work, 0); } } From patchwork Tue Jun 1 00:51:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 451630 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 658A6C47083 for ; Tue, 1 Jun 2021 00:52:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4AF4161377 for ; Tue, 1 Jun 2021 00:52:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232490AbhFAAxz (ORCPT ); Mon, 31 May 2021 20:53:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:46090 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232517AbhFAAxv (ORCPT ); Mon, 31 May 2021 20:53:51 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id EC7AC613AD; Tue, 1 Jun 2021 00:52:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508730; bh=Nu/uf/ccww5gMoSX6cDd3d8bysChi7qjNX8MVEc2FMw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eCUd4yCuYC+w4CZx7hXJJ40s3wA3Fu4IqnCQ5K+MlU+Abnpbs+Kl0XJWyWEi7di7b dImId6l4WTdkcnnLlQ0nzlFFb3nXCs3bQtCEytv+pEeaObt+ovQjW9n1S4E5+l5rQR lpEVnGvusmY85GTI4kSymLzWO0WNpuMv9uoV+bCxxlQDGKLnwj/bM0odvbImVvyoCu 78RsWCx9k5CPqdWpU36y7HQN9QzLXlC7KrrK54gpaRZ+XF20R33COWjJoOtkBuRh8H dmT5CbIci4QWP4kH22VrKjZf6rTwLTdgSEijaYH8pzwb6JV4Hxs8kBnos9z4V6xHGt 77iG83CjR6LlQ== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 05/10] leds: trigger: netdev: change spinlock to mutex Date: Tue, 1 Jun 2021 02:51:50 +0200 Message-Id: <20210601005155.27997-6-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Using spinlocks requires that the trigger_offload() method cannot sleep. This can be problematic for some hardware, since access to registers may sleep. We can change the spinlock to mutex because, according to Jacek: register_netdevice_notifier() registers raw notifier chain, whose callbacks are not called from atomic context and there are no restrictions on callbacks. See include/linux/notifier.h. Signed-off-by: Marek Behún --- drivers/leds/trigger/ledtrig-netdev.c | 14 +++++++------- include/linux/ledtrig-netdev.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index 1f1b63d5a78d..341e1f174c5b 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -83,9 +83,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; } @@ -101,7 +101,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); @@ -125,7 +125,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; } @@ -299,7 +299,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); clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); switch (evt) { @@ -323,7 +323,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; } @@ -384,7 +384,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; diff --git a/include/linux/ledtrig-netdev.h b/include/linux/ledtrig-netdev.h index d6be039e1247..b93687ecc801 100644 --- a/include/linux/ledtrig-netdev.h +++ b/include/linux/ledtrig-netdev.h @@ -8,11 +8,11 @@ #include #include +#include #include -#include struct led_netdev_data { - spinlock_t lock; + struct mutex lock; struct delayed_work work; struct notifier_block notifier; From patchwork Tue Jun 1 00:51:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 452847 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99749C47080 for ; Tue, 1 Jun 2021 00:52:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F5F161376 for ; Tue, 1 Jun 2021 00:52:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232596AbhFAAx4 (ORCPT ); Mon, 31 May 2021 20:53:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:46138 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232544AbhFAAxx (ORCPT ); Mon, 31 May 2021 20:53:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 160AE61375; Tue, 1 Jun 2021 00:52:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508732; bh=z6Xsa2Rq528vEA4u9yW2RDF1eAQO1alQJELR9y3xA50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bK1+vC3zS2QJytjsq4sW5LxNpoQ+drm28iJLbpsWaukxBWOFgySKkDQGSaaj+bmXr zkH74Ep1aXo1XMZo2dXbwJG2P9PFtOmJ/e6US+NRXpMG7z1eAy1/9njojQdHXtPSVi QWT3m9JAPyQF0PrwxuffA/Qi9ocw7S9C3i+Pk+qkhIHsqA8m8eVb5Nd3UFvrJGH37H M4fwz7dZCk5w/CIHHoHLDZPRs5PZaX7OiaV6LPk8yAQREfilF0T7g3H7YaU83clx+a waZT4/NEdnRNpBzOxEmsd8o2GOG/4HsidsK/LxzBb9rFZK0w11IiCxyakdYIXBUQXg vdtKf1ixL2Ykw== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 06/10] leds: core: inform trigger that it's deactivation is due to LED removal Date: Tue, 1 Jun 2021 02:51:51 +0200 Message-Id: <20210601005155.27997-7-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Move setting of the LED_UNREGISTERING before deactivating the trigger in led_classdev_unregister(). It can be useful for a LED trigger to know whether it is being deactivated due to the LED being unregistered. This makes it possible for LED drivers which implement trigger offloading to leave the LED in HW triggering mode when the LED is unregistered, instead of disabling it. Signed-off-by: Marek Behún --- drivers/leds/led-class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 2e495ff67856..0486129a7f31 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -436,6 +436,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev) if (IS_ERR_OR_NULL(led_cdev->dev)) return; + led_cdev->flags |= LED_UNREGISTERING; + #ifdef CONFIG_LEDS_TRIGGERS down_write(&led_cdev->trigger_lock); if (led_cdev->trigger) @@ -443,8 +445,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); #endif - led_cdev->flags |= LED_UNREGISTERING; - /* Stop blinking */ led_stop_software_blink(led_cdev); From patchwork Tue Jun 1 00:51:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 451629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 838EFC47082 for ; Tue, 1 Jun 2021 00:52:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 65FE561375 for ; Tue, 1 Jun 2021 00:52:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232448AbhFAAx5 (ORCPT ); Mon, 31 May 2021 20:53:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:46182 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232559AbhFAAxz (ORCPT ); Mon, 31 May 2021 20:53:55 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 3341D61364; Tue, 1 Jun 2021 00:52:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508734; bh=thmtUafonYJfxBh+qZjVikVs+8hrEVyZs31+MWKROxY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lEVzPQPdMkCfq71Ex4q1U6MrqdEchhLnNrNIneo8BxRTzNwqw4GQlNGUxwH4rsSzk EDWYLjbXLp18w94EHr7xGzF2qQjyUcFjgz99qJtLaYuuEt+bT6Od9EjCM+CkEFeVRi QAn9u09ri+/66y3Ayq/mHvVCCnFQVGbquNi8wUvi0tNOgsM8wEp4kfkZZ+uApO3Sm0 epOZg9yA5DspB8rsN5LTaJsXImwx7a9g1dYFHf+mhiSqwkI49/Ed/53fuBJbGgkM0A nSGkVOYkmVEFfFBrCGfOc9dRsNuvtlVvYj7cWn/KjzMMMnr1oHN1R8immtZ1sjLIcn 5jPDdCXDpgNKA== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 07/10] leds: turris-omnia: refactor sw mode setting code into separate function Date: Tue, 1 Jun 2021 02:51:52 +0200 Message-Id: <20210601005155.27997-8-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org In order to make trigger offloading code more readable, put the code that sets/unsets software mode into a separate function. Signed-off-by: Marek Behún --- drivers/leds/leds-turris-omnia.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index 2f9a289ab245..c5a40afe5d45 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -73,6 +73,13 @@ static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, return ret; } +static int omnia_led_set_sw_mode(struct i2c_client *client, int led, bool sw) +{ + return i2c_smbus_write_byte_data(client, CMD_LED_MODE, + CMD_LED_MODE_LED(led) | + (sw ? CMD_LED_MODE_USER : 0)); +} + static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, struct device_node *np) { @@ -114,9 +121,7 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; /* put the LED into software mode */ - ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE, - CMD_LED_MODE_LED(led->reg) | - CMD_LED_MODE_USER); + ret = omnia_led_set_sw_mode(client, led->reg, true); if (ret < 0) { dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, ret); @@ -250,8 +255,7 @@ static int omnia_leds_remove(struct i2c_client *client) u8 buf[5]; /* put all LEDs into default (HW triggered) mode */ - i2c_smbus_write_byte_data(client, CMD_LED_MODE, - CMD_LED_MODE_LED(OMNIA_BOARD_LEDS)); + omnia_led_set_sw_mode(client, OMNIA_BOARD_LEDS, false); /* set all LEDs color to [255, 255, 255] */ buf[0] = CMD_LED_COLOR; From patchwork Tue Jun 1 00:51:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 452846 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79F7CC47082 for ; Tue, 1 Jun 2021 00:52:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61EC261375 for ; Tue, 1 Jun 2021 00:52:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232504AbhFAAx7 (ORCPT ); Mon, 31 May 2021 20:53:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:46220 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232398AbhFAAx5 (ORCPT ); Mon, 31 May 2021 20:53:57 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 515DD61374; Tue, 1 Jun 2021 00:52:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508737; bh=O5Y4AT4esPTiPEG+/lih5Kns+T03xStg/IARP4QSYJ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oCEbiBarnn6WMMuGmZdXend06qn+Fg/GWkqHJ5TMzNfk4q5WYP4dhoemg2s1y3Toj D7k4lFJ9R1zAD5uTIilLHOQ32FaHjUgKoapwTW0FfgBw+wlxnk9qnYRmA0enaKA9Qn 7FsAYYf2MZiOk6D9yLUAdcbOQZRWSjMWErOy+9l6cStzcpQvS+Au6XOKQ3so6169tN ZS0Ill8rlOy7h5YxhTelpkj18ALgweTPTrDjOLPkFLu4tMiB6SoEYDMMkpGWmSRErD 0EH7icd7po/Xrr3Xij3tnztaMfehHqvhrivv7ZC4bjPUeQv52kwlJ07N8v12NsCFuK ktUkuQCA6FFyg== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 08/10] leds: turris-omnia: refactor brightness setting function Date: Tue, 1 Jun 2021 02:51:53 +0200 Message-Id: <20210601005155.27997-9-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Move the code of brightness setting function guarded by mutex into separate function. This will be useful when used from trigger offload method. Signed-off-by: Marek Behún --- drivers/leds/leds-turris-omnia.c | 35 +++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index c5a40afe5d45..2b51c14b8363 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -41,32 +41,43 @@ struct omnia_leds { struct omnia_led leds[]; }; -static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, - enum led_brightness brightness) +static int omnia_led_brightness_set(struct i2c_client *client, + struct omnia_led *led, + enum led_brightness brightness) { - struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); - struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); - struct omnia_led *led = to_omnia_led(mc_cdev); u8 buf[5], state; int ret; - mutex_lock(&leds->lock); - led_mc_calc_color_components(&led->mc_cdev, brightness); buf[0] = CMD_LED_COLOR; buf[1] = led->reg; - buf[2] = mc_cdev->subled_info[0].brightness; - buf[3] = mc_cdev->subled_info[1].brightness; - buf[4] = mc_cdev->subled_info[2].brightness; + buf[2] = led->mc_cdev.subled_info[0].brightness; + buf[3] = led->mc_cdev.subled_info[1].brightness; + buf[4] = led->mc_cdev.subled_info[2].brightness; state = CMD_LED_STATE_LED(led->reg); if (buf[2] || buf[3] || buf[4]) state |= CMD_LED_STATE_ON; - ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state); + ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE, state); if (ret >= 0 && (state & CMD_LED_STATE_ON)) - ret = i2c_master_send(leds->client, buf, 5); + ret = i2c_master_send(client, buf, 5); + + return ret < 0 ? ret : 0; +} + +static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); + struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct omnia_led *led = to_omnia_led(mc_cdev); + int ret; + + mutex_lock(&leds->lock); + + ret = omnia_led_brightness_set(leds->client, led, brightness); mutex_unlock(&leds->lock); From patchwork Tue Jun 1 00:51:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 451628 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1C64C47080 for ; Tue, 1 Jun 2021 00:52:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A7A7261376 for ; Tue, 1 Jun 2021 00:52:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232637AbhFAAyD (ORCPT ); Mon, 31 May 2021 20:54:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:46280 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232583AbhFAAx7 (ORCPT ); Mon, 31 May 2021 20:53:59 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 6E5AD6128A; Tue, 1 Jun 2021 00:52:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508739; bh=kG+9RtVXlyMIsugN7bZXLPw5uQxPiZSYOoDwJAj9cwU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=grKyL/RUceFsztbX0dt5ZzE6I6q2KwirV0kwMf8VsfySqDElcLxQ6AO5Gg3n419u0 IOtHpXhhz6DwHglR/2Zd6ILyW4aMlunZHvuOAUjqsShyPct8QDNdKs9JkhMmP/5xOU NwRydFV9A9Y9NQSuiEYyDLRMieeXltzIne7w5ycMD3hJ8WUPno1NCx6ImJu3UlzQ26 t6yQ9L5CP5hisYx0VaB8Dzis3XOaXqZkdMlYuKVqkvXCWEWn8ZHHed9b0opMBRJAGb bXUOG8stkJVoBDRp+tqcZzf23CVkMwPqdmvrg0CdjfP4LdH9i+dceamy8jy/C7SQDu 52O8NPaXaw82w== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 09/10] leds: turris-omnia: initialize each multicolor LED to white color Date: Tue, 1 Jun 2021 02:51:54 +0200 Message-Id: <20210601005155.27997-10-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Initialize the intensity of each multi-color LED to white color (255, 255, 255). This is what the hardware does by default when the driver is not present. Signed-off-by: Marek Behún --- drivers/leds/leds-turris-omnia.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index 2b51c14b8363..b3581b98c75d 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -117,10 +117,13 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, led->subled_info[0].color_index = LED_COLOR_ID_RED; led->subled_info[0].channel = 0; + led->subled_info[0].intensity = 255; led->subled_info[1].color_index = LED_COLOR_ID_GREEN; led->subled_info[1].channel = 1; + led->subled_info[1].intensity = 255; led->subled_info[2].color_index = LED_COLOR_ID_BLUE; led->subled_info[2].channel = 2; + led->subled_info[2].intensity = 255; led->mc_cdev.subled_info = led->subled_info; led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS; From patchwork Tue Jun 1 00:51:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 452845 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9EB47C47080 for ; Tue, 1 Jun 2021 00:52:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 328476128A for ; Tue, 1 Jun 2021 00:52:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232412AbhFAAyF (ORCPT ); Mon, 31 May 2021 20:54:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:46336 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232602AbhFAAyB (ORCPT ); Mon, 31 May 2021 20:54:01 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8D21D61370; Tue, 1 Jun 2021 00:52:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1622508741; bh=mwIRJpoT9nxq/Jlz5btqtXLukWmNDZNHqD6M4t/09rk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H7hN7PVHzWelGSDpy3tfDIimEoakerbx2lkvZg1Sx5HVnVNG167yt6zlch0xUcW5B ewtzyO7tgiXu+8cEi6tFT/5V1qRhOhT28/xXv38jrIsDcl6Fnvu/CEeidjJgHRncLg sKjItdBOOHA52L+69M6uENyS5MiRp6kfUSaksw3DHIh/ZmgkMlZ3XXuBkoGPN2o1Hp VFDp846SrHZBQ7HYoITX2YKgZ2HOjGvjiz7xhlL/wZ1GLWbZfVyA2HPzIAsEpTt6iP QovjQdCh2jqUKBg6UJ3ptUf4FnGG9RWS1lCQ/TbWMnIFdlxGWjhe0qYvn66J75vjif e/HtuBftMZmRw== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: linux-leds@vger.kernel.org Cc: netdev@vger.kernel.org, Pavel Machek , Dan Murphy , Russell King , Andrew Lunn , Matthias Schiffer , Jacek Anaszewski , Mauro Carvalho Chehab , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH leds v2 10/10] leds: turris-omnia: support offloading netdev trigger for WAN LED Date: Tue, 1 Jun 2021 02:51:55 +0200 Message-Id: <20210601005155.27997-11-kabel@kernel.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210601005155.27997-1-kabel@kernel.org> References: <20210601005155.27997-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Add support for offloading netdev trigger for WAN LED. Support for LAN LEDs will be added later, because it needs changes in the mv88e6xxx driver. Here is a simplified schema of how the corresponding chips are connected on Turris Omnia: [eth2] +-----+ [eth0 & eth1] /-----------< SOC >-----------------\ | +--v--+ | | | [i2c] | | \-------------\ | [MOD_DEF0] +------v--------+ | | /---------> SerDes switch | [LED0_pin] +--v--+ | +----------+ | +--v-------v----+ /-------------> MCU >---|--> RGB LEDs | | [srds0] | | | +--^--+ | +----------+ | /-------/ | | | | | | [srds1]| | [LED_pins]| | +-^----v---+ +---v-------^---+ +-------^------v-+ | SFP cage | | 88E1512 PHY | | 88E6176 Swtich | +----------+ | with WAN port | | with LAN ports | +---------------+ +----------------+ The RGB LEDs are controlled by the MCU and can be configured into the following modes: - SW mode - both color and whether the LED is on/off is controlled via I2C - HW mode - color is controlled via I2C, on/off state is controlled by HW depending on LED: - WAN LED on/off state reflects LED0_pin from the 88E1512 PHY - LAN LED on/off states reflect corresponding LED_pins from 88E6176 switch [1] - PCIe on/off states reflect the corresponding WWAN/WLAN/MSATA LED pins from the MiniPCIe ports [1] - Power LED is always on in HW mode - User LEDs are always off in HW mode Adding netdev trigger offload support for the WAN LED therefore requires: - checking whether the netdevice for which the netdev trigger should trigger is indeed the WAN device - checking whether SFP cage is empty. If there is a SFP module in the cage, the 88E1512 PHY is not used and we have to trigger in SW. Currently this is done by simply checking if sfp_bus is NULL, because phylink does not yet have support for how the SFP cage is wired on Omnia (via SerDes switch) - configuring the behaviour of LED0_pin of the Marvell 88E1512 PHY according to requested netdev trigger settings - putting the WAN LED into HW mode [1] For more info look at https://wiki.turris.cz/doc/_media/rtrom01-schema.pdf Signed-off-by: Marek Behún --- drivers/leds/Kconfig | 3 + drivers/leds/leds-turris-omnia.c | 232 +++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 49d99cb084db..e2950636f093 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -182,6 +182,9 @@ config LEDS_TURRIS_OMNIA depends on I2C depends on MACH_ARMADA_38X || COMPILE_TEST depends on OF + depends on PHYLIB + select LEDS_TRIGGERS + select LEDS_TRIGGER_NETDEV help This option enables basic support for the LEDs found on the front side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index b3581b98c75d..b9ea0ce261eb 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -7,9 +7,11 @@ #include #include +#include #include #include #include +#include #include "leds.h" #define OMNIA_BOARD_LEDS 12 @@ -27,10 +29,20 @@ #define CMD_LED_SET_BRIGHTNESS 7 #define CMD_LED_GET_BRIGHTNESS 8 +#define MII_MARVELL_LED_PAGE 0x03 +#define MII_PHY_LED_CTRL 0x10 +#define MII_PHY_LED_TCR 0x12 +#define MII_PHY_LED_TCR_PULSESTR_MASK 0x7000 +#define MII_PHY_LED_TCR_PULSESTR_SHIFT 12 +#define MII_PHY_LED_TCR_BLINKRATE_MASK 0x0700 +#define MII_PHY_LED_TCR_BLINKRATE_SHIFT 8 + struct omnia_led { struct led_classdev_mc mc_cdev; struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS]; int reg; + struct device_node *trig_src_np; + struct phy_device *phydev; }; #define to_omnia_led(l) container_of(l, struct omnia_led, mc_cdev) @@ -38,6 +50,7 @@ struct omnia_led { struct omnia_leds { struct i2c_client *client; struct mutex lock; + int count; struct omnia_led leds[]; }; @@ -91,6 +104,208 @@ static int omnia_led_set_sw_mode(struct i2c_client *client, int led, bool sw) (sw ? CMD_LED_MODE_USER : 0)); } +static int wan_led_round_blink_rate(unsigned long *period) +{ + /* Each interval is (0.7 * p, 1.3 * p), where p is the period supported + * by the chip. Should we change this so that there are no holes between + * these intervals? + */ + switch (*period) { + case 29 ... 55: + *period = 42; + return 0; + case 58 ... 108: + *period = 84; + return 1; + case 119 ... 221: + *period = 170; + return 2; + case 238 ... 442: + *period = 340; + return 3; + case 469 ... 871: + *period = 670; + return 4; + default: + return -EOPNOTSUPP; + } +} + +static int omnia_led_trig_offload_wan(struct omnia_leds *leds, + struct omnia_led *led, + struct led_netdev_data *trig) +{ + unsigned long period; + int ret, blink_rate; + bool link, rx, tx; + u8 fun; + + /* HW offload on WAN port is supported only via internal PHY */ + if (trig->net_dev->sfp_bus || !trig->net_dev->phydev) + return -EOPNOTSUPP; + + link = test_bit(NETDEV_LED_LINK, &trig->mode); + rx = test_bit(NETDEV_LED_RX, &trig->mode); + tx = test_bit(NETDEV_LED_TX, &trig->mode); + + if (link && rx && tx) + fun = 0x1; + else if (!link && rx && tx) + fun = 0x4; + else + return -EOPNOTSUPP; + + period = jiffies_to_msecs(atomic_read(&trig->interval)) * 2; + blink_rate = wan_led_round_blink_rate(&period); + if (blink_rate < 0) + return blink_rate; + + mutex_lock(&leds->lock); + + if (!led->phydev) { + led->phydev = trig->net_dev->phydev; + get_device(&led->phydev->mdio.dev); + } + + /* set PHY's LED[0] pin to blink according to trigger setting */ + ret = phy_modify_paged(led->phydev, MII_MARVELL_LED_PAGE, + MII_PHY_LED_TCR, + MII_PHY_LED_TCR_PULSESTR_MASK | + MII_PHY_LED_TCR_BLINKRATE_MASK, + (0 << MII_PHY_LED_TCR_PULSESTR_SHIFT) | + (blink_rate << MII_PHY_LED_TCR_BLINKRATE_SHIFT)); + if (ret) + goto unlock; + + ret = phy_modify_paged(led->phydev, MII_MARVELL_LED_PAGE, + MII_PHY_LED_CTRL, 0xf, fun); + if (ret) + goto unlock; + + /* put the LED into HW mode */ + ret = omnia_led_set_sw_mode(leds->client, led->reg, false); + if (ret) + goto unlock; + + /* set blinking brightness according to led_cdev->blink_brighness */ + ret = omnia_led_brightness_set(leds->client, led, + led->mc_cdev.led_cdev.blink_brightness); + if (ret) + goto unlock; + + atomic_set(&trig->interval, msecs_to_jiffies(period / 2)); + +unlock: + mutex_unlock(&leds->lock); + + if (ret) + dev_err(led->mc_cdev.led_cdev.dev, + "Error offloading trigger: %d\n", ret); + + return ret; +} + +static int omnia_led_trig_offload_off(struct omnia_leds *leds, + struct omnia_led *led) +{ + int ret; + + if (!led->phydev) + return 0; + + mutex_lock(&leds->lock); + + /* set PHY's LED[0] pin to default values */ + ret = phy_modify_paged(led->phydev, MII_MARVELL_LED_PAGE, + MII_PHY_LED_TCR, + MII_PHY_LED_TCR_PULSESTR_MASK | + MII_PHY_LED_TCR_BLINKRATE_MASK, + (4 << MII_PHY_LED_TCR_PULSESTR_SHIFT) | + (1 << MII_PHY_LED_TCR_BLINKRATE_SHIFT)); + + ret = phy_modify_paged(led->phydev, MII_MARVELL_LED_PAGE, + MII_PHY_LED_CTRL, 0xf, 0xe); + + /* + * Return to software controlled mode, but only if we aren't being + * called from led_classdev_unregister. + */ + if (!(led->mc_cdev.led_cdev.flags & LED_UNREGISTERING)) + ret = omnia_led_set_sw_mode(leds->client, led->reg, true); + + put_device(&led->phydev->mdio.dev); + led->phydev = NULL; + + mutex_unlock(&leds->lock); + + return 0; +} + +static int omnia_led_trig_offload(struct led_classdev *cdev, bool enable) +{ + struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); + struct omnia_led *led = to_omnia_led(mc_cdev); + struct led_netdev_data *trig; + int ret = -EOPNOTSUPP; + + if (!enable) + return omnia_led_trig_offload_off(leds, led); + + if (!led->trig_src_np) + goto end; + + /* only netdev trigger offloading is supported currently */ + if (strcmp(cdev->trigger->name, "netdev")) + goto end; + + trig = led_get_trigger_data(cdev); + + if (!trig->net_dev) + goto end; + + if (dev_of_node(trig->net_dev->dev.parent) != led->trig_src_np) + goto end; + + ret = omnia_led_trig_offload_wan(leds, led, trig); + +end: + /* + * if offloading failed (parameters not supported by HW), ensure any + * previous offloading is disabled + */ + if (ret) + omnia_led_trig_offload_off(leds, led); + + return ret; +} + +static int read_trigger_sources(struct omnia_led *led, struct device_node *np) +{ + struct of_phandle_args args; + int ret; + + ret = of_count_phandle_with_args(np, "trigger-sources", + "#trigger-source-cells"); + if (ret < 0) + return ret == -ENOENT ? 0 : ret; + + if (!ret) + return 0; + + ret = of_parse_phandle_with_args(np, "trigger-sources", + "#trigger-source-cells", 0, &args); + if (ret) + return ret; + + if (of_device_is_compatible(args.np, "marvell,armada-370-neta")) + led->trig_src_np = args.np; + else + of_node_put(args.np); + + return 0; +} + static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, struct device_node *np) { @@ -115,6 +330,13 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, return 0; } + ret = read_trigger_sources(led, np); + if (ret) { + dev_warn(dev, "Node %pOF: failed reading trigger sources: %d\n", + np, ret); + return 0; + } + led->subled_info[0].color_index = LED_COLOR_ID_RED; led->subled_info[0].channel = 0; led->subled_info[0].intensity = 255; @@ -133,6 +355,8 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, cdev = &led->mc_cdev.led_cdev; cdev->max_brightness = 255; cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; + if (led->trig_src_np) + cdev->trigger_offload = omnia_led_trig_offload; /* put the LED into software mode */ ret = omnia_led_set_sw_mode(client, led->reg, true); @@ -256,6 +480,7 @@ static int omnia_leds_probe(struct i2c_client *client, } led += ret; + ++leds->count; } if (devm_device_add_groups(dev, omnia_led_controller_groups)) @@ -266,8 +491,15 @@ static int omnia_leds_probe(struct i2c_client *client, static int omnia_leds_remove(struct i2c_client *client) { + struct omnia_leds *leds = i2c_get_clientdata(client); + struct omnia_led *led; u8 buf[5]; + /* put away trigger source OF nodes */ + for (led = &leds->leds[0]; led < &leds->leds[leds->count]; ++led) + if (led->trig_src_np) + of_node_put(led->trig_src_np); + /* put all LEDs into default (HW triggered) mode */ omnia_led_set_sw_mode(client, OMNIA_BOARD_LEDS, false);