Merge branch '2022-04-28-led-updates'
- DM GPIO bugfix
- LED related code clean-ups
- Fix some of the DM/LED tests
- Update the LED dt binding doc
diff --git a/board/aristainetos/aristainetos.c b/board/aristainetos/aristainetos.c
index 19af596..514cb60 100644
--- a/board/aristainetos/aristainetos.c
+++ b/board/aristainetos/aristainetos.c
@@ -418,7 +418,6 @@
int x, y;
int ret;
- led_default_state();
splash_get_pos(&x, &y);
bmp_display((ulong)&bmp_logo_bitmap[0], x, y);
diff --git a/board/bosch/guardian/board.c b/board/bosch/guardian/board.c
index 105b75e..68f2744 100644
--- a/board/bosch/guardian/board.c
+++ b/board/bosch/guardian/board.c
@@ -327,9 +327,6 @@
int ret;
struct udevice *cdev;
-#ifdef CONFIG_LED_GPIO
- led_default_state();
-#endif
set_bootmode_env();
ret = uclass_get_device(UCLASS_PANEL, 0, &cdev);
diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c
index f44afb0..67273f9 100644
--- a/board/dhelectronics/dh_stm32mp1/board.c
+++ b/board/dhelectronics/dh_stm32mp1/board.c
@@ -607,9 +607,6 @@
board_init_fmc2();
- if (CONFIG_IS_ENABLED(LED))
- led_default_state();
-
return 0;
}
diff --git a/board/gardena/smart-gateway-at91sam/board.c b/board/gardena/smart-gateway-at91sam/board.c
index 3f402cf..c6eb11e 100644
--- a/board/gardena/smart-gateway-at91sam/board.c
+++ b/board/gardena/smart-gateway-at91sam/board.c
@@ -24,9 +24,6 @@
{
at91_prepare_cpu_var();
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 8a3a6e3..aa833a0 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -183,9 +183,6 @@
int board_late_init(void)
{
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
factory_data_env_config();
return 0;
diff --git a/board/gateworks/venice/venice.c b/board/gateworks/venice/venice.c
index 4290a69..f1efabb 100644
--- a/board/gateworks/venice/venice.c
+++ b/board/gateworks/venice/venice.c
@@ -128,8 +128,6 @@
u8 enetaddr[6];
char fdt[64];
- led_default_state();
-
/* Set board serial/model */
if (!env_get("serial#"))
env_set_ulong("serial#", eeprom_get_serial());
diff --git a/board/k+p/kp_imx6q_tpc/kp_imx6q_tpc.c b/board/k+p/kp_imx6q_tpc/kp_imx6q_tpc.c
index 110496d..e6877e4 100644
--- a/board/k+p/kp_imx6q_tpc/kp_imx6q_tpc.c
+++ b/board/k+p/kp_imx6q_tpc/kp_imx6q_tpc.c
@@ -137,9 +137,6 @@
add_board_boot_modes(board_boot_modes);
#endif
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
env_set("boardname", "kp-tpc");
env_set("boardsoc", "imx6q");
return 0;
diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c
index 1c516aa..6abf08b 100644
--- a/board/mscc/jr2/jr2.c
+++ b/board/mscc/jr2/jr2.c
@@ -30,10 +30,6 @@
/* Address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
- /* LED setup */
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/mscc/luton/luton.c b/board/mscc/luton/luton.c
index 038902d..76e3f2e 100644
--- a/board/mscc/luton/luton.c
+++ b/board/mscc/luton/luton.c
@@ -31,10 +31,6 @@
/* Address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
- /* LED setup */
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/mscc/ocelot/ocelot.c b/board/mscc/ocelot/ocelot.c
index c462890..2a75ec2 100644
--- a/board/mscc/ocelot/ocelot.c
+++ b/board/mscc/ocelot/ocelot.c
@@ -79,10 +79,6 @@
/* Address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
- /* LED setup */
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/mscc/serval/serval.c b/board/mscc/serval/serval.c
index 94c1c42..87e7907 100644
--- a/board/mscc/serval/serval.c
+++ b/board/mscc/serval/serval.c
@@ -24,10 +24,6 @@
/* Address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
- /* LED setup */
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/mscc/servalt/servalt.c b/board/mscc/servalt/servalt.c
index 252d8e3..bd8c7e8 100644
--- a/board/mscc/servalt/servalt.c
+++ b/board/mscc/servalt/servalt.c
@@ -24,10 +24,6 @@
/* Address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
- /* LED setup */
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/phytec/pcm052/pcm052.c b/board/phytec/pcm052/pcm052.c
index f9cf4ab..0f72359 100644
--- a/board/phytec/pcm052/pcm052.c
+++ b/board/phytec/pcm052/pcm052.c
@@ -360,9 +360,6 @@
struct src *psrc = (struct src *)SRC_BASE_ADDR;
u32 reg;
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
/*
* BK4r1 handle emergency/service SD card boot
* Checking the SBMR1 register BOOTCFG1 byte:
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 28ad6ef..e054f30 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -107,9 +107,6 @@
int board_init(void)
{
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
return 0;
}
diff --git a/board/siemens/capricorn/board.c b/board/siemens/capricorn/board.c
index dcbab8e..4a02d64 100644
--- a/board/siemens/capricorn/board.c
+++ b/board/siemens/capricorn/board.c
@@ -244,10 +244,6 @@
u8 pca_led[2] = { 0x00, 0x00 };
int ret;
- /* init all GPIO LED's */
- if (IS_ENABLED(CONFIG_LED))
- led_default_state();
-
/* enable all leds on PCA9552 */
ret = uclass_get_device_by_seq(UCLASS_I2C, PCA9552_1_I2C_BUS, &bus);
if (ret) {
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index fff1880..7466e1c 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -666,9 +666,6 @@
if (IS_ENABLED(CONFIG_ARMV7_NONSEC))
sysconf_init();
- if (CONFIG_IS_ENABLED(LED))
- led_default_state();
-
setup_led(LEDST_ON);
return 0;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index e09c12f..17dd120 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -361,6 +361,28 @@
}
#endif
+static int dm_probe_devices(struct udevice *dev, bool pre_reloc_only)
+{
+ u32 mask = DM_FLAG_PROBE_AFTER_BIND;
+ u32 flags = dev_get_flags(dev);
+ struct udevice *child;
+ int ret;
+
+ if (pre_reloc_only)
+ mask |= DM_FLAG_PRE_RELOC;
+
+ if ((flags & mask) == mask) {
+ ret = device_probe(dev);
+ if (ret)
+ return ret;
+ }
+
+ list_for_each_entry(child, &dev->child_head, sibling_node)
+ dm_probe_devices(child, pre_reloc_only);
+
+ return 0;
+}
+
/**
* dm_scan() - Scan tables to bind devices
*
@@ -393,7 +415,7 @@
if (ret)
return ret;
- return 0;
+ return dm_probe_devices(gd->dm_root, pre_reloc_only);
}
int dm_init_and_scan(bool pre_reloc_only)
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index 5d7bf40..68ca3c2 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -66,12 +66,6 @@
}
#endif
-/* This is superseded by led_post_bind()/led_post_probe() below. */
-int led_default_state(void)
-{
- return 0;
-}
-
static int led_post_bind(struct udevice *dev)
{
struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
@@ -98,7 +92,9 @@
* In case the LED has default-state DT property, trigger
* probe() to configure its default state during startup.
*/
- return device_probe(dev);
+ dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+
+ return 0;
}
static int led_post_probe(struct udevice *dev)
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index 958dbd3..fbed151 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -57,19 +57,9 @@
static int led_gpio_probe(struct udevice *dev)
{
- struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
struct led_gpio_priv *priv = dev_get_priv(dev);
- int ret;
- /* Ignore the top-level LED node */
- if (!uc_plat->label)
- return 0;
-
- ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
- if (ret)
- return ret;
-
- return 0;
+ return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
}
static int led_gpio_remove(struct udevice *dev)
@@ -110,18 +100,23 @@
.get_state = gpio_led_get_state,
};
+U_BOOT_DRIVER(led_gpio) = {
+ .name = "gpio_led",
+ .id = UCLASS_LED,
+ .ops = &gpio_led_ops,
+ .priv_auto = sizeof(struct led_gpio_priv),
+ .probe = led_gpio_probe,
+ .remove = led_gpio_remove,
+};
+
static const struct udevice_id led_gpio_ids[] = {
{ .compatible = "gpio-leds" },
{ }
};
-U_BOOT_DRIVER(led_gpio) = {
- .name = "gpio_led",
- .id = UCLASS_LED,
+U_BOOT_DRIVER(led_gpio_wrap) = {
+ .name = "gpio_led_wrap",
+ .id = UCLASS_NOP,
.of_match = led_gpio_ids,
- .ops = &gpio_led_ops,
- .priv_auto = sizeof(struct led_gpio_priv),
.bind = led_gpio_bind,
- .probe = led_gpio_probe,
- .remove = led_gpio_remove,
};
diff --git a/include/dm/device.h b/include/dm/device.h
index b474888..5bdb106 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -80,6 +80,9 @@
*/
#define DM_FLAG_VITAL (1 << 14)
+/* Device must be probed after it was bound */
+#define DM_FLAG_PROBE_AFTER_BIND (1 << 15)
+
/*
* One or multiple of these flags are passed to device_remove() so that
* a selective device removal as specified by the remove-stage and the
diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h
index 9e1256a..3be89a7 100644
--- a/include/dt-bindings/leds/common.h
+++ b/include/dt-bindings/leds/common.h
@@ -6,6 +6,7 @@
* Author: Jacek Anaszewski <j.anaszewski@samsung.com>
*
* Copyright (C) 2019 Jacek Anaszewski <jacek.anaszewski@gmail.com>
+ * Copyright (C) 2020 Pavel Machek <pavel@ucw.cz>
*/
#ifndef __DT_BINDINGS_LEDS_H
@@ -29,19 +30,51 @@
#define LED_COLOR_ID_VIOLET 5
#define LED_COLOR_ID_YELLOW 6
#define LED_COLOR_ID_IR 7
-#define LED_COLOR_ID_MAX 8
+#define LED_COLOR_ID_MULTI 8 /* For multicolor LEDs */
+#define LED_COLOR_ID_RGB 9 /* For multicolor LEDs that can do arbitrary color,
+ so this would include RGBW and similar */
+#define LED_COLOR_ID_MAX 10
/* Standard LED functions */
+/* Keyboard LEDs, usually it would be input4::capslock etc. */
+/* Obsolete equivalent: "shift-key-light" */
+#define LED_FUNCTION_CAPSLOCK "capslock"
+#define LED_FUNCTION_SCROLLLOCK "scrolllock"
+#define LED_FUNCTION_NUMLOCK "numlock"
+/* Obsolete equivalents: "tpacpi::thinklight" (IBM/Lenovo Thinkpads),
+ "lp5523:kb{1,2,3,4,5,6}" (Nokia N900) */
+#define LED_FUNCTION_KBD_BACKLIGHT "kbd_backlight"
+
+/* System LEDs, usually found on system body.
+ platform::mute (etc) is sometimes seen, :mute would be better */
+#define LED_FUNCTION_POWER "power"
+#define LED_FUNCTION_DISK "disk"
+
+/* Obsolete: "platform:*:charging" (allwinner sun50i) */
+#define LED_FUNCTION_CHARGING "charging"
+/* Used RGB notification LEDs common on phones.
+ Obsolete equivalents: "status-led:{red,green,blue}" (Motorola Droid 4),
+ "lp5523:{r,g,b}" (Nokia N900) */
+#define LED_FUNCTION_STATUS "status"
+
+#define LED_FUNCTION_MICMUTE "micmute"
+#define LED_FUNCTION_MUTE "mute"
+
+/* Used for player LEDs as found on game controllers from e.g. Nintendo, Sony. */
+#define LED_FUNCTION_PLAYER1 "player-1"
+#define LED_FUNCTION_PLAYER2 "player-2"
+#define LED_FUNCTION_PLAYER3 "player-3"
+#define LED_FUNCTION_PLAYER4 "player-4"
+#define LED_FUNCTION_PLAYER5 "player-5"
+
+/* Miscelleaus functions. Use functions above if you can. */
#define LED_FUNCTION_ACTIVITY "activity"
#define LED_FUNCTION_ALARM "alarm"
#define LED_FUNCTION_BACKLIGHT "backlight"
#define LED_FUNCTION_BLUETOOTH "bluetooth"
#define LED_FUNCTION_BOOT "boot"
#define LED_FUNCTION_CPU "cpu"
-#define LED_FUNCTION_CAPSLOCK "capslock"
-#define LED_FUNCTION_CHARGING "charging"
#define LED_FUNCTION_DEBUG "debug"
-#define LED_FUNCTION_DISK "disk"
#define LED_FUNCTION_DISK_ACTIVITY "disk-activity"
#define LED_FUNCTION_DISK_ERR "disk-err"
#define LED_FUNCTION_DISK_READ "disk-read"
@@ -50,21 +83,14 @@
#define LED_FUNCTION_FLASH "flash"
#define LED_FUNCTION_HEARTBEAT "heartbeat"
#define LED_FUNCTION_INDICATOR "indicator"
-#define LED_FUNCTION_KBD_BACKLIGHT "kbd_backlight"
#define LED_FUNCTION_LAN "lan"
#define LED_FUNCTION_MAIL "mail"
#define LED_FUNCTION_MTD "mtd"
-#define LED_FUNCTION_MICMUTE "micmute"
-#define LED_FUNCTION_MUTE "mute"
-#define LED_FUNCTION_NUMLOCK "numlock"
#define LED_FUNCTION_PANIC "panic"
#define LED_FUNCTION_PROGRAMMING "programming"
-#define LED_FUNCTION_POWER "power"
#define LED_FUNCTION_RX "rx"
#define LED_FUNCTION_SD "sd"
-#define LED_FUNCTION_SCROLLLOCK "scrolllock"
#define LED_FUNCTION_STANDBY "standby"
-#define LED_FUNCTION_STATUS "status"
#define LED_FUNCTION_TORCH "torch"
#define LED_FUNCTION_TX "tx"
#define LED_FUNCTION_USB "usb"
diff --git a/include/led.h b/include/led.h
index 43acca8..3290410 100644
--- a/include/led.h
+++ b/include/led.h
@@ -110,13 +110,4 @@
*/
int led_set_period(struct udevice *dev, int period_ms);
-/**
- * led_default_state() - set the default state for all the LED
- *
- * This enables all leds which have default state.
- * see Documentation/devicetree/bindings/leds/common.txt
- *
- */
-int led_default_state(void);
-
#endif
diff --git a/test/cmd/pinmux.c b/test/cmd/pinmux.c
index de3bb0d..df40bb7 100644
--- a/test/cmd/pinmux.c
+++ b/test/cmd/pinmux.c
@@ -7,12 +7,17 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <dm/test.h>
#include <test/test.h>
#include <test/ut.h>
static int dm_test_cmd_pinmux_status_pinname(struct unit_test_state *uts)
{
+ struct udevice *dev;
+
+ ut_assertok(uclass_get_device(UCLASS_LED, 2, &dev));
+
/* Test that 'pinmux status <pinname>' displays the selected pin. */
console_record_reset();
run_command("pinmux status a5", 0);
diff --git a/test/dm/led.c b/test/dm/led.c
index ac6ee36..eed3f46 100644
--- a/test/dm/led.c
+++ b/test/dm/led.c
@@ -21,8 +21,7 @@
ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
ut_assertok(uclass_get_device(UCLASS_LED, 2, &dev));
ut_assertok(uclass_get_device(UCLASS_LED, 3, &dev));
- ut_assertok(uclass_get_device(UCLASS_LED, 4, &dev));
- ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 5, &dev));
+ ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 4, &dev));
return 0;
}
@@ -33,9 +32,6 @@
{
struct udevice *dev;
- /* configure the default state (auto-probe) */
- led_default_state();
-
/* Check that we handle the default-state property correctly. */
ut_assertok(led_get_by_label("sandbox:default_on", &dev));
ut_asserteq(LEDST_ON, led_get_state(dev));
@@ -55,10 +51,10 @@
struct udevice *dev, *gpio;
/*
- * Check that we can manipulate an LED. LED 1 is connected to GPIO
+ * Check that we can manipulate an LED. LED 0 is connected to GPIO
* bank gpio_a, offset 1.
*/
- ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 0, &dev));
ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
ut_assertok(led_set_state(dev, LEDST_ON));
@@ -80,10 +76,10 @@
struct udevice *dev, *gpio;
/*
- * Check that we can manipulate an LED. LED 1 is connected to GPIO
+ * Check that we can manipulate an LED. LED 0 is connected to GPIO
* bank gpio_a, offset 1.
*/
- ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 0, &dev));
ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
ut_assertok(led_set_state(dev, LEDST_TOGGLE));
@@ -105,12 +101,12 @@
ut_assertok(led_get_by_label("sandbox:red", &dev));
ut_asserteq(1, device_active(dev));
- ut_assertok(uclass_get_device(UCLASS_LED, 1, &cmp));
+ ut_assertok(uclass_get_device(UCLASS_LED, 0, &cmp));
ut_asserteq_ptr(dev, cmp);
ut_assertok(led_get_by_label("sandbox:green", &dev));
ut_asserteq(1, device_active(dev));
- ut_assertok(uclass_get_device(UCLASS_LED, 2, &cmp));
+ ut_assertok(uclass_get_device(UCLASS_LED, 1, &cmp));
ut_asserteq_ptr(dev, cmp);
ut_asserteq(-ENODEV, led_get_by_label("sandbox:blue", &dev));
@@ -130,7 +126,7 @@
* Check that we get an error when trying to blink an LED, since it is
* not supported by the GPIO LED driver.
*/
- ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 0, &dev));
ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
ut_asserteq(-ENOSYS, led_set_state(dev, LEDST_BLINK));