aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2014-02-28 18:41:28 -0500
committerTakashi Iwai <tiwai@suse.de>2014-03-01 05:23:16 -0500
commit7ca954a86b1f2e42af9299eb2ac142bcb5c9bd67 (patch)
treefd987d727b454bfe4ec6c90dbd05cceffe0a1e7e /sound/pci
parentf43923ff2c97c2ecad668c5133a36c2a9821b5df (diff)
ALSA: hda - Add position_check op
This op will be used by hda_intel to do the position check. Takashi wisely suggested adding this before moving the interrupt handler to common HDA code. Having this callback prevents the need to move the hda_intel specific delayed interrupt handling with the irq. Signed-off-by: Dylan Reid <dgreid@chromium.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_intel.c30
-rw-r--r--sound/pci/hda/hda_priv.h2
2 files changed, 23 insertions, 9 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 4f693eff531a..53e4b40a72af 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -416,6 +416,23 @@ static void azx_init_pci(struct azx *chip)
416 416
417static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); 417static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
418 418
419/* called from IRQ */
420static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
421{
422 int ok;
423
424 ok = azx_position_ok(chip, azx_dev);
425 if (ok == 1) {
426 azx_dev->irq_pending = 0;
427 return ok;
428 } else if (ok == 0 && chip->bus && chip->bus->workq) {
429 /* bogus IRQ, process it later */
430 azx_dev->irq_pending = 1;
431 queue_work(chip->bus->workq, &chip->irq_pending_work);
432 }
433 return 0;
434}
435
419/* 436/*
420 * interrupt handler 437 * interrupt handler
421 */ 438 */
@@ -425,7 +442,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
425 struct azx_dev *azx_dev; 442 struct azx_dev *azx_dev;
426 u32 status; 443 u32 status;
427 u8 sd_status; 444 u8 sd_status;
428 int i, ok; 445 int i;
429 446
430#ifdef CONFIG_PM_RUNTIME 447#ifdef CONFIG_PM_RUNTIME
431 if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME) 448 if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
@@ -455,17 +472,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
455 !(sd_status & SD_INT_COMPLETE)) 472 !(sd_status & SD_INT_COMPLETE))
456 continue; 473 continue;
457 /* check whether this IRQ is really acceptable */ 474 /* check whether this IRQ is really acceptable */
458 ok = azx_position_ok(chip, azx_dev); 475 if (!chip->ops->position_check ||
459 if (ok == 1) { 476 chip->ops->position_check(chip, azx_dev)) {
460 azx_dev->irq_pending = 0;
461 spin_unlock(&chip->reg_lock); 477 spin_unlock(&chip->reg_lock);
462 snd_pcm_period_elapsed(azx_dev->substream); 478 snd_pcm_period_elapsed(azx_dev->substream);
463 spin_lock(&chip->reg_lock); 479 spin_lock(&chip->reg_lock);
464 } else if (ok == 0 && chip->bus && chip->bus->workq) {
465 /* bogus IRQ, process it later */
466 azx_dev->irq_pending = 1;
467 queue_work(chip->bus->workq,
468 &chip->irq_pending_work);
469 } 480 }
470 } 481 }
471 } 482 }
@@ -1821,6 +1832,7 @@ static const struct hda_controller_ops pci_hda_ops = {
1821 .substream_alloc_pages = substream_alloc_pages, 1832 .substream_alloc_pages = substream_alloc_pages,
1822 .substream_free_pages = substream_free_pages, 1833 .substream_free_pages = substream_free_pages,
1823 .pcm_mmap_prepare = pcm_mmap_prepare, 1834 .pcm_mmap_prepare = pcm_mmap_prepare,
1835 .position_check = azx_position_check,
1824}; 1836};
1825 1837
1826static int azx_probe(struct pci_dev *pci, 1838static int azx_probe(struct pci_dev *pci,
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h
index edbe2ebac025..bf3cb33e0dd3 100644
--- a/sound/pci/hda/hda_priv.h
+++ b/sound/pci/hda/hda_priv.h
@@ -311,6 +311,8 @@ struct hda_controller_ops {
311 struct snd_pcm_substream *substream); 311 struct snd_pcm_substream *substream);
312 void (*pcm_mmap_prepare)(struct snd_pcm_substream *substream, 312 void (*pcm_mmap_prepare)(struct snd_pcm_substream *substream,
313 struct vm_area_struct *area); 313 struct vm_area_struct *area);
314 /* Check if current position is acceptable */
315 int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
314}; 316};
315 317
316struct azx_pcm { 318struct azx_pcm {