drivers/pinctrl/pinctrl-lantiq.c

Source file repositories/reference/linux-study-clean/drivers/pinctrl/pinctrl-lantiq.c

File Facts

System
Linux kernel
Corpus path
drivers/pinctrl/pinctrl-lantiq.c
Extension
.c
Size
8860 bytes
Lines
346
Domain
Driver Families
Bucket
drivers/pinctrl
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

of_property_for_each_string(np, "lantiq,groups", prop, group) {
			(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
			(*map)->name = function;
			(*map)->data.mux.group = group;
			(*map)->data.mux.function = function;
			(*map)++;
		}
	}

	for (i = 0; i < info->num_params; i++) {
		u32 val;
		int ret = of_property_read_u32(np,
				info->params[i].property, &val);
		if (!ret)
			configs[num_configs++] =
				LTQ_PINCONF_PACK(info->params[i].param,
				val);
	}

	if (!num_configs)
		return;

	of_property_for_each_string(np, "lantiq,pins", prop, pin) {
		(*map)->data.configs.configs = kmemdup(configs,
					num_configs * sizeof(unsigned long),
					GFP_KERNEL);
		(*map)->type = PIN_MAP_TYPE_CONFIGS_PIN;
		(*map)->name = pin;
		(*map)->data.configs.group_or_pin = pin;
		(*map)->data.configs.num_configs = num_configs;
		(*map)++;
	}
	of_property_for_each_string(np, "lantiq,groups", prop, group) {
		(*map)->data.configs.configs = kmemdup(configs,
					num_configs * sizeof(unsigned long),
					GFP_KERNEL);
		(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
		(*map)->name = group;
		(*map)->data.configs.group_or_pin = group;
		(*map)->data.configs.num_configs = num_configs;
		(*map)++;
	}
}

static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
{
	int ret;

	ret = of_property_count_strings(np, "lantiq,groups");
	if (ret < 0)
		ret = of_property_count_strings(np, "lantiq,pins");
	return ret;
}

static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
				      struct device_node *np_config,
				      struct pinctrl_map **map,
				      unsigned *num_maps)
{
	struct pinctrl_map *tmp;
	struct device_node *np;
	int max_maps = 0;

	for_each_child_of_node(np_config, np)
		max_maps += ltq_pinctrl_dt_subnode_size(np);
	*map = kzalloc(array3_size(max_maps, sizeof(struct pinctrl_map), 2),
		       GFP_KERNEL);
	if (!*map)
		return -ENOMEM;
	tmp = *map;

	for_each_child_of_node(np_config, np)
		ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
	*num_maps = ((int)(tmp - *map));

	return 0;
}

static const struct pinctrl_ops ltq_pctrl_ops = {
	.get_groups_count	= ltq_get_group_count,
	.get_group_name		= ltq_get_group_name,
	.get_group_pins		= ltq_get_group_pins,
	.pin_dbg_show		= ltq_pinctrl_pin_dbg_show,
	.dt_node_to_map		= ltq_pinctrl_dt_node_to_map,
	.dt_free_map		= ltq_pinctrl_dt_free_map,
};

static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev)
{
	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);

Annotation

Implementation Notes