
This is a PCI-only feature, but adding a callback for it in the chip structure breaks the PCI dependency in the RIRB code allowing the logic there to be re-used by the platform HDA driver.
Signed-off-by: Dylan Reid dgreid@chromium.org --- sound/pci/hda/hda_intel.c | 22 +++++++++++++++++----- sound/pci/hda/hda_priv.h | 3 +++ 2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 33dc7ae..eaf8c78 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -543,11 +543,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, dev_warn(chip->card->dev, "No response from codec, disabling MSI: last cmd=0x%08x\n", chip->last_cmd[addr]); - free_irq(chip->irq, chip); - chip->irq = -1; - pci_disable_msi(chip->pci); - chip->msi = 0; - if (azx_acquire_irq(chip, 1) < 0) { + if (chip->disable_msi_reset_irq(chip) < 0) { bus->rirb_error = 1; return -1; } @@ -1924,6 +1920,21 @@ static void azx_probe_work(struct work_struct *work) azx_probe_continue(container_of(work, struct azx, probe_work)); }
+static int disable_msi_reset_irq(struct azx *chip) +{ + int err; + + free_irq(chip->irq, chip); + chip->irq = -1; + pci_disable_msi(chip->pci); + chip->msi = 0; + err = azx_acquire_irq(chip, 1); + if (err < 0) + return err; + + return 0; +} + /* * constructor */ @@ -1961,6 +1972,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, chip->driver_type = driver_caps & 0xff; check_msi(chip); chip->dev_index = dev; + chip->disable_msi_reset_irq = disable_msi_reset_irq; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); INIT_LIST_HEAD(&chip->pcm_list); INIT_LIST_HEAD(&chip->list); diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h index 0e3bba1..f1fa6f4 100644 --- a/sound/pci/hda/hda_priv.h +++ b/sound/pci/hda/hda_priv.h @@ -378,6 +378,9 @@ struct azx { /* for debugging */ unsigned int last_cmd[AZX_MAX_CODECS];
+ /* disable msi if supported, PCI only */ + int (*disable_msi_reset_irq)(struct azx *); + /* for pending irqs */ struct work_struct irq_pending_work;