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:
Sugar Zhang
2020-11-03 15:13:56 +08:00
committed by Tao Huang
parent a7e892c783
commit fe27c204eb

View File

@@ -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;
}