static int lp50xx_probe_dt()

in leds-lp50xx.c [440:522]


static int lp50xx_probe_dt(struct lp50xx *priv)
{
	struct fwnode_handle *child = NULL;
	struct fwnode_handle *led_node = NULL;
	struct led_init_data init_data = {};
	struct led_classdev *led_cdev;
	struct mc_subled *mc_led_info;
	struct lp50xx_led *led;
	int ret = -EINVAL;
	int num_colors;
	u32 color_id;
	int i = 0;

	priv->enable_gpio = devm_gpiod_get_optional(priv->dev, "enable", GPIOD_OUT_LOW);
	if (IS_ERR(priv->enable_gpio))
		return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio),
				     "Failed to get enable GPIO\n");

	priv->regulator = devm_regulator_get(priv->dev, "vled");
	if (IS_ERR(priv->regulator))
		priv->regulator = NULL;

	device_for_each_child_node(priv->dev, child) {
		led = &priv->leds[i];
		ret = fwnode_property_count_u32(child, "reg");
		if (ret < 0) {
			dev_err(priv->dev, "reg property is invalid\n");
			goto child_out;
		}

		ret = lp50xx_probe_leds(child, priv, led, ret);
		if (ret)
			goto child_out;

		init_data.fwnode = child;
		num_colors = 0;

		/*
		 * There are only 3 LEDs per module otherwise they should be
		 * banked which also is presented as 3 LEDs.
		 */
		mc_led_info = devm_kcalloc(priv->dev, LP50XX_LEDS_PER_MODULE,
					   sizeof(*mc_led_info), GFP_KERNEL);
		if (!mc_led_info) {
			ret = -ENOMEM;
			goto child_out;
		}

		fwnode_for_each_child_node(child, led_node) {
			ret = fwnode_property_read_u32(led_node, "color",
						       &color_id);
			if (ret) {
				fwnode_handle_put(led_node);
				dev_err(priv->dev, "Cannot read color\n");
				goto child_out;
			}

			mc_led_info[num_colors].color_index = color_id;
			num_colors++;
		}

		led->priv = priv;
		led->mc_cdev.num_colors = num_colors;
		led->mc_cdev.subled_info = mc_led_info;
		led_cdev = &led->mc_cdev.led_cdev;
		led_cdev->brightness_set_blocking = lp50xx_brightness_set;

		ret = devm_led_classdev_multicolor_register_ext(priv->dev,
						       &led->mc_cdev,
						       &init_data);
		if (ret) {
			dev_err(priv->dev, "led register err: %d\n", ret);
			goto child_out;
		}
		i++;
	}

	return 0;

child_out:
	fwnode_handle_put(child);
	return ret;
}