in flash/leds-mt6360.c [794:882]
static int mt6360_led_probe(struct platform_device *pdev)
{
struct mt6360_priv *priv;
struct fwnode_handle *child;
size_t count;
int i = 0, ret;
count = device_get_child_node_count(&pdev->dev);
if (!count || count > MT6360_MAX_LEDS) {
dev_err(&pdev->dev,
"No child node or node count over max led number %zu\n",
count);
return -EINVAL;
}
priv = devm_kzalloc(&pdev->dev,
struct_size(priv, leds, count), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->leds_count = count;
priv->dev = &pdev->dev;
mutex_init(&priv->lock);
priv->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!priv->regmap) {
dev_err(&pdev->dev, "Failed to get parent regmap\n");
return -ENODEV;
}
device_for_each_child_node(&pdev->dev, child) {
struct mt6360_led *led = priv->leds + i;
struct led_init_data init_data = { .fwnode = child, };
u32 reg, led_color;
ret = fwnode_property_read_u32(child, "color", &led_color);
if (ret)
goto out_flash_release;
if (led_color == LED_COLOR_ID_RGB ||
led_color == LED_COLOR_ID_MULTI)
reg = MT6360_VIRTUAL_MULTICOLOR;
else {
ret = fwnode_property_read_u32(child, "reg", ®);
if (ret)
goto out_flash_release;
if (reg >= MT6360_MAX_LEDS) {
ret = -EINVAL;
goto out_flash_release;
}
}
if (priv->leds_active & BIT(reg)) {
ret = -EINVAL;
goto out_flash_release;
}
priv->leds_active |= BIT(reg);
led->led_no = reg;
led->priv = priv;
ret = mt6360_init_common_properties(led, &init_data);
if (ret)
goto out_flash_release;
if (reg == MT6360_VIRTUAL_MULTICOLOR ||
reg <= MT6360_LED_ISNKML)
ret = mt6360_init_isnk_properties(led, &init_data);
else
ret = mt6360_init_flash_properties(led, &init_data);
if (ret)
goto out_flash_release;
ret = mt6360_led_register(&pdev->dev, led, &init_data);
if (ret)
goto out_flash_release;
i++;
}
platform_set_drvdata(pdev, priv);
return 0;
out_flash_release:
mt6360_v4l2_flash_release(priv);
return ret;
}