Merge "gsi: Add clock voting before IO access in debugfs"
diff --git a/drivers/platform/msm/gsi/gsi.h b/drivers/platform/msm/gsi/gsi.h
index 9432f00..1e65d0a 100644
--- a/drivers/platform/msm/gsi/gsi.h
+++ b/drivers/platform/msm/gsi/gsi.h
@@ -338,6 +338,8 @@
 	void *user_data;
 	int (*clk_status_cb)(void);
 	void (*enable_clk_bug_on)(void);
+	void (*vote_clk_cb)(void);
+	void (*unvote_clk_cb)(void);
 	bool skip_ieob_mask_wa;
 	bool tx_poll;
 };
diff --git a/drivers/platform/msm/gsi/gsi_dbg.c b/drivers/platform/msm/gsi/gsi_dbg.c
index 7282197..ba811cd 100644
--- a/drivers/platform/msm/gsi/gsi_dbg.c
+++ b/drivers/platform/msm/gsi/gsi_dbg.c
@@ -71,6 +71,8 @@
 		return -EINVAL;
 	}
 
+	gsi_ctx->per.vote_clk_cb();
+
 	val = gsihal_read_reg_nk(GSI_EE_n_EV_CH_k_CNTXT_0,
 		gsi_ctx->per.ee, arg1);
 	TERR("EV%2d CTX0  0x%x\n", arg1, val);
@@ -120,6 +122,8 @@
 		gsi_ctx->per.ee, arg1);
 	TERR("EV%2d SCR1  0x%x\n", arg1, val);
 
+	gsi_ctx->per.unvote_clk_cb();
+
 	if (arg2) {
 		ctx = &gsi_ctx->evtr[arg1];
 
@@ -183,7 +187,9 @@
 		return -EINVAL;
 	}
 
+	gsi_ctx->per.vote_clk_cb();
 	gsi_dump_ch_info(arg1);
