aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/srcu.h
blob: aca0eee53930f5014fc1037caab46d46cd16a855 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
generated by cgit v1.2.2 (git 2.25.0) at 2025-10-07 06:33:25 -0400
 


pan class="hl opt">{},
};

static int __init syscon_leds_init(void)
{
	const struct of_device_id *devid;
	struct device_node *np;
	struct device_node *child;
	struct regmap *map;
	struct platform_device *pdev;
	struct device *dev;
	int ret;

	np = of_find_matching_node_and_match(NULL, syscon_match,
					     &devid);
	if (!np)
		return -ENODEV;

	map = syscon_node_to_regmap(np);
	if (IS_ERR(map))
		return PTR_ERR(map);

	/*
	 * If the map is there, the device should be there, we allocate
	 * memory on the syscon device's behalf here.
	 */
	pdev = of_find_device_by_node(np);
	if (!pdev)
		return -ENODEV;
	dev = &pdev->dev;

	for_each_available_child_of_node(np, child) {
		struct syscon_led *sled;
		const char *state;

		/* Only check for register-bit-leds */
		if (of_property_match_string(child, "compatible",
					     "register-bit-led") < 0)
			continue;

		sled = devm_kzalloc(dev, sizeof(*sled), GFP_KERNEL);
		if (!sled)
			return -ENOMEM;

		sled->map = map;

		if (of_property_read_u32(child, "offset", &sled->offset))
			return -EINVAL;
		if (of_property_read_u32(child, "mask", &sled->mask))
			return -EINVAL;
		sled->cdev.name =
			of_get_property(child, "label", NULL) ? : child->name;
		sled->cdev.default_trigger =
			of_get_property(child, "linux,default-trigger", NULL);

		state = of_get_property(child, "default-state", NULL);
		if (state) {
			if (!strcmp(state, "keep")) {
				u32 val;

				ret = regmap_read(map, sled->offset, &val);
				if (ret < 0)
					return ret;
				sled->state = !!(val & sled->mask);
			} else if (!strcmp(state, "on")) {
				sled->state = true;
				ret = regmap_update_bits(map, sled->offset,
							 sled->mask,
							 sled->mask);
				if (ret < 0)
					return ret;
			} else {
				sled->state = false;
				ret = regmap_update_bits(map, sled->offset,
							 sled->mask, 0);
				if (ret < 0)
					return ret;
			}

		}
		sled->cdev.brightness_set = syscon_led_set;

		ret = led_classdev_register(dev, &sled->cdev);
		if (ret < 0)
			return ret;

		dev_info(dev, "registered LED %s\n", sled->cdev.name);
	}

       return 0;
}
device_initcall(syscon_leds_init);