pinctrl: mediatek: use spin lock in mtk_rmw

Commit 42a46434e9 ("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: 42a46434e9 ("pinctrl: add lock in mtk_rmw function.")
Signed-off-by: Tzung-Bi Shih <tzungbi@google.com>
Link: https://lore.kernel.org/r/20210419093449.3125704-1-tzungbi@google.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Tzung-Bi Shih 2021-04-19 17:34:49 +08:00 committed by Linus Walleij
parent ea9d2ed465
commit 56ab29ec6f
4 changed files with 6 additions and 5 deletions

View File

@ -619,7 +619,7 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev,
hw->nbase = hw->soc->nbase_names; 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 */ /* Copy from internal struct mtk_pin_desc to register to the core */
pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins), pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),

View File

@ -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) void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
{ {
u32 val; u32 val;
unsigned long flags;
mutex_lock(&pctl->lock); spin_lock_irqsave(&pctl->lock, flags);
val = mtk_r32(pctl, i, reg); val = mtk_r32(pctl, i, reg);
val &= ~mask; val &= ~mask;
val |= set; val |= set;
mtk_w32(pctl, i, reg, val); 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, static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,

View File

@ -253,7 +253,7 @@ struct mtk_pinctrl {
struct mtk_pinctrl_group *groups; struct mtk_pinctrl_group *groups;
const char **grp_names; const char **grp_names;
/* lock pin's register resource to avoid multiple threads issue*/ /* 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); void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);

View File

@ -970,7 +970,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
hw->nbase = hw->soc->nbase_names; hw->nbase = hw->soc->nbase_names;
mutex_init(&hw->lock); spin_lock_init(&hw->lock);
err = mtk_pctrl_build_state(pdev); err = mtk_pctrl_build_state(pdev);
if (err) { if (err) {