diff mbox series

[RFC,net-next,5/8] dsa: Plumb in LED calls needed for hardware offload

Message ID 20231128232135.358638-6-andrew@lunn.ch (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series DSA LED infrastructure, mv88e6xxx and QCA8K | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/codegen success Generated files up to date
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1133 this patch: 1133
netdev/cc_maintainers warning 3 maintainers not CCed: kuba@kernel.org pabeni@redhat.com edumazet@google.com
netdev/build_clang success Errors and warnings before: 1148 this patch: 1148
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1160 this patch: 1160
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 81 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Andrew Lunn Nov. 28, 2023, 11:21 p.m. UTC
In order to offload blinking of the LED to hardware, additional calls
are needed into the LED driver. Add them to the DSA core abstraction.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/net/dsa.h |  6 +++++
 net/dsa/dsa.c     | 57 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 2e05e4fd0b76..19f1338ac604 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -1249,6 +1249,12 @@  struct dsa_switch_ops {
 				  u8 led, enum led_brightness value);
 	int (*led_blink_set)(struct dsa_switch *ds, int port, u8 led,
 			     unsigned long *delay_on, unsigned long *delay_off);
+	int (*led_hw_control_is_supported)(struct dsa_switch *ds, int port,
+					   u8 led, unsigned long flags);
+	int (*led_hw_control_set)(struct dsa_switch *ds, int port, u8 led,
+				  unsigned long flags);
+	int (*led_hw_control_get)(struct dsa_switch *ds, int port, u8 led,
+				  unsigned long *flags);
 };
 
 #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes)		\
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index b13748f9b519..16e51020bc5e 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -492,6 +492,52 @@  static int dsa_led_blink_set(struct led_classdev *led_cdev,
 				      delay_on, delay_off);
 }
 
+static __maybe_unused int
+dsa_led_hw_control_is_supported(struct led_classdev *led_cdev,
+				unsigned long flags)
+{
+	struct dsa_led *dsa_led = to_dsa_led(led_cdev);
+	struct dsa_port *dp = dsa_led->dp;
+	struct dsa_switch *ds = dp->ds;
+
+	return ds->ops->led_hw_control_is_supported(ds, dp->index,
+						    dsa_led->index,
+						    flags);
+}
+
+static __maybe_unused int dsa_led_hw_control_set(struct led_classdev *led_cdev,
+						 unsigned long flags)
+{
+	struct dsa_led *dsa_led = to_dsa_led(led_cdev);
+	struct dsa_port *dp = dsa_led->dp;
+	struct dsa_switch *ds = dp->ds;
+
+	return ds->ops->led_hw_control_set(ds, dp->index, dsa_led->index,
+					   flags);
+}
+
+static __maybe_unused int dsa_led_hw_control_get(struct led_classdev *led_cdev,
+						 unsigned long *flags)
+{
+	struct dsa_led *dsa_led = to_dsa_led(led_cdev);
+	struct dsa_port *dp = dsa_led->dp;
+	struct dsa_switch *ds = dp->ds;
+
+	return ds->ops->led_hw_control_get(ds, dp->index, dsa_led->index,
+					   flags);
+}
+
+static struct device *
+dsa_led_hw_control_get_device(struct led_classdev *led_cdev)
+{
+	struct dsa_led *dsa_led = to_dsa_led(led_cdev);
+	struct dsa_port *dp = dsa_led->dp;
+
+	if (dp->user)
+		return &dp->user->dev;
+	return NULL;
+}
+
 static int dsa_port_led_setup(struct dsa_port *dp,
 			      struct device_node *led)
 {
@@ -521,7 +567,16 @@  static int dsa_port_led_setup(struct dsa_port *dp,
 		cdev->brightness_set_blocking = dsa_led_brightness_set;
 	if (ds->ops->led_blink_set)
 		cdev->blink_set = dsa_led_blink_set;
-
+#ifdef CONFIG_LEDS_TRIGGERS
+	if (ds->ops->led_hw_control_is_supported)
+		cdev->hw_control_is_supported = dsa_led_hw_control_is_supported;
+	if (ds->ops->led_hw_control_set)
+		cdev->hw_control_set = dsa_led_hw_control_set;
+	if (ds->ops->led_hw_control_get)
+		cdev->hw_control_get = dsa_led_hw_control_get;
+	cdev->hw_control_trigger = "netdev";
+#endif
+	cdev->hw_control_get_device = dsa_led_hw_control_get_device;
 	cdev->max_brightness = 1;
 
 	init_data.fwnode = of_fwnode_handle(led);