summaryrefslogtreecommitdiff
path: root/sound/sh/aica.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-03-28 14:54:49 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-03-28 14:54:49 -0700
commit529b10c0091d6bda6d54fc72711a28f3ea01a72c (patch)
treee9608842a0fa3d984a0779ac26032efc1d39f316 /sound/sh/aica.c
parent6e7a2ffd209b59e98b6617d4b8be01af2391b580 (diff)
parent1506d96119eb9454d64f5ae80ab8d04c1594ac25 (diff)
Merge tag 'sound-6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A collection of device-specific small fixes: a series of fixes for TAS2781 HD-audio codec, ASoC SOF, Cirrus CS35L56 and a couple of legacy drivers" * tag 'sound-6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda/tas2781: remove useless dev_dbg from playback_hook ALSA: hda/tas2781: add debug statements to kcontrols ALSA: hda/tas2781: add locks to kcontrols ALSA: hda/tas2781: remove digital gain kcontrol ALSA: aoa: avoid false-positive format truncation warning ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs ALSA: hda: cs35l56: Set the init_done flag before component_add() ALSA: hda: cs35l56: Raise device name message log level ASoC: SOF: ipc4-topology: support NHLT device type ALSA: hda: intel-nhlt: add intel_nhlt_ssp_device_type() function
Diffstat (limited to 'sound/sh/aica.c')
-rw-r--r--sound/sh/aica.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 320ac792c7fe..3182c634464d 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -278,7 +278,8 @@ static void run_spu_dma(struct work_struct *work)
dreamcastcard->clicks++;
if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER))
dreamcastcard->clicks %= AICA_PERIOD_NUMBER;
- mod_timer(&dreamcastcard->timer, jiffies + 1);
+ if (snd_pcm_running(dreamcastcard->substream))
+ mod_timer(&dreamcastcard->timer, jiffies + 1);
}
}
@@ -290,6 +291,8 @@ static void aica_period_elapsed(struct timer_list *t)
/*timer function - so cannot sleep */
int play_period;
struct snd_pcm_runtime *runtime;
+ if (!snd_pcm_running(substream))
+ return;
runtime = substream->runtime;
dreamcastcard = substream->pcm->private_data;
/* Have we played out an additional period? */
@@ -350,12 +353,19 @@ static int snd_aicapcm_pcm_open(struct snd_pcm_substream
return 0;
}
+static int snd_aicapcm_pcm_sync_stop(struct snd_pcm_substream *substream)
+{
+ struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
+
+ del_timer_sync(&dreamcastcard->timer);
+ cancel_work_sync(&dreamcastcard->spu_dma_work);
+ return 0;
+}
+
static int snd_aicapcm_pcm_close(struct snd_pcm_substream
*substream)
{
struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
- flush_work(&(dreamcastcard->spu_dma_work));
- del_timer(&dreamcastcard->timer);
dreamcastcard->substream = NULL;
kfree(dreamcastcard->channel);
spu_disable();
@@ -401,6 +411,7 @@ static const struct snd_pcm_ops snd_aicapcm_playback_ops = {
.prepare = snd_aicapcm_pcm_prepare,
.trigger = snd_aicapcm_pcm_trigger,
.pointer = snd_aicapcm_pcm_pointer,
+ .sync_stop = snd_aicapcm_pcm_sync_stop,
};
/* TO DO: set up to handle more than one pcm instance */