pinctrl: add lock in mtk_rmw function.
authorZhiyong Tao <zhiyong.tao@mediatek.com>
Sun, 21 Mar 2021 03:31:50 +0000 (11:31 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Thu, 25 Mar 2021 09:14:50 +0000 (10:14 +0100)
When multiple threads operate on the same register resource
which include multiple pin, It will make the register resource
wrong to control. So we add lock to avoid the case.

Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
Link: https://lore.kernel.org/r/20210321033150.15380-2-zhiyong.tao@mediatek.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/mediatek/pinctrl-moore.c
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
drivers/pinctrl/mediatek/pinctrl-paris.c

index 0fa7de43bc4c885be8651ad23afe0db02d7c97d0..f77921957f153371e51ef9ff1d2e2b28ed534cb4 100644 (file)
@@ -619,6 +619,8 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev,
 
        hw->nbase = hw->soc->nbase_names;
 
+       mutex_init(&hw->lock);
+
        /* Copy from internal struct mtk_pin_desc to register to the core */
        pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),
                                  GFP_KERNEL);
index 72f17f26acd80df9880a4b92e0bf1f2c0b42a436..fcf7c3eeee4a8aa4c67985ff302eff783a2f8fd9 100644 (file)
@@ -58,10 +58,14 @@ void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
 {
        u32 val;
 
+       mutex_lock(&pctl->lock);
+
        val = mtk_r32(pctl, i, reg);
        val &= ~mask;
        val |= set;
        mtk_w32(pctl, i, reg, val);
+
+       mutex_unlock(&pctl->lock);
 }
 
 static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
index e2aae285b5fc9bbbca3c8efdbb877509435a7848..65eac708a3b311e6ed3e953a36f43b3f24b78f29 100644 (file)
@@ -251,6 +251,8 @@ struct mtk_pinctrl {
        struct mtk_eint                 *eint;
        struct mtk_pinctrl_group        *groups;
        const char          **grp_names;
+       /* lock pin's register resource to avoid multiple threads issue*/
+       struct mutex lock;
 };
 
 void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
index da1f19288aa6d428d3e50261a70679db55aa434b..48e823f6d29393d6d115ca9860aa416bdabb7c23 100644 (file)
@@ -970,6 +970,8 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 
        hw->nbase = hw->soc->nbase_names;
 
+       mutex_init(&hw->lock);
+
        err = mtk_pctrl_build_state(pdev);
        if (err) {
                dev_err(&pdev->dev, "build state failed: %d\n", err);