aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/meson/axg-fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/meson/axg-fifo.c')
-rw-r--r--sound/soc/meson/axg-fifo.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c
index bebee0ca8e388..59abe0b3c59fb 100644
--- a/sound/soc/meson/axg-fifo.c
+++ b/sound/soc/meson/axg-fifo.c
@@ -23,7 +23,7 @@
* These differences are handled in the respective DAI drivers
*/
-static struct snd_pcm_hardware axg_fifo_hw = {
+static const struct snd_pcm_hardware axg_fifo_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -46,7 +46,7 @@ static struct snd_pcm_hardware axg_fifo_hw = {
static struct snd_soc_dai *axg_fifo_dai(struct snd_pcm_substream *ss)
{
- struct snd_soc_pcm_runtime *rtd = ss->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss);
return snd_soc_rtd_to_cpu(rtd, 0);
}
@@ -204,18 +204,26 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id)
unsigned int status;
regmap_read(fifo->map, FIFO_STATUS1, &status);
-
status = FIELD_GET(STATUS1_INT_STS, status);
+ axg_fifo_ack_irq(fifo, status);
+
+ /* Use the thread to call period elapsed on nonatomic links */
if (status & FIFO_INT_COUNT_REPEAT)
- snd_pcm_period_elapsed(ss);
- else
- dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
- status);
+ return IRQ_WAKE_THREAD;
- /* Ack irqs */
- axg_fifo_ack_irq(fifo, status);
+ dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
+ status);
+
+ return IRQ_NONE;
+}
+
+static irqreturn_t axg_fifo_pcm_irq_block_thread(int irq, void *dev_id)
+{
+ struct snd_pcm_substream *ss = dev_id;
+
+ snd_pcm_period_elapsed(ss);
- return IRQ_RETVAL(status);
+ return IRQ_HANDLED;
}
int axg_fifo_pcm_open(struct snd_soc_component *component,
@@ -243,8 +251,9 @@ int axg_fifo_pcm_open(struct snd_soc_component *component,
if (ret)
return ret;
- ret = request_irq(fifo->irq, axg_fifo_pcm_irq_block, 0,
- dev_name(dev), ss);
+ ret = request_threaded_irq(fifo->irq, axg_fifo_pcm_irq_block,
+ axg_fifo_pcm_irq_block_thread,
+ IRQF_ONESHOT, dev_name(dev), ss);
if (ret)
return ret;