diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-01-12 04:09:24 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-01-12 04:33:56 -0500 |
commit | 6acaed38a32e8571e92cfc832b971f9e4450c207 (patch) | |
tree | a3d4bff13d946744b38dce3f48ad530d23e74bf7 /sound/pci/hda/hda_intel.c | |
parent | 4b558991049c12689e5fd645222864b8a80730f1 (diff) |
ALSA: hda - Use own workqueue
snd-hda-intel driver used schedule_work() fot the delayed DMA pointer
updates, but this has several potential problems:
- it may block other eventsd works longer
- it may deadlock when probing fails and flush_scheduled_work() is
called during probe callback (as probe callback itself could be
invoked from eventd)
This patch adds an own workq for each driver instance to solve these
problems.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index f04de115ee11..11e791b965f6 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -996,10 +996,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
996 | spin_unlock(&chip->reg_lock); | 996 | spin_unlock(&chip->reg_lock); |
997 | snd_pcm_period_elapsed(azx_dev->substream); | 997 | snd_pcm_period_elapsed(azx_dev->substream); |
998 | spin_lock(&chip->reg_lock); | 998 | spin_lock(&chip->reg_lock); |
999 | } else { | 999 | } else if (chip->bus && chip->bus->workq) { |
1000 | /* bogus IRQ, process it later */ | 1000 | /* bogus IRQ, process it later */ |
1001 | azx_dev->irq_pending = 1; | 1001 | azx_dev->irq_pending = 1; |
1002 | schedule_work(&chip->irq_pending_work); | 1002 | queue_work(chip->bus->workq, |
1003 | &chip->irq_pending_work); | ||
1003 | } | 1004 | } |
1004 | } | 1005 | } |
1005 | } | 1006 | } |
@@ -1741,7 +1742,6 @@ static void azx_clear_irq_pending(struct azx *chip) | |||
1741 | for (i = 0; i < chip->num_streams; i++) | 1742 | for (i = 0; i < chip->num_streams; i++) |
1742 | chip->azx_dev[i].irq_pending = 0; | 1743 | chip->azx_dev[i].irq_pending = 0; |
1743 | spin_unlock_irq(&chip->reg_lock); | 1744 | spin_unlock_irq(&chip->reg_lock); |
1744 | flush_scheduled_work(); | ||
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | static struct snd_pcm_ops azx_pcm_ops = { | 1747 | static struct snd_pcm_ops azx_pcm_ops = { |