From: "Marek Behún" <kabel@kernel.org>
To: netdev@vger.kernel.org
Cc: linux-leds@vger.kernel.org, "Pavel Machek" <pavel@ucw.cz>,
"Dan Murphy" <dmurphy@ti.com>,
"Russell King" <linux@armlinux.org.uk>,
"Andrew Lunn" <andrew@lunn.ch>,
"Matthias Schiffer" <matthias.schiffer@ew.tq-group.com>,
"David S. Miller" <davem@davemloft.net>,
"Jacek Anaszewski" <jacek.anaszewski@gmail.com>,
"Ben Whitten" <ben.whitten@gmail.com>,
"Marek Behún" <kabel@kernel.org>
Subject: [PATCH RFC leds + net-next 4/7] leds: trigger: netdev: support HW offloading
Date: Fri, 30 Oct 2020 12:44:32 +0100 [thread overview]
Message-ID: <20201030114435.20169-5-kabel@kernel.org> (raw)
In-Reply-To: <20201030114435.20169-1-kabel@kernel.org>
Add support for HW offloading of the netdev trigger.
We need to change spinlock to mutex, because if spinlock is used, the
trigger_offload() method cannot sleep, which can happen for ethernet
PHYs.
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.
Move struct led_trigger_data into global include directory, into file
linux/ledtrig.h, so that drivers wanting to offload the trigger can
access its settings.
Also export the netdev_led_trigger variable and declare it in ledtrih.h
so that drivers may check whether the LED is set to this trigger.
Signed-off-by: Marek Behún <kabel@kernel.org>
---
drivers/leds/trigger/ledtrig-netdev.c | 48 ++++++++++-----------------
include/linux/ledtrig.h | 40 ++++++++++++++++++++++
2 files changed, 57 insertions(+), 31 deletions(-)
create mode 100644 include/linux/ledtrig.h
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index 8f013b6df4fa..d4fa031d3a9e 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 <rpurdie@openedhand.com>
-#include <linux/atomic.h>
#include <linux/ctype.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/leds.h>
+#include <linux/ledtrig.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/spinlock.h>
#include <linux/timer.h>
#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 link:1;
- unsigned tx:1;
- unsigned rx:1;
-
- unsigned linkup:1;
-};
-
enum netdev_led_attr {
NETDEV_ATTR_LINK,
NETDEV_ATTR_TX,
@@ -73,6 +52,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 (!led_trigger_offload(led_cdev))
+ return;
+
if (!trigger_data->linkup)
led_set_brightness(led_cdev, LED_OFF);
else {
@@ -96,9 +78,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;
}
@@ -114,7 +96,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);
@@ -138,7 +120,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;
}
@@ -295,6 +277,7 @@ static int netdev_trig_notify(struct notifier_block *nb,
netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv);
struct led_netdev_data *trigger_data =
container_of(nb, struct led_netdev_data, notifier);
+ bool reset = true;
if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE
&& evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER
@@ -308,7 +291,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->linkup = 0;
switch (evt) {
@@ -327,12 +310,14 @@ static int netdev_trig_notify(struct notifier_block *nb,
case NETDEV_CHANGE:
if (netif_carrier_ok(dev))
trigger_data->linkup = 1;
+ reset = !trigger_data->led_cdev->offloaded;
break;
}
- set_baseline_state(trigger_data);
+ if (reset)
+ set_baseline_state(trigger_data);
- spin_unlock_bh(&trigger_data->lock);
+ mutex_unlock(&trigger_data->lock);
return NOTIFY_DONE;
}
@@ -389,7 +374,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;
@@ -423,12 +408,13 @@ static void netdev_trig_deactivate(struct led_classdev *led_cdev)
kfree(trigger_data);
}
-static struct led_trigger netdev_led_trigger = {
+struct led_trigger netdev_led_trigger = {
.name = "netdev",
.activate = netdev_trig_activate,
.deactivate = netdev_trig_deactivate,
.groups = netdev_trig_groups,
};
+EXPORT_SYMBOL_GPL(netdev_led_trigger);
static int __init netdev_trig_init(void)
{
diff --git a/include/linux/ledtrig.h b/include/linux/ledtrig.h
new file mode 100644
index 000000000000..593b2bee6ca0
--- /dev/null
+++ b/include/linux/ledtrig.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * LED trigger shared structures
+ */
+
+#ifndef __LINUX_LEDTRIG_H__
+#define __LINUX_LEDTRIG_H__
+
+#include <linux/atomic.h>
+#include <linux/leds.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+
+#if IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
+
+struct led_netdev_data {
+ struct mutex 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 link:1;
+ unsigned tx:1;
+ unsigned rx:1;
+
+ unsigned linkup:1;
+};
+
+extern struct led_trigger netdev_led_trigger;
+
+#endif /* IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV) */
+
+#endif /* __LINUX_LEDTRIG_H__ */
--
2.26.2
next prev parent reply other threads:[~2020-10-30 11:44 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-30 11:44 [PATCH RFC leds + net-next 0/7] netdev trigger offloading and LEDs on Marvell PHYs Marek Behún
2020-10-30 11:44 ` [PATCH RFC leds + net-next 1/7] leds: trigger: netdev: don't explicitly zero kzalloced data Marek Behún
2020-11-25 12:34 ` Pavel Machek
2020-10-30 11:44 ` [PATCH RFC leds + net-next 2/7] leds: trigger: netdev: simplify the driver by using bit field members Marek Behún
2020-10-30 22:37 ` Jacek Anaszewski
2020-10-30 23:45 ` Marek Behún
2020-11-01 16:40 ` Jacek Anaszewski
2021-03-01 10:30 ` Pavel Machek
2020-10-30 11:44 ` [PATCH RFC leds + net-next 3/7] leds: trigger: add API for HW offloading of triggers Marek Behún
2021-03-01 10:38 ` Pavel Machek
2020-10-30 11:44 ` Marek Behún [this message]
2020-11-05 14:44 ` [PATCH RFC leds + net-next 4/7] leds: trigger: netdev: support HW offloading Marek Behún
2021-03-01 10:44 ` Pavel Machek
2020-10-30 11:44 ` [PATCH RFC leds + net-next 5/7] net: phy: add simple incrementing phyindex member to phy_device struct Marek Behún
2021-03-01 10:46 ` Pavel Machek
2020-10-30 11:44 ` [PATCH RFC leds + net-next 6/7] net: phy: add support for LEDs connected to ethernet PHYs Marek Behún
2021-03-01 10:52 ` Pavel Machek
2020-10-30 11:44 ` [PATCH RFC leds + net-next 7/7] net: phy: marvell: support LEDs connected on Marvell PHYs Marek Behún
2020-10-30 15:04 ` kernel test robot
2020-10-30 16:04 ` kernel test robot
2020-11-25 12:38 ` Pavel Machek
2021-03-01 11:05 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201030114435.20169-5-kabel@kernel.org \
--to=kabel@kernel.org \
--cc=andrew@lunn.ch \
--cc=ben.whitten@gmail.com \
--cc=davem@davemloft.net \
--cc=dmurphy@ti.com \
--cc=jacek.anaszewski@gmail.com \
--cc=linux-leds@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=matthias.schiffer@ew.tq-group.com \
--cc=netdev@vger.kernel.org \
--cc=pavel@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.