From 6bba2d8d58418e729310ad931afc9c5aff57bdd0 Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Thu, 7 Jun 2018 09:09:33 +0800 Subject: [PATCH 1/2] ASoC: SOF: enable msi for sof hda audio This patch tries to enable msi for sof hda audio driver. If it fails (not supported by HW/BIOS), it will use the legacy interrupt mode. Signed-off-by: Libin Yang --- sound/soc/sof/intel/hda.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7949d6d5508025..61a6b767ecea27 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -446,20 +446,34 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN); - dev_dbg(sdev->dev, "using PCI IRQ %d\n", pci->irq); + /* + * register our IRQ + * let's try to enable msi firstly + * if it fails, use legacy interrupt mode + * TODO: support interrupt mode selection with kernel parameter + * support msi multiple vectors + */ + ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI); + if (ret < 0) { + dev_info(sdev->dev, "use legacy interrupt mode\n"); + sdev->hda->irq = pci->irq; + sdev->ipc_irq = pci->irq; + } else { + dev_info(sdev->dev, "use msi interrupt mode\n"); + sdev->hda->irq = pci_irq_vector(pci, 0); + sdev->ipc_irq = pci_irq_vector(pci, 0); + } - /* register our IRQ */ - ret = request_threaded_irq(pci->irq, hda_dsp_stream_interrupt, + dev_dbg(sdev->dev, "using HDA IRQ %d\n", sdev->hda->irq); + ret = request_threaded_irq(sdev->hda->irq, hda_dsp_stream_interrupt, hda_dsp_stream_threaded_handler, - IRQF_SHARED, "AudioHDA", sdev); + IRQF_SHARED, "AudioHDA", sdev); if (ret < 0) { dev_err(sdev->dev, "error: failed to register HDA IRQ %d\n", - sdev->ipc_irq); + sdev->hda->irq); goto stream_err; } - sdev->hda->irq = pci->irq; - sdev->ipc_irq = pci->irq; dev_dbg(sdev->dev, "using IPC IRQ %d\n", sdev->ipc_irq); ret = request_threaded_irq(sdev->ipc_irq, hda_dsp_ipc_irq_handler, chip->ops->irq_thread, IRQF_SHARED, @@ -494,8 +508,9 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) return 0; irq_err: - free_irq(pci->irq, sdev); + free_irq(sdev->hda->irq, sdev); stream_err: + pci_free_irq_vectors(pci); hda_dsp_stream_free(sdev); err: /* disable DSP */ @@ -506,6 +521,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) int hda_dsp_remove(struct snd_sof_dev *sdev) { + struct pci_dev *pci = sdev->pci; const struct sof_intel_dsp_desc *chip = sdev->hda->desc; /* disable DSP IRQ */ @@ -526,6 +542,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) free_irq(sdev->ipc_irq, sdev); free_irq(sdev->pci->irq, sdev); + pci_free_irq_vectors(pci); hda_dsp_stream_free(sdev); return 0; From fcc6ac239412ce1bdf5fa4f69d9e35080a51126d Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Tue, 3 Jul 2018 14:32:34 +0800 Subject: [PATCH 2/2] ASoC: SOF: enable msi for sof byt audio This patch tries to enable msi for sof byt pci audio driver. If it fails (not supported by HW/BIOS), it will use the legacy interrupt mode. Signed-off-by: Libin Yang --- sound/soc/sof/intel/byt.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 49ec019b45d0fa..0ab59620b34f21 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -689,8 +689,22 @@ static int byt_pci_probe(struct snd_sof_dev *sdev) dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); irq: - /* register our IRQ */ - sdev->ipc_irq = pci->irq; + /* + * register our IRQ + * let's try to enable msi firstly + * if it fails, use legacy interrupt mode + * TODO: support interrupt mode selection with kernel parameter + * support msi multiple vectors + */ + ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI); + if (ret < 0) { + dev_info(sdev->dev, "use legacy interrupt mode\n"); + sdev->ipc_irq = pci->irq; + } else { + dev_info(sdev->dev, "use msi interrupt mode\n"); + sdev->ipc_irq = pci_irq_vector(pci, 0); + } + dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); ret = request_threaded_irq(sdev->ipc_irq, byt_irq_handler, byt_irq_thread, 0, "AudioDSP", sdev); @@ -714,6 +728,7 @@ static int byt_pci_probe(struct snd_sof_dev *sdev) irq_err: iounmap(sdev->bar[BYT_IMR_BAR]); + pci_free_irq_vectors(pci); imr_err: iounmap(sdev->bar[BYT_DSP_BAR]); return ret; @@ -738,7 +753,10 @@ static int byt_acpi_remove(struct snd_sof_dev *sdev) static int byt_pci_remove(struct snd_sof_dev *sdev) { + struct pci_dev *pci = sdev->pci; + free_irq(sdev->ipc_irq, sdev); + pci_free_irq_vectors(pci); return 0; }