summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhiyong Tao <zhiyong.tao@mediatek.com>2021-03-21 11:31:50 +0800
committerLinus Walleij <linus.walleij@linaro.org>2021-03-25 10:14:50 +0100
commit42a46434e9b18b35d2e57433cdbeff3233ca9765 (patch)
tree2ae95aa6a5a8d58de13a40b233e859c853d861c3
parent1517dad8e7129c5e28bd7b536c560f0f0bff87a4 (diff)
downloadlinux-42a46434e9b18b35d2e57433cdbeff3233ca9765.tar.bz2
pinctrl: add lock in mtk_rmw function.
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>
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-moore.c2
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c4
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h2
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-paris.c2
4 files changed, 10 insertions, 0 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
index 0fa7de43bc4c..f77921957f15 100644
--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
@@ -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);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 72f17f26acd8..fcf7c3eeee4a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -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,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index e2aae285b5fc..65eac708a3b3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -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);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index da1f19288aa6..48e823f6d293 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -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);