Prechádzať zdrojové kódy

msm: ipa4: debug patch gsi interrupt issue

Debug patch for GSI interrupt issue.

Change-Id: I705cd893233e1afcaeed6fedb424830e39621114
Acked-by: Ashok Vuyyuru <[email protected]>
Signed-off-by: Bojun Pan <[email protected]>
Bojun Pan 5 rokov pred
rodič
commit
a619aab34b

+ 9 - 2
drivers/platform/msm/gsi/gsi.c

@@ -20,6 +20,7 @@
 #define GSI_CMD_POLL_CNT 5
 #define GSI_STOP_CMD_TIMEOUT_MS 200
 #define GSI_MAX_CH_LOW_WEIGHT 15
+#define GSI_IRQ_STORM_THR 5
 
 #define GSI_STOP_CMD_POLL_CNT 4
 #define GSI_STOP_IN_PROC_CMD_POLL_CNT 2
@@ -805,9 +806,15 @@ static irqreturn_t gsi_isr(int irq, void *ctxt)
 			gsi_handle_irq();
 			gsi_ctx->per.rel_clk_cb(gsi_ctx->per.user_data);
 		}
+	} else if (!gsi_ctx->per.clk_status_cb()) {
+	/* we only want to capture the gsi isr storm here */
+		if (atomic_read(&gsi_ctx->num_unclock_irq) ==
+			GSI_IRQ_STORM_THR)
+			gsi_ctx->per.enable_clk_bug_on();
+		atomic_inc(&gsi_ctx->num_unclock_irq);
+		return IRQ_HANDLED;
 	} else {
-		if (!gsi_ctx->per.clk_status_cb())
-			return IRQ_HANDLED;
+		atomic_set(&gsi_ctx->num_unclock_irq, 0);
 		gsi_handle_irq();
 	}
 	return IRQ_HANDLED;

+ 2 - 0
drivers/platform/msm/gsi/gsi.h

@@ -235,6 +235,8 @@ struct gsi_ctx {
 	u32 intcntrlr_mem_size;
 	irq_handler_t intcntrlr_gsi_isr;
 	irq_handler_t intcntrlr_client_isr;
+
+	atomic_t num_unclock_irq;
 };
 
 enum gsi_re_type {

+ 24 - 0
drivers/platform/msm/ipa/ipa_v3/ipa.c

@@ -122,6 +122,10 @@ static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work);
 static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_wq_work,
 	ipa_dec_clients_disable_clks_on_wq);
 
+static void ipa_inc_clients_enable_clks_on_wq(struct work_struct *work);
+static DECLARE_WORK(ipa_inc_clients_enable_clks_on_wq_work,
+	ipa_inc_clients_enable_clks_on_wq);
+
 static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg);
 static int ipa3_ioctl_add_rt_rule_ext_v2(unsigned long arg);
 static int ipa3_ioctl_add_rt_rule_after_v2(unsigned long arg);
@@ -4839,6 +4843,12 @@ void ipa3_disable_clks(void)
 
 	IPADBG("disabling IPA clocks and bus voting\n");
 
+	/*
+	 * We see a NoC error on GSI on this flag sequence.
+	 * Need to set this flag first before clock off.
+	 */
+	atomic_set(&ipa3_ctx->ipa_clk_vote, 0);
+
 	ipa3_ctx->ctrl->ipa3_disable_clks();
 
 	ipa_pm_set_clock_index(0);
@@ -5024,6 +5034,12 @@ void ipa3_inc_client_enable_clks(struct ipa_active_client_logging_info *id)
 	mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
 }
 
+static void ipa3_handle_gsi_differ_irq(void)
+{
+	queue_work(ipa3_ctx->power_mgmt_wq,
+		&ipa_inc_clients_enable_clks_on_wq_work);
+}
+
 /**
  * ipa3_active_clks_status() - update the current msm bus clock vote
  * status
@@ -5140,6 +5156,13 @@ static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work)
 	__ipa3_dec_client_disable_clks();
 }
 
+static void ipa_inc_clients_enable_clks_on_wq(struct work_struct *work)
+{
+	ipa3_enable_clks();
+	IPAERR("unexpected clk access, clock on IPA to save reg");
+	ipa_assert();
+}
+
 /**
  * ipa3_dec_client_disable_clks_no_block() - Decrease active clients counter
  * if possible without blocking. If this is the last client then the desrease
@@ -5960,6 +5983,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
 	gsi_props.req_clk_cb = NULL;
 	gsi_props.rel_clk_cb = NULL;
 	gsi_props.clk_status_cb = ipa3_active_clks_status;
+	gsi_props.enable_clk_bug_on = ipa3_handle_gsi_differ_irq;
 
 	if (ipa3_ctx->ipa_config_is_mhi) {
 		gsi_props.mhi_er_id_limits_valid = true;