in ti-msgmgr.c [706:825]
static int ti_msgmgr_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *of_id;
struct device_node *np;
struct resource *res;
const struct ti_msgmgr_desc *desc;
struct ti_msgmgr_inst *inst;
struct ti_queue_inst *qinst;
struct mbox_controller *mbox;
struct mbox_chan *chans;
int queue_count;
int i;
int ret = -EINVAL;
const struct ti_msgmgr_valid_queue_desc *queue_desc;
if (!dev->of_node) {
dev_err(dev, "no OF information\n");
return -EINVAL;
}
np = dev->of_node;
of_id = of_match_device(ti_msgmgr_of_match, dev);
if (!of_id) {
dev_err(dev, "OF data missing\n");
return -EINVAL;
}
desc = of_id->data;
inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
inst->dev = dev;
inst->desc = desc;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
desc->data_region_name);
inst->queue_proxy_region = devm_ioremap_resource(dev, res);
if (IS_ERR(inst->queue_proxy_region))
return PTR_ERR(inst->queue_proxy_region);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
desc->status_region_name);
inst->queue_state_debug_region = devm_ioremap_resource(dev, res);
if (IS_ERR(inst->queue_state_debug_region))
return PTR_ERR(inst->queue_state_debug_region);
if (desc->is_sproxy) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
desc->ctrl_region_name);
inst->queue_ctrl_region = devm_ioremap_resource(dev, res);
if (IS_ERR(inst->queue_ctrl_region))
return PTR_ERR(inst->queue_ctrl_region);
}
dev_dbg(dev, "proxy region=%p, queue_state=%p\n",
inst->queue_proxy_region, inst->queue_state_debug_region);
queue_count = desc->num_valid_queues;
if (!queue_count || queue_count > desc->queue_count) {
dev_crit(dev, "Invalid Number of queues %d. Max %d\n",
queue_count, desc->queue_count);
return -ERANGE;
}
inst->num_valid_queues = queue_count;
qinst = devm_kcalloc(dev, queue_count, sizeof(*qinst), GFP_KERNEL);
if (!qinst)
return -ENOMEM;
inst->qinsts = qinst;
chans = devm_kcalloc(dev, queue_count, sizeof(*chans), GFP_KERNEL);
if (!chans)
return -ENOMEM;
inst->chans = chans;
if (desc->is_sproxy) {
struct ti_msgmgr_valid_queue_desc sproxy_desc;
/* All proxies may be valid in Secure Proxy instance */
for (i = 0; i < queue_count; i++, qinst++, chans++) {
sproxy_desc.queue_id = 0;
sproxy_desc.proxy_id = i;
ret = ti_msgmgr_queue_setup(i, dev, np, inst,
desc, &sproxy_desc, qinst,
chans);
if (ret)
return ret;
}
} else {
/* Only Some proxies are valid in Message Manager */
for (i = 0, queue_desc = desc->valid_queues;
i < queue_count; i++, qinst++, chans++, queue_desc++) {
ret = ti_msgmgr_queue_setup(i, dev, np, inst,
desc, queue_desc, qinst,
chans);
if (ret)
return ret;
}
}
mbox = &inst->mbox;
mbox->dev = dev;
mbox->ops = &ti_msgmgr_chan_ops;
mbox->chans = inst->chans;
mbox->num_chans = inst->num_valid_queues;
mbox->txdone_irq = false;
mbox->txdone_poll = desc->tx_polled;
if (desc->tx_polled)
mbox->txpoll_period = desc->tx_poll_timeout_ms;
mbox->of_xlate = ti_msgmgr_of_xlate;
platform_set_drvdata(pdev, inst);
ret = devm_mbox_controller_register(dev, mbox);
if (ret)
dev_err(dev, "Failed to register mbox_controller(%d)\n", ret);
return ret;
}