summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkylar Chang <chiaweic@codeaurora.org>2016-11-18 10:56:51 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-11-20 21:20:56 -0800
commitcd1c2b1674383a4c800aaefbc332e716e3deec65 (patch)
treedf26e534b96ab32a8caec4fe88e771a27e001b95
parenta0b8ac8a2886e16a4faf1b34decf434f5521419d (diff)
msm: gsi: fix interrupt processing
Fix GSI interrupt processing to make sure interrupt are not missed. In order to achieve that interrupt should first be cleared before processed. Change-Id: I42978f2230e95456e4b4e932365e5b2c83445f56 CRs-Fixed: 1090894 Acked-by: Ady Abraham <adya@qti.qualcomm.com> Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
-rw-r--r--drivers/platform/msm/gsi/gsi.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index df3901093006..a617c9e8e11f 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -105,6 +105,8 @@ static void gsi_handle_ch_ctrl(int ee)
ch = gsi_readl(gsi_ctx->base +
GSI_EE_n_CNTXT_SRC_GSI_CH_IRQ_OFFS(ee));
+ gsi_writel(ch, gsi_ctx->base +
+ GSI_EE_n_CNTXT_SRC_GSI_CH_IRQ_CLR_OFFS(ee));
GSIDBG("ch %x\n", ch);
for (i = 0; i < 32; i++) {
if ((1 << i) & ch) {
@@ -124,9 +126,6 @@ static void gsi_handle_ch_ctrl(int ee)
gsi_ctx->ch_dbg[i].cmd_completed++;
}
}
-
- gsi_writel(ch, gsi_ctx->base +
- GSI_EE_n_CNTXT_SRC_GSI_CH_IRQ_CLR_OFFS(ee));
}
static void gsi_handle_ev_ctrl(int ee)
@@ -138,6 +137,8 @@ static void gsi_handle_ev_ctrl(int ee)
ch = gsi_readl(gsi_ctx->base +
GSI_EE_n_CNTXT_SRC_EV_CH_IRQ_OFFS(ee));
+ gsi_writel(ch, gsi_ctx->base +
+ GSI_EE_n_CNTXT_SRC_EV_CH_IRQ_CLR_OFFS(ee));
GSIDBG("ev %x\n", ch);
for (i = 0; i < 32; i++) {
if ((1 << i) & ch) {
@@ -156,9 +157,6 @@ static void gsi_handle_ev_ctrl(int ee)
complete(&ctx->compl);
}
}
-
- gsi_writel(ch, gsi_ctx->base +
- GSI_EE_n_CNTXT_SRC_EV_CH_IRQ_CLR_OFFS(ee));
}
static void gsi_handle_glob_err(uint32_t err)
@@ -439,9 +437,16 @@ static void gsi_handle_ieob(int ee)
GSI_EE_n_CNTXT_SRC_IEOB_IRQ_OFFS(ee));
msk = gsi_readl(gsi_ctx->base +
GSI_EE_n_CNTXT_SRC_IEOB_IRQ_MSK_OFFS(ee));
+ gsi_writel(ch & msk, gsi_ctx->base +
+ GSI_EE_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(ee));
for (i = 0; i < 32; i++) {
if ((1 << i) & ch & msk) {
+ if (i >= gsi_ctx->max_ev || i >= GSI_EVT_RING_MAX) {
+ GSIERR("invalid event %d\n", i);
+ break;
+ }
+
ctx = &gsi_ctx->evtr[i];
BUG_ON(ctx->props.intf != GSI_EVT_CHTYPE_GPI_EV);
spin_lock_irqsave(&ctx->ring.slock, flags);
@@ -467,9 +472,6 @@ check_again:
spin_unlock_irqrestore(&ctx->ring.slock, flags);
}
}
-
- gsi_writel(ch & msk, gsi_ctx->base +
- GSI_EE_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(ee));
}
static void gsi_handle_inter_ee_ch_ctrl(int ee)
@@ -479,15 +481,14 @@ static void gsi_handle_inter_ee_ch_ctrl(int ee)
ch = gsi_readl(gsi_ctx->base +
GSI_INTER_EE_n_SRC_GSI_CH_IRQ_OFFS(ee));
+ gsi_writel(ch, gsi_ctx->base +
+ GSI_INTER_EE_n_SRC_GSI_CH_IRQ_CLR_OFFS(ee));
for (i = 0; i < 32; i++) {
if ((1 << i) & ch) {
/* not currently expected */
GSIERR("ch %u was inter-EE changed\n", i);
}
}
-
- gsi_writel(ch, gsi_ctx->base +
- GSI_INTER_EE_n_SRC_GSI_CH_IRQ_CLR_OFFS(ee));
}
static void gsi_handle_inter_ee_ev_ctrl(int ee)
@@ -497,15 +498,14 @@ static void gsi_handle_inter_ee_ev_ctrl(int ee)
ch = gsi_readl(gsi_ctx->base +
GSI_INTER_EE_n_SRC_EV_CH_IRQ_OFFS(ee));
+ gsi_writel(ch, gsi_ctx->base +
+ GSI_INTER_EE_n_SRC_EV_CH_IRQ_CLR_OFFS(ee));
for (i = 0; i < 32; i++) {
if ((1 << i) & ch) {
/* not currently expected */
GSIERR("evt %u was inter-EE changed\n", i);
}
}
-
- gsi_writel(ch, gsi_ctx->base +
- GSI_INTER_EE_n_SRC_EV_CH_IRQ_CLR_OFFS(ee));
}
static void gsi_handle_general(int ee)