dm: Add support for LEDs

Add a simple uclass for LEDs, so that these can be controlled by the device
tree and activated when needed. LEDs are referred to by their label.

This implementation requires a driver for each type of LED (e.g GPIO, I2C).

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c7e526c..5ebc89d 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -20,6 +20,8 @@
 
 source "drivers/input/Kconfig"
 
+source "drivers/led/Kconfig"
+
 source "drivers/serial/Kconfig"
 
 source "drivers/tpm/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 405b64b..c090aba 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -7,6 +7,7 @@
 obj-y += crypto/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += hwmon/
+obj-$(CONFIG_LED) += led/
 obj-y += misc/
 obj-y += pcmcia/
 obj-y += dfu/
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
new file mode 100644
index 0000000..e4d9a84
--- /dev/null
+++ b/drivers/led/Kconfig
@@ -0,0 +1,17 @@
+config LED
+	bool "Enable LED support"
+	depends on DM
+	help
+	  Many boards have LEDs which can be used to signal status or alerts.
+	  U-Boot provides a uclass API to implement this feature. LED drivers
+	  can provide access to board-specific LEDs. Use of the device tree
+	  for configuration is encouraged.
+
+config SPL_LED_SUPPORT
+	bool "Enable LED support in SPL"
+	depends on LED
+	help
+	  The LED subsystem adds a small amount of overhead to the image.
+	  If this is acceptable and you have a need to use LEDs in SPL,
+	  enable this option. You will need to enable device tree in SPL
+	  for this to work.
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
new file mode 100644
index 0000000..b39b205
--- /dev/null
+++ b/drivers/led/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_LED) += led-uclass.o
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
new file mode 100644
index 0000000..a80ae93
--- /dev/null
+++ b/drivers/led/led-uclass.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+
+int led_get_by_label(const char *label, struct udevice **devp)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_LED, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(dev, uc) {
+		struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+		if (!strcmp(label, uc_plat->label))
+			return uclass_get_device_tail(dev, 0, devp);
+	}
+
+	return -ENOENT;
+}
+
+int led_set_on(struct udevice *dev, int on)
+{
+	struct led_ops *ops = led_get_ops(dev);
+
+	if (!ops->set_on)
+		return -ENOSYS;
+
+	return ops->set_on(dev, on);
+}
+
+UCLASS_DRIVER(led) = {
+	.id		= UCLASS_LED,
+	.name		= "led",
+	.per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat),
+};