pinctrl: mediatek: use spin lock in mtk_rmw
Commit42a46434e9
("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:
parent
ea9d2ed465
commit
56ab29ec6f
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue