Parse `led-max-current` property of child nodes and compute aggregated
value in a separate function. The controller cannot set this value
separately for every LED, so there is no need to store this value for
every LED.

Signed-off-by: Marek Behún <[email protected]>
Cc: H. Nikolaus Schaller <[email protected]>
---
 drivers/leds/leds-is31fl319x.c | 61 ++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 22 deletions(-)

diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
index 4161b9dd7e488..ba1a5da5521b5 100644
--- a/drivers/leds/leds-is31fl319x.c
+++ b/drivers/leds/leds-is31fl319x.c
@@ -71,7 +71,6 @@ struct is31fl319x_chip {
        struct is31fl319x_led {
                struct is31fl319x_chip  *chip;
                struct led_classdev     cdev;
-               u32                     max_microamp;
                bool                    configured;
        } leds[IS31FL319X_MAX_LEDS];
 };
@@ -171,6 +170,35 @@ static int is31fl319x_brightness_set(struct led_classdev 
*cdev,
        return ret;
 }
 
+static int is31fl319x_parse_max_current(struct device *dev, u32 *aggregated)
+{
+       struct device_node *np;
+       u32 value;
+       int ret;
+
+       *aggregated = IS31FL319X_CURRENT_MAX;
+
+       for_each_available_child_of_node(dev_of_node(dev), np) {
+               value = IS31FL319X_CURRENT_DEFAULT;
+               ret = of_property_read_u32(np, "led-max-microamp", &value);
+               if (!ret)
+                       value = min(value, IS31FL319X_CURRENT_MAX);
+
+               if (value < IS31FL319X_CURRENT_MIN) {
+                       dev_err(dev,
+                               "Value of led-max-microamp too low for %pOF\n",
+                               np);
+                       of_node_put(np);
+                       return -EINVAL;
+               }
+
+               if (value < *aggregated)
+                       *aggregated = value;
+       }
+
+       return 0;
+}
+
 static int is31fl319x_parse_child_dt(const struct device *dev,
                                     const struct device_node *child,
                                     struct is31fl319x_led *led)
@@ -186,16 +214,6 @@ static int is31fl319x_parse_child_dt(const struct device 
*dev,
        if (ret < 0 && ret != -EINVAL) /* is optional */
                return ret;
 
-       led->max_microamp = IS31FL319X_CURRENT_DEFAULT;
-       ret = of_property_read_u32(child, "led-max-microamp",
-                                  &led->max_microamp);
-       if (!ret) {
-               if (led->max_microamp < IS31FL319X_CURRENT_MIN)
-                       return -EINVAL; /* not supported */
-               led->max_microamp = min(led->max_microamp,
-                                         IS31FL319X_CURRENT_MAX);
-       }
-
        return 0;
 }
 
@@ -339,11 +357,20 @@ static int is31fl319x_probe(struct i2c_client *client,
        struct device *dev = &client->dev;
        int err;
        int i = 0;
-       u32 aggregated_led_microamp = IS31FL319X_CURRENT_MAX;
+       u32 aggregated_led_microamp;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
                return -EIO;
 
+       /*
+        * Kernel conventions require per-LED led-max-microamp property.
+        * But the chip does not allow to limit individual LEDs.
+        * So we take minimum from all subnodes for safety of hardware.
+        */
+       err = is31fl319x_parse_max_current(dev, &aggregated_led_microamp);
+       if (err)
+               return err;
+
        is31 = devm_kzalloc(&client->dev, sizeof(*is31), GFP_KERNEL);
        if (!is31)
                return -ENOMEM;
@@ -379,16 +406,6 @@ static int is31fl319x_probe(struct i2c_client *client,
                goto free_mutex;
        }
 
-       /*
-        * Kernel conventions require per-LED led-max-microamp property.
-        * But the chip does not allow to limit individual LEDs.
-        * So we take minimum from all subnodes for safety of hardware.
-        */
-       for (i = 0; i < is31->cdef->num_leds; i++)
-               if (is31->leds[i].configured &&
-                   is31->leds[i].max_microamp < aggregated_led_microamp)
-                       aggregated_led_microamp = is31->leds[i].max_microamp;
-
        regmap_write(is31->regmap, IS31FL319X_CONFIG2,
                     is31fl319x_microamp_to_cs(dev, aggregated_led_microamp) |
                     is31fl319x_db_to_gain(is31->audio_gain_db));
-- 
2.26.2

Reply via email to