Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2f95e6a authored by Bojun Pan's avatar Bojun Pan
Browse files

msm: gsi: cache last 20 gsi interrupt for interrupt storm debug



GSI interrupt storm can happen due to un-clocked gsi isr.
If we enable clock and assert, there is a chance the gsi isr will
be already handled.
To debug it further, the change is to cache last 20 gsi isr with
timestamp.

Change-Id: I30be03a20df9f11be7f5d8c06b049591305940bb
Signed-off-by: default avatarBojun Pan <bojunp@codeaurora.org>
parent 6adb2262
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,13 @@
#include "gsi_reg.h"
#include "gsi_reg.h"
#include "gsi_emulation.h"
#include "gsi_emulation.h"


#include <asm/arch_timer.h>
#include <linux/sched/clock.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/delay.h>

#define GSI_CMD_TIMEOUT (5*HZ)
#define GSI_CMD_TIMEOUT (5*HZ)
#define GSI_START_CMD_TIMEOUT_MS 1000
#define GSI_START_CMD_TIMEOUT_MS 1000
#define GSI_CMD_POLL_CNT 5
#define GSI_CMD_POLL_CNT 5
@@ -776,6 +783,7 @@ static void gsi_handle_irq(void)
	uint32_t type;
	uint32_t type;
	int ee = gsi_ctx->per.ee;
	int ee = gsi_ctx->per.ee;
	unsigned long cnt = 0;
	unsigned long cnt = 0;
	int index;


	while (1) {
	while (1) {
		if (!gsi_ctx->per.clk_status_cb())
		if (!gsi_ctx->per.clk_status_cb())
@@ -787,6 +795,15 @@ static void gsi_handle_irq(void)
			break;
			break;


		GSIDBG_LOW("type 0x%x\n", type);
		GSIDBG_LOW("type 0x%x\n", type);
		index = gsi_ctx->gsi_isr_cache_index;
		gsi_ctx->gsi_isr_cache[index].timestamp =
			sched_clock();
		gsi_ctx->gsi_isr_cache[index].qtimer =
			__arch_counter_get_cntvct();
		gsi_ctx->gsi_isr_cache[index].interrupt_type = type;
		gsi_ctx->gsi_isr_cache_index++;
		if (gsi_ctx->gsi_isr_cache_index == GSI_ISR_CACHE_MAX)
			gsi_ctx->gsi_isr_cache_index = 0;


		if (type & GSI_EE_n_CNTXT_TYPE_IRQ_CH_CTRL_BMSK)
		if (type & GSI_EE_n_CNTXT_TYPE_IRQ_CH_CTRL_BMSK)
			gsi_handle_ch_ctrl(ee);
			gsi_handle_ch_ctrl(ee);
@@ -1348,6 +1365,7 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl)
	}
	}


	*dev_hdl = (uintptr_t)gsi_ctx;
	*dev_hdl = (uintptr_t)gsi_ctx;
	gsi_ctx->gsi_isr_cache_index = 0;


	return GSI_STATUS_SUCCESS;
	return GSI_STATUS_SUCCESS;
}
}
+9 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@
#define GSI_CHAN_MAX      31
#define GSI_CHAN_MAX      31
#define GSI_EVT_RING_MAX  24
#define GSI_EVT_RING_MAX  24
#define GSI_NO_EVT_ERINDEX 31
#define GSI_NO_EVT_ERINDEX 31
#define GSI_ISR_CACHE_MAX 20


#define gsi_readl(c)	(readl_relaxed(c))
#define gsi_readl(c)	(readl_relaxed(c))
#define gsi_writel(v, c)	({ __iowmb(); writel_relaxed((v), (c)); })
#define gsi_writel(v, c)	({ __iowmb(); writel_relaxed((v), (c)); })
@@ -206,6 +207,12 @@ struct gsi_coal_chan_info {
	uint8_t evchid;
	uint8_t evchid;
};
};


struct gsi_log_ts {
	u64 timestamp;
	u64 qtimer;
	u32 interrupt_type;
};

struct gsi_ctx {
struct gsi_ctx {
	void __iomem *base;
	void __iomem *base;
	struct device *dev;
	struct device *dev;
@@ -237,6 +244,8 @@ struct gsi_ctx {
	u32 intcntrlr_mem_size;
	u32 intcntrlr_mem_size;
	irq_handler_t intcntrlr_gsi_isr;
	irq_handler_t intcntrlr_gsi_isr;
	irq_handler_t intcntrlr_client_isr;
	irq_handler_t intcntrlr_client_isr;
	struct gsi_log_ts gsi_isr_cache[GSI_ISR_CACHE_MAX];
	int gsi_isr_cache_index;


	atomic_t num_unclock_irq;
	atomic_t num_unclock_irq;
};
};