[PATCH] led: Configure LED default-state on boot

Marek Vasut marex at denx.de
Mon Apr 4 01:23:27 CEST 2022


In case the DT LED subnode contains "default-state" property set to
either "on" or "off", probe the LED driver and configure the LED state
automatically.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alex Nemirovsky <alex.nemirovsky at cortina-access.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: Philippe Reynes <philippe.reynes at softathome.com>
Cc: Sean Anderson <seanga2 at gmail.com>
Cc: Simon Glass <sjg at chromium.org>
Cc: Steven Lawrance <steven.lawrance at softathome.com>
---
 drivers/led/led-uclass.c | 57 ++++++++++++++++++++++------------------
 include/led.h            | 24 +++++++++--------
 2 files changed, 45 insertions(+), 36 deletions(-)

diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index 2f4aa18fb10..5d7bf40896b 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -66,43 +66,49 @@ int led_set_period(struct udevice *dev, int period_ms)
 }
 #endif
 
+/* This is superseded by led_post_bind()/led_post_probe() below. */
 int led_default_state(void)
 {
-	struct udevice *dev;
-	struct uclass *uc;
-	const char *default_state;
-	int ret;
-
-	ret = uclass_get(UCLASS_LED, &uc);
-	if (ret)
-		return ret;
-	for (uclass_find_first_device(UCLASS_LED, &dev);
-	     dev;
-	     uclass_find_next_device(&dev)) {
-		default_state = dev_read_string(dev, "default-state");
-		if (!default_state)
-			continue;
-		ret = device_probe(dev);
-		if (ret)
-			return ret;
-		if (!strncmp(default_state, "on", 2))
-			led_set_state(dev, LEDST_ON);
-		else if (!strncmp(default_state, "off", 3))
-			led_set_state(dev, LEDST_OFF);
-		/* default-state = "keep" : device is only probed */
-	}
-
-	return ret;
+	return 0;
 }
 
 static int led_post_bind(struct udevice *dev)
 {
 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+	const char *default_state;
 
 	uc_plat->label = dev_read_string(dev, "label");
 	if (!uc_plat->label)
 		uc_plat->label = ofnode_get_name(dev_ofnode(dev));
 
+	uc_plat->default_state = LEDST_COUNT;
+
+	default_state = dev_read_string(dev, "default-state");
+	if (!default_state)
+		return 0;
+
+	if (!strncmp(default_state, "on", 2))
+		uc_plat->default_state = LEDST_ON;
+	else if (!strncmp(default_state, "off", 3))
+		uc_plat->default_state = LEDST_OFF;
+	else
+		return 0;
+
+	/*
+	 * In case the LED has default-state DT property, trigger
+	 * probe() to configure its default state during startup.
+	 */
+	return device_probe(dev);
+}
+
+static int led_post_probe(struct udevice *dev)
+{
+	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+
+	if (uc_plat->default_state == LEDST_ON ||
+	    uc_plat->default_state == LEDST_OFF)
+		led_set_state(dev, uc_plat->default_state);
+
 	return 0;
 }
 
@@ -111,4 +117,5 @@ UCLASS_DRIVER(led) = {
 	.name		= "led",
 	.per_device_plat_auto	= sizeof(struct led_uc_plat),
 	.post_bind	= led_post_bind,
+	.post_probe	= led_post_probe,
 };
diff --git a/include/led.h b/include/led.h
index 8eeb5a7c6d3..43acca85719 100644
--- a/include/led.h
+++ b/include/led.h
@@ -9,13 +9,26 @@
 
 struct udevice;
 
+enum led_state_t {
+	LEDST_OFF = 0,
+	LEDST_ON = 1,
+	LEDST_TOGGLE,
+#ifdef CONFIG_LED_BLINK
+	LEDST_BLINK,
+#endif
+
+	LEDST_COUNT,
+};
+
 /**
  * struct led_uc_plat - Platform data the uclass stores about each device
  *
  * @label:	LED label
+ * @default_state:	LED default state
  */
 struct led_uc_plat {
 	const char *label;
+	enum led_state_t default_state;
 };
 
 /**
@@ -27,17 +40,6 @@ struct led_uc_priv {
 	int period_ms;
 };
 
-enum led_state_t {
-	LEDST_OFF = 0,
-	LEDST_ON = 1,
-	LEDST_TOGGLE,
-#ifdef CONFIG_LED_BLINK
-	LEDST_BLINK,
-#endif
-
-	LEDST_COUNT,
-};
-
 struct led_ops {
 	/**
 	 * set_state() - set the state of an LED
-- 
2.35.1



More information about the U-Boot mailing list