Hi!
A LED is usually powered by a voltage/current regulator. Let the LED core
know about it. This allows the LED core to turn on or off the power supply
as needed.
Because turning ON/OFF a regulator might block, it is not done
synchronously but done in a workqueue. Turning ON the regulator is
always
How will this interact with LEDs that can be used from atomic context?
+static ssize_t regulator_auto_off_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ ssize_t ret = size;
+ bool auto_off;
+
+ if (strncmp(buf, "enable\n", size) == 0)
+ auto_off = true;
+ else if (strncmp(buf, "disable\n", size) == 0)
+ auto_off = false;
+ else
+ return -EINVAL;
Sounds like device power management to me. Is it compatible with that?
@@ -135,6 +203,8 @@ static void set_brightness_delayed(struct work_struct *ws)
(led_cdev->flags & LED_HW_PLUGGABLE)))
dev_err(led_cdev->dev,
"Setting an LED's brightness failed (%d)\n", ret);
+
+ led_handle_regulator(led_cdev);
}
You only modify set_brigthness_delays, so this will not work at all
for non-blocking LEDs, right?
static void led_set_software_blink(struct led_classdev *led_cdev,
@@ -189,6 +259,7 @@ static void led_blink_setup(struct led_classdev *led_cdev,
void led_init_core(struct led_classdev *led_cdev)
{
INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
+ INIT_DELAYED_WORK(&led_cdev->reg_off_work, turn_off_regulator_delayed);
Could this re-use the workqueue? Many systems will not need
regulators, so this is overhead...
+ /*
+ * the regulator must be turned off. This cannot be
Use "The", and fix double spaces between must and be.
+ } else if (regulator_on && old == REG_R_OFF_U_OFF) {
+ /*
+ * the regulator must be enabled. This cannot be here
"The"
+ /*
+ * small optimization. Cancel the work that had been started
"Small."
+#include <linux/regulator/consumer.h>
+
+/*
+ * The regulator state tracks 2 boolean variables:
+ * - the state of regulator (or more precisely the state required by
+ * led core layer, as many users can interact with the same regulator).
+ * It is tracked by bit 0.
+ * - the state last asked-for by the LED user. It is tracked by bit 1.
+ */
+#define REG_R_ON BIT(0)
+#define REG_U_ON BIT(1)
+
+enum { REG_R_OFF_U_OFF = 0,
+ REG_R_ON_U_OFF = REG_R_ON,
+ REG_R_OFF_U_ON = REG_U_ON,
+ REG_R_ON_U_ON = REG_R_ON | REG_U_ON
+};
That's quite weird use of enum.
+++ b/include/linux/leds.h
@@ -149,6 +149,15 @@ struct led_classdev {
/* Ensures consistent access to the LED Flash Class device */
struct mutex led_access;
+
+ /* regulator */
"Regulator".