in renesas/core.c [930:1064]
static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info)
{
const struct pinmux_bias_reg *bias_regs = info->bias_regs;
const char *drvname = info->name;
unsigned int *refcnts;
unsigned int i, j, k;
pr_info("sh_pfc: Checking %s\n", drvname);
sh_pfc_num_regs = 0;
sh_pfc_num_enums = 0;
/* Check pins */
for (i = 0; i < info->nr_pins; i++) {
const struct sh_pfc_pin *pin = &info->pins[i];
if (!pin->name) {
sh_pfc_err("empty pin %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
const struct sh_pfc_pin *pin2 = &info->pins[j];
if (same_name(pin->name, pin2->name))
sh_pfc_err("pin %s: name conflict\n",
pin->name);
if (pin->pin != (u16)-1 && pin->pin == pin2->pin)
sh_pfc_err("pin %s/%s: pin %u conflict\n",
pin->name, pin2->name, pin->pin);
if (pin->enum_id && pin->enum_id == pin2->enum_id)
sh_pfc_err("pin %s/%s: enum_id %u conflict\n",
pin->name, pin2->name,
pin->enum_id);
}
}
/* Check groups and functions */
refcnts = kcalloc(info->nr_groups, sizeof(*refcnts), GFP_KERNEL);
if (!refcnts)
return;
for (i = 0; i < info->nr_functions; i++) {
const struct sh_pfc_function *func = &info->functions[i];
if (!func->name) {
sh_pfc_err("empty function %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
if (same_name(func->name, info->functions[j].name))
sh_pfc_err("function %s: name conflict\n",
func->name);
}
for (j = 0; j < func->nr_groups; j++) {
for (k = 0; k < info->nr_groups; k++) {
if (same_name(func->groups[j],
info->groups[k].name)) {
refcnts[k]++;
break;
}
}
if (k == info->nr_groups)
sh_pfc_err("function %s: group %s not found\n",
func->name, func->groups[j]);
}
}
for (i = 0; i < info->nr_groups; i++) {
const struct sh_pfc_pin_group *group = &info->groups[i];
if (!group->name) {
sh_pfc_err("empty group %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
if (same_name(group->name, info->groups[j].name))
sh_pfc_err("group %s: name conflict\n",
group->name);
}
if (!refcnts[i])
sh_pfc_err("orphan group %s\n", group->name);
else if (refcnts[i] > 1)
sh_pfc_warn("group %s referenced by %u functions\n",
group->name, refcnts[i]);
}
kfree(refcnts);
/* Check config register descriptions */
for (i = 0; info->cfg_regs && info->cfg_regs[i].reg; i++)
sh_pfc_check_cfg_reg(drvname, &info->cfg_regs[i]);
/* Check drive strength registers */
for (i = 0; info->drive_regs && info->drive_regs[i].reg; i++)
sh_pfc_check_drive_reg(info, &info->drive_regs[i]);
/* Check bias registers */
for (i = 0; bias_regs && (bias_regs[i].puen || bias_regs[i].pud); i++)
sh_pfc_check_bias_reg(info, &bias_regs[i]);
/* Check ioctrl registers */
for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++)
sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg, U32_MAX);
/* Check data registers */
for (i = 0; info->data_regs && info->data_regs[i].reg; i++) {
sh_pfc_check_reg(drvname, info->data_regs[i].reg,
GENMASK(info->data_regs[i].reg_width - 1, 0));
sh_pfc_check_reg_enums(drvname, info->data_regs[i].reg,
info->data_regs[i].enum_ids,
info->data_regs[i].reg_width);
}
#ifdef CONFIG_PINCTRL_SH_FUNC_GPIO
/* Check function GPIOs */
for (i = 0; i < info->nr_func_gpios; i++) {
const struct pinmux_func *func = &info->func_gpios[i];
if (!func->name) {
sh_pfc_err("empty function gpio %u\n", i);
continue;
}
for (j = 0; j < i; j++) {
if (same_name(func->name, info->func_gpios[j].name))
sh_pfc_err("func_gpio %s: name conflict\n",
func->name);
}
if (sh_pfc_check_enum(drvname, func->enum_id))
sh_pfc_err("%s enum_id %u conflict\n", func->name,
func->enum_id);
}
#endif
}