pinctrl: starfive: Serialize adding groups and functions

The pinctrl dt_node_to_map method may be called in parallel which leads
us to call pinconf_generic_add_group and pinconf_generic_add_function
in parallel. This is not supported though and leads to errors, so add a
mutex to serialize these calls.

Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
Link: https://lore.kernel.org/r/20220627085333.1774396-1-emil.renner.berthing@canonical.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Jianlong Huang 2022-06-27 10:53:33 +02:00 committed by Linus Walleij
parent 04131ae29b
commit e2961cd685
1 changed files with 5 additions and 0 deletions

View File

@ -207,6 +207,7 @@ struct starfive_pinctrl {
void __iomem *base; void __iomem *base;
void __iomem *padctl; void __iomem *padctl;
struct pinctrl_dev *pctl; struct pinctrl_dev *pctl;
struct mutex mutex; /* serialize adding groups and functions */
}; };
static inline unsigned int starfive_pin_to_gpio(const struct starfive_pinctrl *sfp, static inline unsigned int starfive_pin_to_gpio(const struct starfive_pinctrl *sfp,
@ -522,6 +523,7 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev,
nmaps = 0; nmaps = 0;
ngroups = 0; ngroups = 0;
mutex_lock(&sfp->mutex);
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
int npins; int npins;
int i; int i;
@ -615,12 +617,14 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev,
*maps = map; *maps = map;
*num_maps = nmaps; *num_maps = nmaps;
mutex_unlock(&sfp->mutex);
return 0; return 0;
put_child: put_child:
of_node_put(child); of_node_put(child);
free_map: free_map:
pinctrl_utils_free_map(pctldev, map, nmaps); pinctrl_utils_free_map(pctldev, map, nmaps);
mutex_unlock(&sfp->mutex);
return ret; return ret;
} }
@ -1267,6 +1271,7 @@ static int starfive_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sfp); platform_set_drvdata(pdev, sfp);
sfp->gc.parent = dev; sfp->gc.parent = dev;
raw_spin_lock_init(&sfp->lock); raw_spin_lock_init(&sfp->lock);
mutex_init(&sfp->mutex);
ret = devm_pinctrl_register_and_init(dev, &starfive_desc, sfp, &sfp->pctl); ret = devm_pinctrl_register_and_init(dev, &starfive_desc, sfp, &sfp->pctl);
if (ret) if (ret)