in mhi/core/init.c [639:720]
static int parse_ev_cfg(struct mhi_controller *mhi_cntrl,
const struct mhi_controller_config *config)
{
struct mhi_event *mhi_event;
const struct mhi_event_config *event_cfg;
struct device *dev = mhi_cntrl->cntrl_dev;
int i, num;
num = config->num_events;
mhi_cntrl->total_ev_rings = num;
mhi_cntrl->mhi_event = kcalloc(num, sizeof(*mhi_cntrl->mhi_event),
GFP_KERNEL);
if (!mhi_cntrl->mhi_event)
return -ENOMEM;
/* Populate event ring */
mhi_event = mhi_cntrl->mhi_event;
for (i = 0; i < num; i++) {
event_cfg = &config->event_cfg[i];
mhi_event->er_index = i;
mhi_event->ring.elements = event_cfg->num_elements;
mhi_event->intmod = event_cfg->irq_moderation_ms;
mhi_event->irq = event_cfg->irq;
if (event_cfg->channel != U32_MAX) {
/* This event ring has a dedicated channel */
mhi_event->chan = event_cfg->channel;
if (mhi_event->chan >= mhi_cntrl->max_chan) {
dev_err(dev,
"Event Ring channel not available\n");
goto error_ev_cfg;
}
mhi_event->mhi_chan =
&mhi_cntrl->mhi_chan[mhi_event->chan];
}
/* Priority is fixed to 1 for now */
mhi_event->priority = 1;
mhi_event->db_cfg.brstmode = event_cfg->mode;
if (MHI_INVALID_BRSTMODE(mhi_event->db_cfg.brstmode))
goto error_ev_cfg;
if (mhi_event->db_cfg.brstmode == MHI_DB_BRST_ENABLE)
mhi_event->db_cfg.process_db = mhi_db_brstmode;
else
mhi_event->db_cfg.process_db = mhi_db_brstmode_disable;
mhi_event->data_type = event_cfg->data_type;
switch (mhi_event->data_type) {
case MHI_ER_DATA:
mhi_event->process_event = mhi_process_data_event_ring;
break;
case MHI_ER_CTRL:
mhi_event->process_event = mhi_process_ctrl_ev_ring;
break;
default:
dev_err(dev, "Event Ring type not supported\n");
goto error_ev_cfg;
}
mhi_event->hw_ring = event_cfg->hardware_event;
if (mhi_event->hw_ring)
mhi_cntrl->hw_ev_rings++;
else
mhi_cntrl->sw_ev_rings++;
mhi_event->cl_manage = event_cfg->client_managed;
mhi_event->offload_ev = event_cfg->offload_channel;
mhi_event++;
}
return 0;
error_ev_cfg:
kfree(mhi_cntrl->mhi_event);
return -EINVAL;
}