From 72675b063b6ede269a8edee29575ade02c21b58d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 4 Apr 2022 01:23:27 +0200 Subject: [PATCH] led: Configure LED default-state on boot 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 Cc: Alex Nemirovsky Cc: Patrick Delaunay Cc: Philippe Reynes Cc: Sean Anderson Cc: Simon Glass Cc: Steven Lawrance [trini: Update the relevant test now that we have support] Signed-off-by: Tom Rini --- drivers/led/led-uclass.c | 57 ++++++++++++++++++++++------------------ include/led.h | 24 +++++++++-------- test/cmd/pinmux.c | 2 +- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index 2f4aa18fb1..5d7bf40896 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 8eeb5a7c6d..43acca8571 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 diff --git a/test/cmd/pinmux.c b/test/cmd/pinmux.c index ba338b8dce..de3bb0d2f9 100644 --- a/test/cmd/pinmux.c +++ b/test/cmd/pinmux.c @@ -16,7 +16,7 @@ static int dm_test_cmd_pinmux_status_pinname(struct unit_test_state *uts) /* Test that 'pinmux status ' displays the selected pin. */ console_record_reset(); run_command("pinmux status a5", 0); - ut_assert_nextlinen("a5 : gpio input ."); + ut_assert_nextlinen("a5 : gpio output ."); ut_assert_console_end(); console_record_reset(); -- 2.39.5