Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: make struct pinfunction a pointer in struct function_desc

We currently duplicate the entire struct pinfunction object in
pinmux_generic_add_pinfunction(). While this is inevitable when the
arguments come in split through pinmux_generic_add_function(), users of
pinmux_generic_add_pinfunction() will typically pass addresses of
structures in .rodata, meaning we can try to avoid the duplication with
the help from kmemdup_const(). To that end: don't wrap the entire struct
pinfunction in struct function_desc but rather just store the address.

Tested-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Bartosz Golaszewski and committed by
Linus Walleij
d57b7979 fbba4a9e

+19 -9
+1 -1
drivers/pinctrl/freescale/pinctrl-imx.c
··· 266 266 npins = grp->grp.npins; 267 267 268 268 dev_dbg(ipctl->dev, "enable function %s group %s\n", 269 - func->func.name, grp->grp.name); 269 + func->func->name, grp->grp.name); 270 270 271 271 for (i = 0; i < npins; i++) { 272 272 /*
+1 -1
drivers/pinctrl/mediatek/pinctrl-airoha.c
··· 2456 2456 return -EINVAL; 2457 2457 2458 2458 dev_dbg(pctrl_dev->dev, "enable function %s group %s\n", 2459 - desc->func.name, grp->grp.name); 2459 + desc->func->name, grp->grp.name); 2460 2460 2461 2461 func = desc->data; 2462 2462 for (i = 0; i < func->group_size; i++) {
+1 -1
drivers/pinctrl/mediatek/pinctrl-moore.c
··· 56 56 return -EINVAL; 57 57 58 58 dev_dbg(pctldev->dev, "enable function %s group %s\n", 59 - func->func.name, grp->grp.name); 59 + func->func->name, grp->grp.name); 60 60 61 61 for (i = 0; i < grp->grp.npins; i++) { 62 62 const struct mtk_pin_desc *desc;
+1 -1
drivers/pinctrl/pinctrl-ingenic.c
··· 4015 4015 return -EINVAL; 4016 4016 4017 4017 dev_dbg(pctldev->dev, "enable function %s group %s\n", 4018 - func->func.name, grp->grp.name); 4018 + func->func->name, grp->grp.name); 4019 4019 4020 4020 mode = (uintptr_t)grp->data; 4021 4021 if (mode <= 3) {
+14 -4
drivers/pinctrl/pinmux.c
··· 810 810 if (!function) 811 811 return NULL; 812 812 813 - return function->func.name; 813 + return function->func->name; 814 814 } 815 815 EXPORT_SYMBOL_GPL(pinmux_generic_get_function_name); 816 816 ··· 835 835 __func__, selector); 836 836 return -EINVAL; 837 837 } 838 - *groups = function->func.groups; 839 - *ngroups = function->func.ngroups; 838 + *groups = function->func->groups; 839 + *ngroups = function->func->ngroups; 840 840 841 841 return 0; 842 842 } ··· 903 903 if (!function) 904 904 return -ENOMEM; 905 905 906 - function->func = *func; 906 + /* 907 + * FIXME: It's generally a bad idea to use devres in subsystem core 908 + * code - managed interfaces are aimed at drivers - but pinctrl already 909 + * uses it all over the place so it's a larger piece of technical debt 910 + * to fix. 911 + */ 912 + function->func = devm_kmemdup_const(pctldev->dev, func, 913 + sizeof(*func), GFP_KERNEL); 914 + if (!function->func) 915 + return -ENOMEM; 916 + 907 917 function->data = data; 908 918 909 919 error = radix_tree_insert(&pctldev->pin_function_tree, selector, function);
+1 -1
drivers/pinctrl/pinmux.h
··· 137 137 * @data: pin controller driver specific data 138 138 */ 139 139 struct function_desc { 140 - struct pinfunction func; 140 + const struct pinfunction *func; 141 141 void *data; 142 142 }; 143 143