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 <ma...@denx.de>
Cc: Alex Nemirovsky <alex.nemirov...@cortina-access.com>
Cc: Patrick Delaunay <patrick.delau...@foss.st.com>
Cc: Philippe Reynes <philippe.rey...@softathome.com>
Cc: Sean Anderson <sean...@gmail.com>
Cc: Simon Glass <s...@chromium.org>
Cc: Steven Lawrance <steven.lawra...@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

Reply via email to