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>
diff --git a/sound/soc/amlogic/auge/earc.c b/sound/soc/amlogic/auge/earc.c
index d0d8d86..084f28f 100644
--- a/sound/soc/amlogic/auge/earc.c
+++ b/sound/soc/amlogic/auge/earc.c
@@ -181,6 +181,7 @@
 	/* 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 @@
 			dev_err(dev, "failed to claim toddr\n");
 			goto err_ddr;
 		}
-		substream->pcm->nonatomic = 0;
 	}
 
 	runtime->private_data = p_earc;
@@ -3282,6 +3282,17 @@
 		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 @@
 		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 @@
 		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);