+	gsi_ctx->per.unvote_clk_cb();
 
 	if (arg2) {
 		ctx = &gsi_ctx->chan[arg1];
@@ -354,7 +360,6 @@
 	unsigned long missing;
 	char *sptr, *token;
 
-
 	if (count >= sizeof(dbg_buff))
 		goto error;
 
@@ -432,6 +437,8 @@
 	int ee = gsi_ctx->per.ee;
 	uint16_t used_hw;
 
+	gsi_ctx->per.vote_clk_cb();
+
 	rp_hw = gsihal_read_reg_nk(GSI_EE_n_GSI_CH_k_CNTXT_4,
 		ee, ctx->props.ch_id);
 	rp_hw |= ((uint64_t)gsihal_read_reg_nk(GSI_EE_n_GSI_CH_k_CNTXT_5,
@@ -442,6 +449,8 @@
 	wp_hw |= ((uint64_t)gsihal_read_reg_nk(GSI_EE_n_GSI_CH_k_CNTXT_7,
 		ee, ctx->props.ch_id)) << 32;
 
+	gsi_ctx->per.unvote_clk_cb();
+
 	start_hw = gsi_find_idx_from_addr(&ctx->ring, rp_hw);
 	end_hw = gsi_find_idx_from_addr(&ctx->ring, wp_hw);
 
@@ -590,7 +599,7 @@
 	char __user *buf, size_t count, loff_t *ppos)
 {
 	struct gsi_hw_profiling_data stats;
-	int nbytes, cnt = 0;
+	int ret, nbytes, cnt = 0;
 	u64 totalCycles = 0, util = 0;
 
 	if (gsi_ctx->per.ver < GSI_VER_2_9) {
@@ -599,7 +608,12 @@
 		cnt += nbytes;
 		goto done;
 	}
-	if (!gsi_get_hw_profiling_stats(&stats)) {
+
+	gsi_ctx->per.vote_clk_cb();
+	ret = gsi_get_hw_profiling_stats(&stats);
+	gsi_ctx->per.unvote_clk_cb();
+
+	if (!ret) {
 		totalCycles = stats.mcs_busy_cnt + stats.mcs_idle_cnt +
 			stats.bp_and_pending_cnt;
 		if (totalCycles != 0)
@@ -636,7 +650,7 @@
 	char __user *buf, size_t count, loff_t *ppos)
 {
 	struct gsi_fw_version ver;
-	int nbytes, cnt = 0;
+	int ret, nbytes, cnt = 0;
 
 	if (gsi_ctx->per.ver < GSI_VER_2_9) {
 		nbytes = scnprintf(dbg_buff, GSI_MAX_MSG_LEN,
@@ -644,7 +658,12 @@
 		cnt += nbytes;
 		goto done;
 	}
-	if (!gsi_get_fw_version(&ver)) {
+
+	gsi_ctx->per.vote_clk_cb();
+	ret = gsi_get_fw_version(&ver);
+	gsi_ctx->per.unvote_clk_cb();
+
+	if (!ret) {
 		nbytes = scnprintf(dbg_buff, GSI_MAX_MSG_LEN,
 			"hw=%d\nflavor=%d\nfw=%d\n",
 			ver.hw,
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index e9d85b4..7295f6e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -6924,17 +6924,16 @@
 }
 
 /**
- * ipa3_inc_client_enable_clks() - Increase active clients counter, and
+ * ipa3_inc_client_enable_clks_no_log() - Increase active clients counter, and
  * enable ipa clocks if necessary
  *
  * Return codes:
  * None
  */
-void ipa3_inc_client_enable_clks(struct ipa_active_client_logging_info *id)
+static void ipa3_inc_client_enable_clks_no_log(void)
 {
 	int ret;
 
-	ipa3_active_clients_log_inc(id, false);
 	ret = atomic_inc_not_zero(&ipa3_ctx->ipa3_active_clients.cnt);
 	if (ret) {
 		IPADBG_LOW("active clients = %d\n",
@@ -6960,6 +6959,19 @@
 		atomic_read(&ipa3_ctx->ipa3_active_clients.cnt));
 	mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
 }
+
+/**
+ * ipa3_inc_client_enable_clks() - Increase active clients counter and
+ * enable ipa clocks if necessary, log the caller
+ *
+ * Return codes:
+ * None
+ */
+void ipa3_inc_client_enable_clks(struct ipa_active_client_logging_info *id)
+{
+	ipa3_active_clients_log_inc(id, false);
+	ipa3_inc_client_enable_clks_no_log();
+}
 EXPORT_SYMBOL(ipa3_inc_client_enable_clks);
 
 static void ipa3_handle_gsi_differ_irq(void)
@@ -7064,7 +7076,23 @@
 }
 
 /**
- * ipa3_dec_client_disable_clks() - Decrease active clients counter
+ * ipa3_dec_client_disable_clks_no_log() - Decrease active clients counter
+ *
+ * In case that there are no active clients this function also starts
+ * TAG process. When TAG progress ends ipa clocks will be gated.
+ * start_tag_process_again flag is set during this function to signal TAG
+ * process to start again as there was another client that may send data to ipa
+ *
+ * Return codes:
+ * None
+ */
+static void ipa3_dec_client_disable_clks_no_log(void)
+{
+	__ipa3_dec_client_disable_clks();
+}
+
+/**
+ * ipa3_dec_client_disable_clks() - Decrease active clients counter and log caller
  *
  * In case that there are no active clients this function also starts
  * TAG process. When TAG progress ends ipa clocks will be gated.
@@ -8102,6 +8130,8 @@
 	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;
+	gsi_props.vote_clk_cb = ipa3_inc_client_enable_clks_no_log;
+	gsi_props.unvote_clk_cb = ipa3_dec_client_disable_clks_no_log;
 
 	if (ipa3_ctx->ipa_config_is_mhi) {
 		gsi_props.mhi_er_id_limits_valid = true;