mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
audio: fix earc rx crash warning [1/1]
PD#SWPL-198561 PD#OTT-71761 Problem: Call trace: dump_backtrace+0x0/0x1e4 show_stack+0x24/0x34 dump_stack+0xbc/0x108 ___might_sleep+0x100/0x110 __might_sleep+0x54/0x98 mutex_lock+0x2c/0x68 snd_pcm_stop_xrun+0x2c/0xb0 earcrx_timer_func+0x94/0xac [snd_soc] call_timer_fn+0xc0/0x1ac expire_timers+0x74/0x164 root cause: in spin lock irqsave section code, there is mutex called. Solution: 1.keep nonatomic as true. 2.trigger xrun in work task, not in timer function. Verify: sc2 Change-Id: Idde8f3bce545c55f6a9bf20a6a5903feac290f9e Signed-off-by: jian zhou <jian.zhou@amlogic.com>
This commit is contained in:
committed by
gerrit autosubmit
parent
16f6ad368d
commit
72bbe1cebf
@@ -181,6 +181,7 @@ struct earc {
|
||||
/* do analog auto calibration when bootup */
|
||||
struct work_struct work;
|
||||
struct work_struct rx_dmac_int_work;
|
||||
struct work_struct rx_xrun_work;
|
||||
struct work_struct tx_hold_bus_work;
|
||||
struct work_struct earctx_reg_init_work;
|
||||
struct delayed_work tx_resume_work;
|
||||
@@ -1088,7 +1089,6 @@ static int earc_open(struct snd_soc_component *component, struct snd_pcm_substre
|
||||
dev_err(dev, "failed to claim toddr\n");
|
||||
goto err_ddr;
|
||||
}
|
||||
substream->pcm->nonatomic = 0;
|
||||
}
|
||||
|
||||
runtime->private_data = p_earc;
|
||||
@@ -3282,6 +3282,17 @@ static void rx_stable_work_func(struct work_struct *p_work)
|
||||
mute, p_earc->stream_stable);
|
||||
}
|
||||
|
||||
static void rx_xrun_work_func(struct work_struct *p_work)
|
||||
{
|
||||
struct earc *p_earc = container_of(p_work, struct earc, rx_xrun_work);
|
||||
|
||||
earcrx_pll_refresh(p_earc->rx_top_map, RST_BY_SELF, true, p_earc->chipinfo->rx_pll_new);
|
||||
|
||||
snd_pcm_stop_xrun(p_earc->substreams[SNDRV_PCM_STREAM_CAPTURE]);
|
||||
|
||||
dev_info(p_earc->dev, "reset pll and trigger xrun\n");
|
||||
}
|
||||
|
||||
static void earcrx_timer_func(struct timer_list *t)
|
||||
{
|
||||
struct earc *p_earc = from_timer(p_earc, t, rx_detect_point_timer);
|
||||
@@ -3297,14 +3308,8 @@ static void earcrx_timer_func(struct timer_list *t)
|
||||
goto exit;
|
||||
|
||||
cur_addr = aml_toddr_get_position(p_earc->tddr);
|
||||
if (p_earc->rx_position_addr == cur_addr) {
|
||||
earcrx_pll_refresh(p_earc->rx_top_map, RST_BY_SELF, true,
|
||||
p_earc->chipinfo->rx_pll_new);
|
||||
|
||||
snd_pcm_stop_xrun(p_earc->substreams[SNDRV_PCM_STREAM_CAPTURE]);
|
||||
|
||||
dev_info(p_earc->dev, "reset pll and trigger xrun\n");
|
||||
}
|
||||
if (p_earc->rx_position_addr == cur_addr)
|
||||
schedule_work(&p_earc->rx_xrun_work);
|
||||
|
||||
p_earc->rx_position_addr = cur_addr;
|
||||
|
||||
@@ -3536,6 +3541,7 @@ static int earc_platform_probe(struct platform_device *pdev)
|
||||
if (earcrx_cmdc_get_attended_type(p_earc->rx_cmdc_map) == ATNDTYP_EARC)
|
||||
earcrx_cmdc_set_cds(p_earc->rx_cmdc_map, p_earc->rx_cds_data);
|
||||
INIT_WORK(&p_earc->rx_dmac_int_work, valid_auto_work_func);
|
||||
INIT_WORK(&p_earc->rx_xrun_work, rx_xrun_work_func);
|
||||
INIT_DELAYED_WORK(&p_earc->rx_stable_work, rx_stable_work_func);
|
||||
INIT_DELAYED_WORK(&p_earc->rx_pll_detect_work, rx_pll_detect_work_func);
|
||||
INIT_DELAYED_WORK(&p_earc->hdmitx_5v_work, hdmitx_5v_work_func);
|
||||
|
||||
Reference in New Issue
Block a user