Kaynağa Gözat

msm: ipa: add log for uC HOLB monitor

Log last 20 HOLB event for each client.
Add debugfs support to print those events.

Change-Id: I4aa1bd6c86b22efbbaa3a5be2030667d3e4c8bec
Bojun Pan 4 yıl önce
ebeveyn
işleme
acde797a5f

+ 59 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c

@@ -489,6 +489,61 @@ static ssize_t ipa3_read_keep_awake(struct file *file, char __user *ubuf,
 	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
 }
 
+static ssize_t ipa3_read_holb_events(struct file *file, char __user *ubuf, size_t count,
+		loff_t *ppos)
+{
+	int nbytes = 0;
+	int client_idx;
+	int event_id;
+	bool enable;
+	int num_clients = ipa3_ctx->uc_ctx.holb_monitor.num_holb_clients;
+	struct ipa_uc_holb_client_info *holb_client;
+	uint32_t qtimer_lsb;
+	uint32_t qtimer_msb;
+
+	mutex_lock(&ipa3_ctx->lock);
+	for (client_idx = 0; client_idx < num_clients; client_idx++) {
+		holb_client =
+			&(ipa3_ctx->uc_ctx.holb_monitor.client[client_idx]);
+		event_id = holb_client->current_idx;
+		nbytes += scnprintf(
+			dbg_buff + nbytes,
+			IPA_MAX_MSG_LEN - nbytes,
+			"========================\n");
+		nbytes += scnprintf(
+			dbg_buff + nbytes,
+			IPA_MAX_MSG_LEN - nbytes,
+			"GSI ch %d cur event_id %d ",
+			holb_client->gsi_chan_hdl, holb_client->current_idx);
+		nbytes += scnprintf(
+			dbg_buff + nbytes,
+			IPA_MAX_MSG_LEN - nbytes,
+			"enable cnt %d disable cnt %d\n",
+			holb_client->enable_cnt, holb_client->disable_cnt);
+		for (event_id = 0; event_id < IPA_HOLB_EVENT_LOG_MAX; event_id++) {
+			enable = holb_client->events[event_id].enable;
+			qtimer_lsb = holb_client->events[event_id].qTimerLSB;
+			qtimer_msb = holb_client->events[event_id].qTimerMSB;
+			nbytes += scnprintf(
+				dbg_buff + nbytes,
+				IPA_MAX_MSG_LEN - nbytes,
+				"event id %d: %s QTimer %u %u\n",
+				event_id,
+				enable ? "Bad Periph event" : "Recovered Periph event",
+				qtimer_lsb,
+				qtimer_msb);
+		}
+		nbytes += scnprintf(
+			dbg_buff + nbytes,
+			IPA_MAX_MSG_LEN - nbytes,
+			"===============\n");
+	}
+
+	mutex_unlock(&ipa3_ctx->lock);
+
+	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
+}
+
 static ssize_t ipa3_read_hdr(struct file *file, char __user *ubuf, size_t count,
 		loff_t *ppos)
 {
@@ -2693,6 +2748,10 @@ static const struct ipa3_debugfs_file debugfs_files[] = {
 		"holb_monitor_client_add_del", IPA_WRITE_ONLY_MODE, NULL, {
 			.write = ipa3_write_holb_monitor_client_add_del,
 		}
+	}, {
+		"holb_events", IPA_READ_ONLY_MODE, NULL, {
+			.read = ipa3_read_holb_events,
+		}
 	}, {
 		"hdr", IPA_READ_ONLY_MODE, NULL, {
 			.read = ipa3_read_hdr,

+ 10 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_uc.c

@@ -561,6 +561,11 @@ static void ipa3_event_ring_hdlr(void)
 				e_h->Value.holb_notify_param.ipaProdGsiChid,
 				e_h->Value.holb_notify_param.qTimerMSB,
 				e_h->Value.holb_notify_param.qTimerLSB);
+			ipa3_uc_holb_event_log(
+				e_h->Value.holb_notify_param.ipaProdGsiChid,
+				true,
+				e_h->Value.holb_notify_param.qTimerLSB,
+				e_h->Value.holb_notify_param.qTimerMSB);
 		} else if (((struct eventElement_t *) rp_va)->Opcode
 				== IPA_HOLB_PERIPHERAL_RECOVERED_EVENT) {
 			e_h = ((struct eventElement_t *) rp_va);
@@ -568,6 +573,11 @@ static void ipa3_event_ring_hdlr(void)
 				e_h->Value.holb_notify_param.ipaProdGsiChid,
 				e_h->Value.holb_notify_param.qTimerMSB,
 				e_h->Value.holb_notify_param.qTimerLSB);
+			ipa3_uc_holb_event_log(
+				e_h->Value.holb_notify_param.ipaProdGsiChid,
+				false,
+				e_h->Value.holb_notify_param.qTimerLSB,
+				e_h->Value.holb_notify_param.qTimerMSB);
 		}
 		ipa3_ctx->uc_ctx.ering_rp_local += offset;
 		ipa3_ctx->uc_ctx.ering_rp_local %=

+ 32 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_uc_holb_monitor.c

@@ -197,7 +197,6 @@ int ipa3_uc_client_del_holb_monitor(uint16_t gsi_ch, uint8_t ee)
 		ret = ipa3_uc_del_holb_monitor(holb_client->gsi_chan_hdl,
 		ee);
 		holb_client->state = IPA_HOLB_DEL;
