diff options
author | Dylan Reid <dgreid@chromium.org> | 2014-02-28 18:41:28 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-03-01 05:23:16 -0500 |
commit | 7ca954a86b1f2e42af9299eb2ac142bcb5c9bd67 (patch) | |
tree | fd987d727b454bfe4ec6c90dbd05cceffe0a1e7e /sound/pci | |
parent | f43923ff2c97c2ecad668c5133a36c2a9821b5df (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.c | 30 | ||||
-rw-r--r-- | sound/pci/hda/hda_priv.h | 2 |
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 | ||
417 | static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); | 417 | static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); |
418 | 418 | ||
419 | /* called from IRQ */ | ||
420 | static 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 | ||
1826 | static int azx_probe(struct pci_dev *pci, | 1838 | static 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 | ||
316 | struct azx_pcm { | 318 | struct azx_pcm { |