diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 3afd96d9c92575..d128839b24504b 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -39,10 +39,6 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context) u32 msg_ext; irqreturn_t ret = IRQ_NONE; - /* here we handle IPC interrupts only */ - if (!(sdev->irq_status & HDA_DSP_ADSPIS_IPC)) - return ret; - hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA); hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCCTL); hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR); diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index a938f568dbb1c3..73ead7070cdefd 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -145,10 +145,6 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) u32 msg; u32 msg_ext; - /* here we handle IPC interrupts only */ - if (!(sdev->irq_status & HDA_DSP_ADSPIS_IPC)) - return IRQ_NONE; - /* read IPC status */ hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE); @@ -234,19 +230,20 @@ irqreturn_t hda_dsp_ipc_irq_handler(int irq, void *context) { struct snd_sof_dev *sdev = context; int ret = IRQ_NONE; + u32 irq_status; spin_lock(&sdev->hw_lock); /* store status */ - sdev->irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_DSP_REG_ADSPIS); + irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIS); + dev_vdbg(sdev->dev, "irq handler: irq_status:0x%x\n", irq_status); /* invalid message ? */ - if (sdev->irq_status == 0xffffffff) + if (irq_status == 0xffffffff) goto out; /* IPC message ? */ - if (sdev->irq_status & HDA_DSP_ADSPIS_IPC) { + if (irq_status & HDA_DSP_ADSPIS_IPC) { /* disable IPC interrupt */ snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC, diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 6290b2df5e621d..f9c9a40b2ea991 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -433,6 +433,8 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, irqreturn_t hda_dsp_stream_interrupt(int irq, void *context) { struct hdac_bus *bus = context; + struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus); + u32 stream_mask; u32 status; if (!pm_runtime_active(bus->dev)) @@ -441,7 +443,10 @@ irqreturn_t hda_dsp_stream_interrupt(int irq, void *context) spin_lock(&bus->reg_lock); status = snd_hdac_chip_readl(bus, INTSTS); - if (status == 0 || status == 0xffffffff) { + stream_mask = GENMASK(sof_hda->stream_max - 1, 0) | AZX_INT_CTRL_EN; + + /* Not stream interrupt or register inaccessible, ignore it.*/ + if (!(status & stream_mask) || status == 0xffffffff) { spin_unlock(&bus->reg_lock); return IRQ_NONE; } @@ -500,6 +505,7 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) struct hdac_ext_stream *stream; struct hdac_stream *hstream; struct pci_dev *pci = to_pci_dev(sdev->dev); + struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus); int sd_offset; int i, num_playback, num_capture, num_total, ret; u32 gcap; @@ -657,6 +663,9 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) list_add_tail(&hstream->list, &bus->stream_list); } + /* store total stream count (playback + capture) from GCAP */ + sof_hda->stream_max = num_total; + return 0; } diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 7d78110c65a609..59ae6f8a1beaee 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -384,6 +384,9 @@ struct sof_intel_hda_dev { /* if position update IPC needed */ u32 no_ipc_position; + /* the maximum number of streams (playback + capture) supported */ + u32 stream_max; + int irq; /* DMIC device */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 35e78ffecce2fe..192b8828fd3d06 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -365,7 +365,6 @@ struct snd_sof_dev { struct snd_sof_mailbox host_box; /* Host initiated IPC */ struct snd_sof_mailbox stream_box; /* Stream position update */ struct snd_sof_ipc_msg *msg; - u64 irq_status; int ipc_irq; u32 next_comp_id; /* monotonic - reset during S3 */