mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
ASoC: rockchip: i2s-tdm: Fix BUG scheduling while atomic
BUG: scheduling while atomic: mediaserver/664/0x00000002
CPU: 0 PID: 664 Comm: mediaserver Tainted: G O 4.19.111 #36
Hardware name: Generic DT based system
[<b010f408>] (unwind_backtrace) from [<b010b96c>] (show_stack+0x10/0x14)
[<b010b96c>] (show_stack) from [<b08157c4>] (dump_stack+0x90/0xa4)
[<b08157c4>] (dump_stack) from [<b0147bb0>] (_schedule_bug+0x64/0x84)
[<b0147bb0>] (_schedule_bug) from [<b082b93c>] (_schedule+0x4a4/0x580)
[<b082b93c>] (_schedule) from [<b082ba68>] (schedule+0x50/0xb4)
[<b082ba68>] (schedule) from [<b082bebc>] (schedule_preempt_disabled+0x28/0x40)
[<b082bebc>] (schedule_preempt_disabled) from [<b082d020>] (_mutex_lock.constprop.7+0x534/0x5c0)
[<b082d020>] (_mutex_lock.constprop.7) from [<b03e5ba4>] (clk_prepare_lock+0x50/0xf8)
[<b03e5ba4>] (clk_prepare_lock) from [<b03e9204>] (clk_set_rate+0x18/0x88)
[<b03e9204>] (clk_set_rate) from [<b068a0dc>] (rockchip_i2s_tdm_hw_params+0x88/0x798)
[<b068a0dc>] (rockchip_i2s_tdm_hw_params) from [<b0680758>] (soc_dai_hw_params+0x58/0xa4)
[<b0680758>] (soc_dai_hw_params) from [<b0680914>] (soc_pcm_hw_params+0x170/0x55c)
[<b0680914>] (soc_pcm_hw_params) from [<b0668540>] (snd_pcm_hw_params+0x124/0x3ac)
[<b0668540>] (snd_pcm_hw_params) from [<b0669ae4>] (snd_pcm_ioctl+0x764/0xcbc)
[<b0669ae4>] (snd_pcm_ioctl) from [<b0220c38>] (do_vfs_ioctl+0xac/0x798)
[<b0220c38>] (do_vfs_ioctl) from [<b0221358>] (ksys_ioctl+0x34/0x58)
[<b0221358>] (ksys_ioctl) from [<b0101000>] (ret_fast_syscall+0x0/0x4c)
Exception stack(0xdbda3fa8 to 0xdbda3ff0)
Fixes: 61559b25ba ("ASoC: rockchip: i2s: Set clk rate when master mode")
Change-Id: I266efee0f9e5d99ff6d358c4f12e7b9dc7eb6bf8
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
This commit is contained in:
@@ -751,13 +751,7 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct clk *mclk;
|
||||
int ret = 0;
|
||||
unsigned int val = 0;
|
||||
unsigned int mclk_rate, bclk_rate, div_bclk, div_lrck;
|
||||
|
||||
if (i2s_tdm->clk_trcm) {
|
||||
spin_lock(&i2s_tdm->lock);
|
||||
if (atomic_read(&i2s_tdm->refcount))
|
||||
rockchip_i2s_tdm_xfer_pause(substream, i2s_tdm);
|
||||
}
|
||||
unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
|
||||
|
||||
if (i2s_tdm->is_master_mode) {
|
||||
if (i2s_tdm->mclk_calibrate)
|
||||
@@ -776,28 +770,6 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
}
|
||||
div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
|
||||
div_lrck = bclk_rate / params_rate(params);
|
||||
if (i2s_tdm->clk_trcm) {
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
|
||||
I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK,
|
||||
I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
|
||||
I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK,
|
||||
I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck));
|
||||
} else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
|
||||
I2S_CLKDIV_TXM_MASK,
|
||||
I2S_CLKDIV_TXM(div_bclk));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
|
||||
I2S_CKR_TSD_MASK,
|
||||
I2S_CKR_TSD(div_lrck));
|
||||
} else {
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
|
||||
I2S_CLKDIV_RXM_MASK,
|
||||
I2S_CLKDIV_RXM(div_bclk));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
|
||||
I2S_CKR_RSD_MASK,
|
||||
I2S_CKR_RSD(div_lrck));
|
||||
}
|
||||
}
|
||||
|
||||
switch (params_format(params)) {
|
||||
@@ -841,6 +813,33 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (i2s_tdm->clk_trcm) {
|
||||
spin_lock(&i2s_tdm->lock);
|
||||
if (atomic_read(&i2s_tdm->refcount))
|
||||
rockchip_i2s_tdm_xfer_pause(substream, i2s_tdm);
|
||||
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
|
||||
I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK,
|
||||
I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
|
||||
I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK,
|
||||
I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck));
|
||||
} else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
|
||||
I2S_CLKDIV_TXM_MASK,
|
||||
I2S_CLKDIV_TXM(div_bclk));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
|
||||
I2S_CKR_TSD_MASK,
|
||||
I2S_CKR_TSD(div_lrck));
|
||||
} else {
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
|
||||
I2S_CLKDIV_RXM_MASK,
|
||||
I2S_CLKDIV_RXM(div_bclk));
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
|
||||
I2S_CKR_RSD_MASK,
|
||||
I2S_CKR_RSD(div_lrck));
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
|
||||
I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
|
||||
@@ -864,8 +863,6 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (i2s_tdm->clk_trcm)
|
||||
spin_unlock(&i2s_tdm->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user