@@ -324,84 +324,63 @@ static int is31fl32xx_init_regs(struct is31fl32xx_priv *priv)
return 0;
}
-static int is31fl32xx_parse_child_dt(const struct device *dev,
- const struct device_node *child,
- struct is31fl32xx_led_data *led_data)
+static bool is31fl32xx_has_led(struct is31fl32xx_priv *priv, u8 channel)
{
- struct led_classdev *cdev = &led_data->cdev;
- int ret = 0;
- u32 reg;
+ int i;
- if (of_property_read_string(child, "label", &cdev->name))
- cdev->name = child->name;
+ for (i = 0; i < priv->num_leds; ++i)
+ if (priv->leds[i].channel == channel)
+ return true;
+
+ return false;
+}
+
+static int is31fl32xx_led_register(struct device *dev, struct device_node *np,
+ struct is31fl32xx_led_data *led_data)
+{
+ struct led_init_data init_data = {};
+ u32 reg;
+ int ret;
- ret = of_property_read_u32(child, "reg", ®);
+ ret = of_property_read_u32(np, "reg", ®);
if (ret || reg < 1 || reg > led_data->priv->cdef->channels) {
- dev_err(dev,
- "Child node %pOF does not have a valid reg property\n",
- child);
+ dev_err(dev, "Node %pOF has no valid reg property\n", np);
return -EINVAL;
}
- led_data->channel = reg;
-
- of_property_read_string(child, "linux,default-trigger",
- &cdev->default_trigger);
- cdev->brightness_set_blocking = is31fl32xx_brightness_set;
-
- return 0;
-}
+ if (is31fl32xx_has_led(led_data->priv, reg)) {
+ dev_err(dev, "Node %pOF reg property already used\n", np);
+ return -EEXIST;
+ }
-static struct is31fl32xx_led_data *is31fl32xx_find_led_data(
- struct is31fl32xx_priv *priv,
- u8 channel)
-{
- size_t i;
+ led_data->channel = reg;
+ led_data->cdev.brightness_set_blocking = is31fl32xx_brightness_set;
+ init_data.fwnode = of_fwnode_handle(np);
- for (i = 0; i < priv->num_leds; i++) {
- if (priv->leds[i].channel == channel)
- return &priv->leds[i];
- }
+ ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data);
+ if (ret)
+ dev_err(dev, "Failed to register LED for %pOF: %d\n", np,
+ ret);
- return NULL;
+ return ret;
}
-static int is31fl32xx_parse_dt(struct device *dev,
- struct is31fl32xx_priv *priv)
+static int is31fl32xx_leds_register(struct device *dev,
+ struct is31fl32xx_priv *priv)
{
struct device_node *child;
- int ret = 0;
+ int ret;
- for_each_child_of_node(dev->of_node, child) {
+ for_each_child_of_node(dev_of_node(dev), child) {
struct is31fl32xx_led_data *led_data =
&priv->leds[priv->num_leds];
- const struct is31fl32xx_led_data *other_led_data;
led_data->priv = priv;
- ret = is31fl32xx_parse_child_dt(dev, child, led_data);
+ ret = is31fl32xx_led_register(dev, child, led_data);
if (ret)
goto err;
- /* Detect if channel is already in use by another child */
- other_led_data = is31fl32xx_find_led_data(priv,
- led_data->channel);
- if (other_led_data) {
- dev_err(dev,
- "%s and %s both attempting to use channel %d\n",
- led_data->cdev.name,
- other_led_data->cdev.name,
- led_data->channel);
- goto err;
- }
-
- ret = devm_led_classdev_register(dev, &led_data->cdev);
- if (ret) {
- dev_err(dev, "failed to register PWM led for %s: %d\n",
- led_data->cdev.name, ret);
- goto err;
- }
-
priv->num_leds++;
}
@@ -457,11 +436,7 @@ static int is31fl32xx_probe(struct i2c_client *client,
if (ret)
return ret;
- ret = is31fl32xx_parse_dt(dev, priv);
- if (ret)
- return ret;
-
- return 0;
+ return is31fl32xx_leds_register(dev, priv);
}
static int is31fl32xx_remove(struct i2c_client *client)
By using struct led_init_data when registering we do not need to parse `label` DT property nor `linux,default-trigger` property. This driver needed small refactoring for this to work nicely. Signed-off-by: Marek BehĂșn <marek.behun@nic.cz> Cc: H. Nikolaus Schaller <hns@goldelico.com> Cc: David Rivshin <drivshin@allworx.com> --- drivers/leds/leds-is31fl32xx.c | 95 +++++++++++++--------------------- 1 file changed, 35 insertions(+), 60 deletions(-)