in leds-mc13783.c [176:262]
static int __init mc13xxx_led_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(dev);
struct mc13xxx *mcdev = dev_get_drvdata(dev->parent);
struct mc13xxx_led_devtype *devtype =
(struct mc13xxx_led_devtype *)pdev->id_entry->driver_data;
struct mc13xxx_leds *leds;
int i, id, ret = -ENODATA;
u32 init_led = 0;
leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
if (!leds)
return -ENOMEM;
leds->devtype = devtype;
leds->master = mcdev;
platform_set_drvdata(pdev, leds);
if (dev_of_node(dev->parent)) {
pdata = mc13xxx_led_probe_dt(pdev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
} else if (!pdata)
return -ENODATA;
leds->num_leds = pdata->num_leds;
if ((leds->num_leds < 1) ||
(leds->num_leds > (devtype->led_max - devtype->led_min + 1))) {
dev_err(dev, "Invalid LED count %d\n", leds->num_leds);
return -EINVAL;
}
leds->led = devm_kcalloc(dev, leds->num_leds, sizeof(*leds->led),
GFP_KERNEL);
if (!leds->led)
return -ENOMEM;
for (i = 0; i < devtype->num_regs; i++) {
ret = mc13xxx_reg_write(mcdev, leds->devtype->ledctrl_base + i,
pdata->led_control[i]);
if (ret)
return ret;
}
for (i = 0; i < leds->num_leds; i++) {
const char *name, *trig;
ret = -EINVAL;
id = pdata->led[i].id;
name = pdata->led[i].name;
trig = pdata->led[i].default_trigger;
if ((id > devtype->led_max) || (id < devtype->led_min)) {
dev_err(dev, "Invalid ID %i\n", id);
break;
}
if (init_led & (1 << id)) {
dev_warn(dev, "LED %i already initialized\n", id);
break;
}
init_led |= 1 << id;
leds->led[i].id = id;
leds->led[i].leds = leds;
leds->led[i].cdev.name = name;
leds->led[i].cdev.default_trigger = trig;
leds->led[i].cdev.flags = LED_CORE_SUSPENDRESUME;
leds->led[i].cdev.brightness_set_blocking = mc13xxx_led_set;
leds->led[i].cdev.max_brightness = mc13xxx_max_brightness(id);
ret = led_classdev_register(dev->parent, &leds->led[i].cdev);
if (ret) {
dev_err(dev, "Failed to register LED %i\n", id);
break;
}
}
if (ret)
while (--i >= 0)
led_classdev_unregister(&leds->led[i].cdev);
return ret;
}