-
 	} else if (!ipa3_uc_holb_enabled_check() &&
 			holb_client->state == IPA_HOLB_ADD_PENDING) {
 		IPADBG("GSI chan %d going from ADD_PENDING to DEL state\n",
@@ -208,3 +207,35 @@ int ipa3_uc_client_del_holb_monitor(uint16_t gsi_ch, uint8_t ee)
 	mutex_unlock(&ipa3_ctx->uc_ctx.holb_monitor.uc_holb_lock);
 	return ret;
 }
+
+void ipa3_uc_holb_event_log(uint16_t gsi_ch, bool enable,
+	uint32_t qtimer_lsb, uint32_t qtimer_msb)
+{
+	struct ipa_uc_holb_client_info *holb_client;
+	int client_idx;
+	int current_idx;
+
+	if (!ipa3_ctx->uc_ctx.ipa_use_uc_holb_monitor)
+		return;
+
+	mutex_lock(&ipa3_ctx->uc_ctx.holb_monitor.uc_holb_lock);
+	client_idx = ipa3_get_holb_client_idx_by_ch(gsi_ch);
+	if (client_idx == -EINVAL) {
+		IPAERR("Invalid client with GSI chan %d\n", gsi_ch);
+		mutex_unlock(&ipa3_ctx->uc_ctx.holb_monitor.uc_holb_lock);
+		return;
+	}
+	holb_client = &(ipa3_ctx->uc_ctx.holb_monitor.client[client_idx]);
+	current_idx = holb_client->current_idx;
+
+	holb_client->events[current_idx].enable = enable;
+	holb_client->events[current_idx].qTimerLSB = qtimer_lsb;
+	holb_client->events[current_idx].qTimerMSB = qtimer_msb;
+	if (enable)
+		holb_client->enable_cnt++;
+	else
+		holb_client->disable_cnt++;
+	holb_client->current_idx = (holb_client->current_idx + 1) %
+		IPA_HOLB_EVENT_LOG_MAX;
+	mutex_unlock(&ipa3_ctx->uc_ctx.holb_monitor.uc_holb_lock);
+}

+ 33 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_uc_holb_monitor.h

@@ -12,6 +12,7 @@
 #define NOTIFY_AP_ON_HOLB 0x2
 #define HOLB_MONITOR_MASK (HOLB_OP | NOTIFY_AP_ON_HOLB)
 #define IPA_HOLB_CLIENT_MAX 30
+#define IPA_HOLB_EVENT_LOG_MAX 20
 #define IPA_CLIENT_IS_HOLB_CONS(x) \
 (x == IPA_CLIENT_USB_CONS || x == IPA_CLIENT_WLAN2_CONS || \
 x == IPA_CLIENT_WLAN1_CONS || x == IPA_CLIENT_WIGIG1_CONS || \
@@ -32,6 +33,18 @@ enum ipa_holb_client_state {
 	IPA_HOLB_DEL  = 3,
 };
 
+/**
+ * struct ipa_holb_events - HOLB enable/disable events log
+ * @qTimerLSB: LSB for event qtimer
+ * @qTimerMSB: MSB for event qtimer
+ * @enable: Even for enable/disable
+ */
+struct ipa_holb_events {
+	uint32_t qTimerLSB;
+	uint32_t qTimerMSB;
+	bool enable;
+};
+
 /**
  * struct  ipa_uc_holb_client_info - Client info needed for HOLB callback
  * @gsi_chan_hdl: GSI Channel of the client to be monitored
@@ -40,7 +53,10 @@ enum ipa_holb_client_state {
  * @ee: EE that the chid belongs to
  * @debugfs_param: If debugfs is used to set the client parameters
  * @state: Client state
- *
+ * @events: HOLB enable/disable events log
+ * @current_idx: index of current event
+ * @enable_cnt: accumulate count for enable
+ * @disable_cnt: accumulate count for disable
  */
 struct ipa_uc_holb_client_info {
 	uint16_t gsi_chan_hdl;
@@ -49,6 +65,10 @@ struct ipa_uc_holb_client_info {
 	uint8_t ee;
 	bool debugfs_param;
 	enum ipa_holb_client_state state;
+	struct ipa_holb_events events[IPA_HOLB_EVENT_LOG_MAX];
+	uint32_t current_idx;
+	uint32_t enable_cnt;
+	uint32_t disable_cnt;
 };
 
 /**
@@ -106,4 +126,16 @@ int ipa3_uc_client_del_holb_monitor(uint16_t gsi_ch, uint8_t ee);
  *
  */
 void ipa3_set_holb_client_by_ch(struct ipa_uc_holb_client_info client);
+
+/**
+ * ipa3_uc_holb_event_log() - Log HOLB event for specific gsi
+ * channel
+ * @gsi_ch: Client values to be set for the gsi channel
+ * @enable: event is for enable/disable
+ * @qtimer_lsb: msb for event qtimer
+ * @qtimer_msb: lsb for event qtimer
+ */
+void ipa3_uc_holb_event_log(uint16_t gsi_ch, bool enable,
+	uint32_t qtimer_lsb, uint32_t qtimer_msb);
+
 #endif /* IPA_UC_HOLB_MONITOR_H */