in leds-bcm6328.c [392:465]
static int bcm6328_leds_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev_of_node(&pdev->dev);
struct device_node *child;
void __iomem *mem;
spinlock_t *lock; /* memory lock */
unsigned long val, *blink_leds, *blink_delay;
mem = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mem))
return PTR_ERR(mem);
lock = devm_kzalloc(dev, sizeof(*lock), GFP_KERNEL);
if (!lock)
return -ENOMEM;
blink_leds = devm_kcalloc(dev, BCM6328_LED_BLINK_DELAYS,
sizeof(*blink_leds), GFP_KERNEL);
if (!blink_leds)
return -ENOMEM;
blink_delay = devm_kcalloc(dev, BCM6328_LED_BLINK_DELAYS,
sizeof(*blink_delay), GFP_KERNEL);
if (!blink_delay)
return -ENOMEM;
spin_lock_init(lock);
bcm6328_led_write(mem + BCM6328_REG_HWDIS, ~0);
bcm6328_led_write(mem + BCM6328_REG_LNKACTSEL_HI, 0);
bcm6328_led_write(mem + BCM6328_REG_LNKACTSEL_LO, 0);
val = bcm6328_led_read(mem + BCM6328_REG_INIT);
val &= ~(BCM6328_INIT_MASK);
if (of_property_read_bool(np, "brcm,serial-leds"))
val |= BCM6328_SERIAL_LED_EN;
if (of_property_read_bool(np, "brcm,serial-mux"))
val |= BCM6328_SERIAL_LED_MUX;
if (of_property_read_bool(np, "brcm,serial-clk-low"))
val |= BCM6328_SERIAL_LED_CLK_NPOL;
if (!of_property_read_bool(np, "brcm,serial-dat-low"))
val |= BCM6328_SERIAL_LED_DATA_PPOL;
if (!of_property_read_bool(np, "brcm,serial-shift-inv"))
val |= BCM6328_SERIAL_LED_SHIFT_DIR;
bcm6328_led_write(mem + BCM6328_REG_INIT, val);
for_each_available_child_of_node(np, child) {
int rc;
u32 reg;
if (of_property_read_u32(child, "reg", ®))
continue;
if (reg >= BCM6328_LED_MAX_COUNT) {
dev_err(dev, "invalid LED (%u >= %d)\n", reg,
BCM6328_LED_MAX_COUNT);
continue;
}
if (of_property_read_bool(child, "brcm,hardware-controlled"))
rc = bcm6328_hwled(dev, child, reg, mem, lock);
else
rc = bcm6328_led(dev, child, reg, mem, lock,
blink_leds, blink_delay);
if (rc < 0) {
of_node_put(child);
return rc;
}
}
return 0;
}