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
This commit is contained in:
Bojun Pan 2020-05-04 19:04:45 -07:00 • committed by Gerrit - the friendly Code Review server
commit acde797a5f
4 changed files with 134 additions and 2 deletions

View file

@ -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,

View file

@ -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 %=

View file

@ -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);
}

View file

@ -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 */