static int bcm6328_hwled()

in leds-bcm6328.c [255:325]


static int bcm6328_hwled(struct device *dev, struct device_node *nc, u32 reg,
			 void __iomem *mem, spinlock_t *lock)
{
	int i, cnt;
	unsigned long flags, val;

	spin_lock_irqsave(lock, flags);
	val = bcm6328_led_read(mem + BCM6328_REG_HWDIS);
	val &= ~BIT(reg);
	bcm6328_led_write(mem + BCM6328_REG_HWDIS, val);
	spin_unlock_irqrestore(lock, flags);

	/* Only LEDs 0-7 can be activity/link controlled */
	if (reg >= 8)
		return 0;

	cnt = of_property_count_elems_of_size(nc, "brcm,link-signal-sources",
					      sizeof(u32));
	for (i = 0; i < cnt; i++) {
		u32 sel;
		void __iomem *addr;

		if (reg < 4)
			addr = mem + BCM6328_REG_LNKACTSEL_LO;
		else
			addr = mem + BCM6328_REG_LNKACTSEL_HI;

		of_property_read_u32_index(nc, "brcm,link-signal-sources", i,
					   &sel);

		if (reg / 4 != sel / 4) {
			dev_warn(dev, "invalid link signal source\n");
			continue;
		}

		spin_lock_irqsave(lock, flags);
		val = bcm6328_led_read(addr);
		val |= (BIT(reg % 4) << (((sel % 4) * 4) + 16));
		bcm6328_led_write(addr, val);
		spin_unlock_irqrestore(lock, flags);
	}

	cnt = of_property_count_elems_of_size(nc,
					      "brcm,activity-signal-sources",
					      sizeof(u32));
	for (i = 0; i < cnt; i++) {
		u32 sel;
		void __iomem *addr;

		if (reg < 4)
			addr = mem + BCM6328_REG_LNKACTSEL_LO;
		else
			addr = mem + BCM6328_REG_LNKACTSEL_HI;

		of_property_read_u32_index(nc, "brcm,activity-signal-sources",
					   i, &sel);

		if (reg / 4 != sel / 4) {
			dev_warn(dev, "invalid activity signal source\n");
			continue;
		}

		spin_lock_irqsave(lock, flags);
		val = bcm6328_led_read(addr);
		val |= (BIT(reg % 4) << ((sel % 4) * 4));
		bcm6328_led_write(addr, val);
		spin_unlock_irqrestore(lock, flags);
	}

	return 0;
}