ASoC: core: Update ALSA core  to issue restart in underrun.

When compressed and pcm session is started the buffer pull will
Be from the DSP, in mmap mode for the scenario Hardware pointer
Is same as application pointer implies application has not filled the
Buffer to be send to DSP, and platform driver has to break and restart
The de queue process when the application has sufficient buffers.

When hardware pointer is same as application pointer it is an under run
Scenario where the ALSA framework has to trigger the under run and in HAL
The session has to re-prepare and re-triggered. based on the stop
Threshold, but in our system the stop threshold is INT_MAX which
Indicates that under run is not triggered in practical cases.

We have a brodcast usecase in which the mentioned under run case
Is hit mulitple times, and every time re-prepare and re-trigger will be
Expensive

Update the ASoC core framework to restart de queue process stopped
By platform Driver when the under run is hit, based on the available
Buffer and render flag, so the System will recover from the hang state.

To restart de queue process the ASoC core will be calling the restart
Callback registered by platform driver and this callback will be running in
Atomic context.

Change-Id: Ic9ea05a0dc6246346e9913493232882e2f5447d1
Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index b11118f..4636247 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2477,6 +2477,7 @@
 	volatile struct snd_pcm_mmap_status *status;
 	volatile struct snd_pcm_mmap_control *control;
 	int err;
+	snd_pcm_uframes_t hw_avail;
 
 	memset(&sync_ptr, 0, sizeof(sync_ptr));
 	if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
@@ -2499,6 +2500,16 @@
 		control->avail_min = sync_ptr.c.control.avail_min;
 	else
 		sync_ptr.c.control.avail_min = control->avail_min;
+
+	if (runtime->render_flag & SNDRV_NON_DMA_MODE) {
+		hw_avail = snd_pcm_playback_hw_avail(runtime);
+		if ((hw_avail >= runtime->start_threshold)
+			&& (runtime->render_flag &
+				SNDRV_RENDER_STOPPED)) {
+			if (substream->ops->restart)
+				substream->ops->restart(substream);
+		}
+	}
 	sync_ptr.s.status.state = status->state;
 	sync_ptr.s.status.hw_ptr = status->hw_ptr;
 	sync_ptr.s.status.tstamp = status->tstamp;