in arm_mhuv2.c [870:927]
static int mhuv2_allocate_channels(struct mhuv2 *mhu)
{
struct mbox_controller *mbox = &mhu->mbox;
struct mhuv2_mbox_chan_priv *priv;
struct device *dev = mbox->dev;
struct mbox_chan *chans;
int protocol, windows = 0, next_window = 0, i, j, k;
chans = devm_kcalloc(dev, mbox->num_chans, sizeof(*chans), GFP_KERNEL);
if (!chans)
return -ENOMEM;
mbox->chans = chans;
for (i = 0; i < mhu->length; i += 2) {
next_window += windows;
protocol = mhu->protocols[i];
windows = mhu->protocols[i + 1];
if (protocol == DATA_TRANSFER) {
priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->ch_wn_idx = next_window;
priv->ops = &mhuv2_data_transfer_ops;
priv->windows = windows;
chans++->con_priv = priv;
continue;
}
for (j = 0; j < windows; j++) {
for (k = 0; k < MHUV2_STAT_BITS; k++) {
priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->ch_wn_idx = next_window + j;
priv->ops = &mhuv2_doorbell_ops;
priv->doorbell = k;
chans++->con_priv = priv;
}
/*
* Permanently enable interrupt as we can't
* control it per doorbell.
*/
if (mhu->frame == SENDER_FRAME && mhu->minor)
writel_relaxed(0x1, &mhu->send->ch_wn[priv->ch_wn_idx].int_en);
}
}
/* Make sure we have initialized all channels */
BUG_ON(chans - mbox->chans != mbox->num_chans);
return 0;
}