aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers/pcsp/pcsp.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-08-11 04:18:39 -0400
committerTakashi Iwai <tiwai@suse.de>2008-10-20 08:47:15 -0400
commit96c7d478efad594e483ee8a826395b1342404885 (patch)
tree8ecb6f20f1f72f9d406b3c949d9b811347dcbb3e /sound/drivers/pcsp/pcsp.c
parent76a4d10e522bfc238ddf70f35272088d420d2dcf (diff)
ALSA: pcsp - Fix locking messes in snd-pcsp
snd-pcsp driver takes chip->substream_lock together with PCM substream lock. These are even mixed up with hrtimer's lock, resulting in messy lock depencies. Right now, snd-pcsp driver resolves the deadlock by using HRTIMER_CB_SOFTIRQ. However, this isn't nice for a really fast path like bit-flipping. This patch introduces a tasklet for PCM period handling so that the hrtimer callback can be handled fast. This also reduce the use of chip->substream_lock to avoid deadlocks. It's still used in pointer callback, but even this could be removed with a proper barrier. Another good solution is to introduce async trigger callback. But, this will involve with a major rewrite of the PCM core code, so I take first this easy fix. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/drivers/pcsp/pcsp.c')
-rw-r--r--sound/drivers/pcsp/pcsp.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 1899cf0685bc..87219bf0a35e 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
96 return -EINVAL; 96 return -EINVAL;
97 97
98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
99 pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ; 99 pcsp_chip.timer.cb_mode = HRTIMER_CB_IRQSAFE;
100 pcsp_chip.timer.function = pcsp_do_timer; 100 pcsp_chip.timer.function = pcsp_do_timer;
101 101
102 card = snd_card_new(index, id, THIS_MODULE, 0); 102 card = snd_card_new(index, id, THIS_MODULE, 0);
@@ -188,10 +188,8 @@ static int __devexit pcsp_remove(struct platform_device *dev)
188 188
189static void pcsp_stop_beep(struct snd_pcsp *chip) 189static void pcsp_stop_beep(struct snd_pcsp *chip)
190{ 190{
191 spin_lock_irq(&chip->substream_lock); 191 pcsp_sync_stop(chip);
192 if (!chip->playback_substream) 192 pcspkr_stop_sound();
193 pcspkr_stop_sound();
194 spin_unlock_irq(&chip->substream_lock);
195} 193}
196 194
197#ifdef CONFIG_PM 195#ifdef CONFIG_PM