Unverified Commit 97bd565f authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Mark Brown
Browse files

ASoC: Intel: avs: Abstract IRQ handling



Servicing IPCs on CNL platforms and onward differs from the existing
one. To make room for these, relocate SKL-based platforms specific code
into the skl.c file leaving only the genering irq_handler in the common
code.

Reviewed-by: default avatarAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://msgid.link/r/20240220115035.770402-6-cezary.rojewski@intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7576e2f4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -236,8 +236,8 @@ const struct avs_dsp_ops avs_apl_dsp_ops = {
	.power = avs_dsp_core_power,
	.reset = avs_dsp_core_reset,
	.stall = avs_dsp_core_stall,
	.irq_handler = avs_dsp_irq_handler,
	.irq_thread = avs_dsp_irq_thread,
	.irq_handler = avs_irq_handler,
	.irq_thread = avs_skl_irq_thread,
	.int_control = avs_dsp_interrupt_control,
	.load_basefw = avs_hda_load_basefw,
	.load_lib = avs_hda_load_library,
+4 −4
Original line number Diff line number Diff line
@@ -46,8 +46,8 @@ struct avs_dsp_ops {
	int (* const power)(struct avs_dev *, u32, bool);
	int (* const reset)(struct avs_dev *, u32, bool);
	int (* const stall)(struct avs_dev *, u32, bool);
	irqreturn_t (* const irq_handler)(int, void *);
	irqreturn_t (* const irq_thread)(int, void *);
	irqreturn_t (* const irq_handler)(struct avs_dev *);
	irqreturn_t (* const irq_thread)(struct avs_dev *);
	void (* const int_control)(struct avs_dev *, bool);
	int (* const load_basefw)(struct avs_dev *, struct firmware *);
	int (* const load_lib)(struct avs_dev *, struct firmware *, u32);
@@ -242,8 +242,7 @@ struct avs_ipc {
#define AVS_IPC_RET(ret) \
	(((ret) <= 0) ? (ret) : -AVS_EIPC)

irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id);
irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id);
irqreturn_t avs_irq_handler(struct avs_dev *adev);
void avs_dsp_process_response(struct avs_dev *adev, u64 header);
int avs_dsp_send_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request,
			     struct avs_ipc_msg *reply, int timeout, const char *name);
@@ -265,6 +264,7 @@ void avs_ipc_block(struct avs_ipc *ipc);
int avs_dsp_disable_d0ix(struct avs_dev *adev);
int avs_dsp_enable_d0ix(struct avs_dev *adev);

irqreturn_t avs_skl_irq_thread(struct avs_dev *adev);
int avs_skl_log_buffer_offset(struct avs_dev *adev, u32 core);

/* Firmware resources management */
+14 −0
Original line number Diff line number Diff line
@@ -321,6 +321,20 @@ static irqreturn_t hdac_bus_irq_thread(int irq, void *context)
	return IRQ_HANDLED;
}

static irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
{
	struct avs_dev *adev = dev_id;

	return avs_dsp_op(adev, irq_handler);
}

static irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id)
{
	struct avs_dev *adev = dev_id;

	return avs_dsp_op(adev, irq_thread);
}

static int avs_hdac_acquire_irq(struct avs_dev *adev)
{
	struct hdac_bus *bus = &adev->base.core;
+1 −29
Original line number Diff line number Diff line
@@ -301,9 +301,8 @@ void avs_dsp_process_response(struct avs_dev *adev, u64 header)
	complete(&ipc->busy_completion);
}

irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
irqreturn_t avs_irq_handler(struct avs_dev *adev)
{
	struct avs_dev *adev = dev_id;
	struct avs_ipc *ipc = adev->ipc;
	const struct avs_spec *const spec = adev->spec;
	u32 adspis, hipc_rsp, hipc_ack;
@@ -350,33 +349,6 @@ irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
	return ret;
}

irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id)
{
	struct avs_dev *adev = dev_id;
	union avs_reply_msg msg;
	u32 hipct, hipcte;

	hipct = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
	hipcte = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCTE);

	/* ensure DSP sent new response to process */
	if (!(hipct & SKL_ADSP_HIPCT_BUSY))
		return IRQ_NONE;

	msg.primary = hipct;
	msg.ext.val = hipcte;
	avs_dsp_process_response(adev, msg.val);

	/* tell DSP we accepted its message */
	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCT,
			      SKL_ADSP_HIPCT_BUSY, SKL_ADSP_HIPCT_BUSY);
	/* unmask busy interrupt */
	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
			      AVS_ADSP_HIPCCTL_BUSY, AVS_ADSP_HIPCCTL_BUSY);

	return IRQ_HANDLED;
}

static bool avs_ipc_is_busy(struct avs_ipc *ipc)
{
	struct avs_dev *adev = to_avs_dev(ipc->dev);
+27 −2
Original line number Diff line number Diff line
@@ -12,6 +12,31 @@
#include "avs.h"
#include "messages.h"

irqreturn_t avs_skl_irq_thread(struct avs_dev *adev)
{
	union avs_reply_msg msg;
	u32 hipct, hipcte;

	hipct = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
	hipcte = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCTE);

	/* Ensure DSP sent new response to process. */
	if (!(hipct & SKL_ADSP_HIPCT_BUSY))
		return IRQ_NONE;

	msg.primary = hipct;
	msg.ext.val = hipcte;
	avs_dsp_process_response(adev, msg.val);

	/* Tell DSP we accepted its message. */
	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCT, SKL_ADSP_HIPCT_BUSY, SKL_ADSP_HIPCT_BUSY);
	/* Unmask busy interrupt. */
	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, AVS_ADSP_HIPCCTL_BUSY,
			      AVS_ADSP_HIPCCTL_BUSY);

	return IRQ_HANDLED;
}

static int __maybe_unused
avs_skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
		    u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
@@ -103,8 +128,8 @@ const struct avs_dsp_ops avs_skl_dsp_ops = {
	.power = avs_dsp_core_power,
	.reset = avs_dsp_core_reset,
	.stall = avs_dsp_core_stall,
	.irq_handler = avs_dsp_irq_handler,
	.irq_thread = avs_dsp_irq_thread,
	.irq_handler = avs_irq_handler,
	.irq_thread = avs_skl_irq_thread,
	.int_control = avs_dsp_interrupt_control,
	.load_basefw = avs_cldma_load_basefw,
	.load_lib = avs_cldma_load_library,