summaryrefslogtreecommitdiff
path: root/sound/soc/sof/intel/hda.h
diff options
context:
space:
mode:
authorBard Liao <yung-chuan.liao@linux.intel.com>2019-12-05 00:28:59 +0300
committerMark Brown <broonie@kernel.org>2019-12-09 21:35:56 +0300
commit7c11af9fcdc425b80f140a218d4fef9f17734bfc (patch)
tree1316234b4cecc9854d2493dd02840a035e400534 /sound/soc/sof/intel/hda.h
parent253f584a0699d12a90bde9d524d499a921cc7827 (diff)
downloadlinux-7c11af9fcdc425b80f140a218d4fef9f17734bfc.tar.xz
ASoC: SOF: Intel: hda: solve MSI issues by merging ipc and stream irq handlers
The existing code uses two handlers for a shared edge-based MSI interrupts. In corner cases, interrupts are lost, leading to IPC timeouts. Those timeouts do not appear in legacy mode. This patch merges the two handlers and threads into a single one, and simplifies the mask/unmask operations by using a single top-level mask (Global Interrupt Enable). The handler only checks for interrupt sources using the Global Interrupt Status (GIS) field, and all the actual work happens in the thread. This also enables us to remove the use of spin locks. Stream events are prioritized over IPC ones. This patch was tested with HDaudio and SoundWire platforms, and all known IPC timeout issues are solved in MSI mode. The SoundWire-specific patches will be provided in follow-up patches, where the SoundWire interrupts are handled in the same thread as IPC and stream interrupts. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20191204212859.13239-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/intel/hda.h')
-rw-r--r--sound/soc/sof/intel/hda.h11
1 files changed, 6 insertions, 5 deletions
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 18d7e72bf9b7..63df888dddb6 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -43,11 +43,14 @@
/* SOF_HDA_GCTL register bist */
#define SOF_HDA_GCTL_RESET BIT(0)
-/* SOF_HDA_INCTL and SOF_HDA_INTSTS regs */
+/* SOF_HDA_INCTL regs */
#define SOF_HDA_INT_GLOBAL_EN BIT(31)
#define SOF_HDA_INT_CTRL_EN BIT(30)
#define SOF_HDA_INT_ALL_STREAM 0xff
+/* SOF_HDA_INTSTS regs */
+#define SOF_HDA_INTSTS_GIS BIT(31)
+
#define SOF_HDA_MAX_CAPS 10
#define SOF_HDA_CAP_ID_OFF 16
#define SOF_HDA_CAP_ID_MASK GENMASK(SOF_HDA_CAP_ID_OFF + 11,\
@@ -406,8 +409,6 @@ struct sof_intel_hda_dev {
/* the maximum number of streams (playback + capture) supported */
u32 stream_max;
- int irq;
-
/* PM related */
bool l1_support_changed;/* during suspend, is L1SEN changed or not */
@@ -511,11 +512,12 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
struct snd_pcm_hw_params *params);
int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
struct hdac_ext_stream *stream, int cmd);
-irqreturn_t hda_dsp_stream_interrupt(int irq, void *context);
irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context);
int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
struct snd_dma_buffer *dmab,
struct hdac_stream *stream);
+bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev);
+bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev);
struct hdac_ext_stream *
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction);
@@ -540,7 +542,6 @@ void hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev);
int hda_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev);
int hda_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id);
-irqreturn_t hda_dsp_ipc_irq_handler(int irq, void *context);
irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context);
int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir);