From 42a46434e9b18b35d2e57433cdbeff3233ca9765 Mon Sep 17 00:00:00 2001 From: Zhiyong Tao Date: Sun, 21 Mar 2021 11:31:50 +0800 Subject: 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 Link: https://lore.kernel.org/r/20210321033150.15380-2-zhiyong.tao@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h') 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); -- cgit v1.2.3 From ea9d2ed46520a3fb0b865143cc824aea27deb8fa Mon Sep 17 00:00:00 2001 From: Zhiyong Tao Date: Tue, 13 Apr 2021 13:57:01 +0800 Subject: pinctrl: add drive for I2C related pins on MT8195 This patch provides the advanced drive raw data setting version for I2C used pins on MT8195. Signed-off-by: Zhiyong Tao Acked-by: Sean Wang Link: https://lore.kernel.org/r/20210413055702.27535-4-zhiyong.tao@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mt8195.c | 22 ++++++++++++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 14 ++++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++ 3 files changed, 41 insertions(+) (limited to 'drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h') diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c index 063f164d7c9b..a7500e18bb1d 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8195.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c @@ -760,6 +760,25 @@ static const struct mtk_pin_field_calc mt8195_pin_drv_range[] = { PIN_FIELD_BASE(143, 143, 1, 0x020, 0x10, 24, 3), }; +static const struct mtk_pin_field_calc mt8195_pin_drv_adv_range[] = { + PIN_FIELD_BASE(8, 8, 4, 0x020, 0x10, 15, 3), + PIN_FIELD_BASE(9, 9, 4, 0x020, 0x10, 0, 3), + PIN_FIELD_BASE(10, 10, 4, 0x020, 0x10, 18, 3), + PIN_FIELD_BASE(11, 11, 4, 0x020, 0x10, 3, 3), + PIN_FIELD_BASE(12, 12, 4, 0x020, 0x10, 21, 3), + PIN_FIELD_BASE(13, 13, 4, 0x020, 0x10, 6, 3), + PIN_FIELD_BASE(14, 14, 4, 0x020, 0x10, 24, 3), + PIN_FIELD_BASE(15, 15, 4, 0x020, 0x10, 9, 3), + PIN_FIELD_BASE(16, 16, 4, 0x020, 0x10, 27, 3), + PIN_FIELD_BASE(17, 17, 4, 0x020, 0x10, 12, 3), + PIN_FIELD_BASE(29, 29, 2, 0x020, 0x10, 0, 3), + PIN_FIELD_BASE(30, 30, 2, 0x020, 0x10, 3, 3), + PIN_FIELD_BASE(34, 34, 1, 0x040, 0x10, 0, 3), + PIN_FIELD_BASE(35, 35, 1, 0x040, 0x10, 3, 3), + PIN_FIELD_BASE(44, 44, 1, 0x040, 0x10, 6, 3), + PIN_FIELD_BASE(45, 45, 1, 0x040, 0x10, 9, 3), +}; + static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = { [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8195_pin_mode_range), [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8195_pin_dir_range), @@ -773,6 +792,7 @@ static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = { [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8195_pin_pupd_range), [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8195_pin_r0_range), [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8195_pin_r1_range), + [PINCTRL_PIN_REG_DRV_ADV] = MTK_RANGE(mt8195_pin_drv_adv_range), }; static const char * const mt8195_pinctrl_register_base_names[] = { @@ -801,6 +821,8 @@ static const struct mtk_pin_soc mt8195_data = { .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_rev1, .drive_get = mtk_pinconf_drive_get_rev1, + .adv_drive_get = mtk_pinconf_adv_drive_get_raw, + .adv_drive_set = mtk_pinconf_adv_drive_set_raw, }; static const struct of_device_id mt8195_pinctrl_of_match[] = { diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index fcf7c3eeee4a..c068a2259741 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -1031,6 +1031,20 @@ int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, } EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get); +int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg) +{ + return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, arg); +} +EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set_raw); + +int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val) +{ + return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, val); +} +EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get_raw); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Sean Wang "); MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs"); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 65eac708a3b3..be35443d81f8 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -66,6 +66,7 @@ enum { PINCTRL_PIN_REG_DRV_EN, PINCTRL_PIN_REG_DRV_E0, PINCTRL_PIN_REG_DRV_E1, + PINCTRL_PIN_REG_DRV_ADV, PINCTRL_PIN_REG_MAX, }; @@ -316,6 +317,10 @@ int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 *val); +int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *val); bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n); #endif /* __PINCTRL_MTK_COMMON_V2_H */ -- cgit v1.2.3 From 56ab29ec6ff6c1441fda6ddcca0193be32d395b7 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Mon, 19 Apr 2021 17:34:49 +0800 Subject: pinctrl: mediatek: use spin lock in mtk_rmw Commit 42a46434e9b1 ("pinctrl: add lock in mtk_rmw function.") uses mutex lock in mtk_rmw. However the function is possible called from atomic context. For example call trace: mutex_lock+0x28/0x64 mtk_rmw+0x38/0x80 [snip] max98357a_daiops_trigger+0x8c/0x9c soc_pcm_trigger+0x5c/0x10c The max98357a_daiops_trigger() could run in either atomic or non-atomic context. As a result, dmesg shows some similar messages: "BUG: sleeping function called from invalid context at kernel/locking/mutex.c:254". Uses spin lock in mtk_rmw instead. Fixes: 42a46434e9b1 ("pinctrl: add lock in mtk_rmw function.") Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20210419093449.3125704-1-tzungbi@google.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-moore.c | 2 +- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 5 +++-- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 2 +- drivers/pinctrl/mediatek/pinctrl-paris.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h') diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c index f77921957f15..3a4a23c40a71 100644 --- a/drivers/pinctrl/mediatek/pinctrl-moore.c +++ b/drivers/pinctrl/mediatek/pinctrl-moore.c @@ -619,7 +619,7 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev, hw->nbase = hw->soc->nbase_names; - mutex_init(&hw->lock); + spin_lock_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), diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index c068a2259741..5b3b048725cc 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -57,15 +57,16 @@ static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg) void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set) { u32 val; + unsigned long flags; - mutex_lock(&pctl->lock); + spin_lock_irqsave(&pctl->lock, flags); val = mtk_r32(pctl, i, reg); val &= ~mask; val |= set; mtk_w32(pctl, i, reg, val); - mutex_unlock(&pctl->lock); + spin_unlock_irqrestore(&pctl->lock, flags); } 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 be35443d81f8..a6f1bdb2083b 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -253,7 +253,7 @@ struct mtk_pinctrl { struct mtk_pinctrl_group *groups; const char **grp_names; /* lock pin's register resource to avoid multiple threads issue*/ - struct mutex lock; + spinlock_t 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 48e823f6d293..85db2e4377f0 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -970,7 +970,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev, hw->nbase = hw->soc->nbase_names; - mutex_init(&hw->lock); + spin_lock_init(&hw->lock); err = mtk_pctrl_build_state(pdev); if (err) { -- cgit v1.2.3