Merge patch series "led: implement software blinking"

Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> says:

v2 changes:
 * Drop sw_blink_state structure, move its necessary fields to
   led_uc_plat structure.
 * Add cyclic_info pointer to led_uc_plat structure. This
   simplify code a lot.
 * Remove cyclic function search logic. Not needed anymore.
 * Fix blinking period. It was twice large.
 * Other cleanups.

v3 changes:
 * Adapt code to recent cyclic function changes
 * Move software blinking functions to separate file
 * Other small changes

v4 changes:
 * Refactoring of led_set_period() function

v5 changes
 * Fix compilation if CONFIG_LED_BLINK is not defined

v6 changes:
 * Enable LEDST_BLINK state unconditionally.
 * Function led_set_period() becomes available when CONFIG_LED_BLINK
   is disabled. This makes led code simpler.
 * Software blinking requires about 100 bytes of data for a led. It's
   not a good idea to allocate so much memory for each supported led.
   Change the code to allocate blinking data only for required leds.
diff --git a/include/led.h b/include/led.h
index a635316..99f93c5 100644
--- a/include/led.h
+++ b/include/led.h
@@ -7,19 +7,34 @@
 #ifndef __LED_H
 #define __LED_H
 
+#include <stdbool.h>
+#include <cyclic.h>
+
 struct udevice;
 
 enum led_state_t {
 	LEDST_OFF = 0,
 	LEDST_ON = 1,
 	LEDST_TOGGLE,
-#ifdef CONFIG_LED_BLINK
 	LEDST_BLINK,
-#endif
 
 	LEDST_COUNT,
 };
 
+enum led_sw_blink_state_t {
+	LED_SW_BLINK_ST_DISABLED,
+	LED_SW_BLINK_ST_NOT_READY,
+	LED_SW_BLINK_ST_OFF,
+	LED_SW_BLINK_ST_ON,
+};
+
+struct led_sw_blink {
+	enum led_sw_blink_state_t state;
+	struct udevice *dev;
+	struct cyclic_info cyclic;
+	const char cyclic_name[0];
+};
+
 /**
  * struct led_uc_plat - Platform data the uclass stores about each device
  *
@@ -29,6 +44,9 @@
 struct led_uc_plat {
 	const char *label;
 	enum led_state_t default_state;
+#ifdef CONFIG_LED_SW_BLINK
+	struct led_sw_blink *sw_blink;
+#endif
 };
 
 /**
@@ -118,4 +136,9 @@
  */
 int led_bind_generic(struct udevice *parent, const char *driver_name);
 
+/* Internal functions for software blinking. Do not use them in your code */
+int led_sw_set_period(struct udevice *dev, int period_ms);
+bool led_sw_is_blinking(struct udevice *dev);
+bool led_sw_on_state_change(struct udevice *dev, enum led_state_t state);
+
 #endif