Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sound/soc/sof/intel/hda-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,8 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
{
Comment thread
keyonjie marked this conversation as resolved.
Outdated
struct hdac_bus *bus = context;
struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
struct hdac_stream *s;
u32 status = snd_hdac_chip_readl(bus, INTSTS);
struct hdac_stream *s;
u32 sd_status;

/* check streams */
Expand All @@ -486,7 +486,7 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)

/* Inform ALSA only in case not do that with IPC */
if (sof_hda->no_ipc_position)
snd_pcm_period_elapsed(s->substream);
snd_sof_pcm_period_elapsed(s->substream);

}
}
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id)

Comment thread
keyonjie marked this conversation as resolved.
Outdated
/* only inform ALSA for period_wakeup mode */
if (!stream->substream->runtime->no_period_wakeup)
snd_pcm_period_elapsed(stream->substream);
snd_sof_pcm_period_elapsed(stream->substream);
}

/* DSP notifies host of an XRUN within FW */
Expand Down
48 changes: 48 additions & 0 deletions sound/soc/sof/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,48 @@ static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream
return ret;
}

/*
Comment thread
keyonjie marked this conversation as resolved.
Outdated
Comment thread
keyonjie marked this conversation as resolved.
Outdated
* sof pcm period elapse work
*/
static void sof_pcm_period_elapsed_work(struct work_struct *work)
{
struct snd_sof_pcm_stream *sps =
container_of(work, struct snd_sof_pcm_stream,
period_elapsed_work);

snd_pcm_period_elapsed(sps->substream);
}

/*
* sof pcm period elapse, this could be called at irq thread context.
*/
void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct snd_sof_pcm *spcm;

spcm = snd_sof_find_spcm_dai(sdev, rtd);
if (!spcm) {
dev_err(sdev->dev,
"error: period elapsed for unknown stream!\n");
return;
}

/*
* snd_pcm_period_elapsed() can be called in interrupt context
* before IRQ_HANDLED is returned. Inside snd_pcm_period_elapsed(),
* when the PCM is done draining or xrun happened, a STOP IPC will
* then be sent and this IPC will hit IPC timeout.
* To avoid sending IPC before the previous IPC is handled, we
* schedule delayed work here to call the snd_pcm_period_elapsed().
*/
schedule_work(&spcm->stream[substream->stream].period_elapsed_work);
}
EXPORT_SYMBOL(snd_sof_pcm_period_elapsed);

/* this may get called several times by oss emulation */
static int sof_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
Expand Down Expand Up @@ -169,6 +211,9 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream,
/* save pcm hw_params */
memcpy(&spcm->params[substream->stream], params, sizeof(*params));

INIT_WORK(&spcm->stream[substream->stream].period_elapsed_work,
sof_pcm_period_elapsed_work);

return ret;
}

Expand Down Expand Up @@ -203,6 +248,9 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
sizeof(stream), &reply, sizeof(reply));

snd_pcm_lib_free_pages(substream);

cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work);

return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions sound/soc/sof/sof-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ struct snd_sof_pcm_stream {
struct snd_dma_buffer page_table;
struct sof_ipc_stream_posn posn;
struct snd_pcm_substream *substream;
struct work_struct period_elapsed_work;
};

/* ALSA SOF PCM device */
Expand Down Expand Up @@ -495,6 +496,7 @@ struct snd_sof_pcm *snd_sof_find_spcm_comp(struct snd_sof_dev *sdev,
int *direction);
struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_sof_dev *sdev,
unsigned int pcm_id);
void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream);

/*
* Stream IPC
Expand Down