static int mt6323_led_probe()

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", &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;
}