Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ca954a8 authored by Dylan Reid's avatar Dylan Reid Committed by Takashi Iwai
Browse files

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: default avatarDylan Reid <dgreid@chromium.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f43923ff
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -416,6 +416,23 @@ static void azx_init_pci(struct azx *chip)

static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);

/* called from IRQ */
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
{
	int ok;

	ok = azx_position_ok(chip, azx_dev);
	if (ok == 1) {
		azx_dev->irq_pending = 0;
		return ok;
	} else if (ok == 0 && chip->bus && chip->bus->workq) {
		/* bogus IRQ, process it later */
		azx_dev->irq_pending = 1;
		queue_work(chip->bus->workq, &chip->irq_pending_work);
	}
	return 0;
}

/*
 * interrupt handler
 */
@@ -425,7 +442,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
	struct azx_dev *azx_dev;
	u32 status;
	u8 sd_status;
	int i, ok;
	int i;

#ifdef CONFIG_PM_RUNTIME
	if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
@@ -455,17 +472,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
			    !(sd_status & SD_INT_COMPLETE))
				continue;
			/* check whether this IRQ is really acceptable */
			ok = azx_position_ok(chip, azx_dev);
			if (ok == 1) {
				azx_dev->irq_pending = 0;
			if (!chip->ops->position_check ||
			    chip->ops->position_check(chip, azx_dev)) {
				spin_unlock(&chip->reg_lock);
				snd_pcm_period_elapsed(azx_dev->substream);
				spin_lock(&chip->reg_lock);
			} else if (ok == 0 && chip->bus && chip->bus->workq) {
				/* bogus IRQ, process it later */
				azx_dev->irq_pending = 1;
				queue_work(chip->bus->workq,
					   &chip->irq_pending_work);
			}
		}
	}
@@ -1821,6 +1832,7 @@ static const struct hda_controller_ops pci_hda_ops = {
	.substream_alloc_pages = substream_alloc_pages,
	.substream_free_pages = substream_free_pages,
	.pcm_mmap_prepare = pcm_mmap_prepare,
	.position_check = azx_position_check,
};

static int azx_probe(struct pci_dev *pci,
+2 −0
Original line number Diff line number Diff line
@@ -311,6 +311,8 @@ struct hda_controller_ops {
				    struct snd_pcm_substream *substream);
	void (*pcm_mmap_prepare)(struct snd_pcm_substream *substream,
				 struct vm_area_struct *area);
	/* Check if current position is acceptable */
	int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
};

struct azx_pcm {