in leds-mt6323.c [364:452]
static int mt6323_led_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev_of_node(dev);
struct device_node *child;
struct mt6397_chip *hw = dev_get_drvdata(dev->parent);
struct mt6323_leds *leds;
struct mt6323_led *led;
int ret;
unsigned int status;
u32 reg;
leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
if (!leds)
return -ENOMEM;
platform_set_drvdata(pdev, leds);
leds->dev = dev;
/*
* leds->hw points to the underlying bus for the register
* controlled.
*/
leds->hw = hw;
mutex_init(&leds->lock);
status = MT6323_RG_DRV_32K_CK_PDN;
ret = regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0,
MT6323_RG_DRV_32K_CK_PDN_MASK, ~status);
if (ret < 0) {
dev_err(leds->dev,
"Failed to update MT6323_TOP_CKPDN0 Register\n");
return ret;
}
for_each_available_child_of_node(np, child) {
struct led_init_data init_data = {};
ret = of_property_read_u32(child, "reg", ®);
if (ret) {
dev_err(dev, "Failed to read led 'reg' property\n");
goto put_child_node;
}
if (reg >= MT6323_MAX_LEDS || leds->led[reg]) {
dev_err(dev, "Invalid led reg %u\n", reg);
ret = -EINVAL;
goto put_child_node;
}
led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
if (!led) {
ret = -ENOMEM;
goto put_child_node;
}
leds->led[reg] = led;
leds->led[reg]->id = reg;
leds->led[reg]->cdev.max_brightness = MT6323_MAX_BRIGHTNESS;
leds->led[reg]->cdev.brightness_set_blocking =
mt6323_led_set_brightness;
leds->led[reg]->cdev.blink_set = mt6323_led_set_blink;
leds->led[reg]->cdev.brightness_get =
mt6323_get_led_hw_brightness;
leds->led[reg]->parent = leds;
ret = mt6323_led_set_dt_default(&leds->led[reg]->cdev, child);
if (ret < 0) {
dev_err(leds->dev,
"Failed to LED set default from devicetree\n");
goto put_child_node;
}
init_data.fwnode = of_fwnode_handle(child);
ret = devm_led_classdev_register_ext(dev, &leds->led[reg]->cdev,
&init_data);
if (ret) {
dev_err(dev, "Failed to register LED: %d\n", ret);
goto put_child_node;
}
}
return 0;
put_child_node:
of_node_put(child);
return ret;
}