in rockchip-mailbox.c [164:247]
static int rockchip_mbox_probe(struct platform_device *pdev)
{
struct rockchip_mbox *mb;
const struct of_device_id *match;
const struct rockchip_mbox_data *drv_data;
struct resource *res;
int ret, irq, i;
if (!pdev->dev.of_node)
return -ENODEV;
match = of_match_node(rockchip_mbox_of_match, pdev->dev.of_node);
drv_data = (const struct rockchip_mbox_data *)match->data;
mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL);
if (!mb)
return -ENOMEM;
mb->chans = devm_kcalloc(&pdev->dev, drv_data->num_chans,
sizeof(*mb->chans), GFP_KERNEL);
if (!mb->chans)
return -ENOMEM;
mb->mbox.chans = devm_kcalloc(&pdev->dev, drv_data->num_chans,
sizeof(*mb->mbox.chans), GFP_KERNEL);
if (!mb->mbox.chans)
return -ENOMEM;
platform_set_drvdata(pdev, mb);
mb->mbox.dev = &pdev->dev;
mb->mbox.num_chans = drv_data->num_chans;
mb->mbox.ops = &rockchip_mbox_chan_ops;
mb->mbox.txdone_irq = true;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
mb->mbox_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mb->mbox_base))
return PTR_ERR(mb->mbox_base);
/* Each channel has two buffers for A2B and B2A */
mb->buf_size = (size_t)resource_size(res) / (drv_data->num_chans * 2);
mb->pclk = devm_clk_get(&pdev->dev, "pclk_mailbox");
if (IS_ERR(mb->pclk)) {
ret = PTR_ERR(mb->pclk);
dev_err(&pdev->dev, "failed to get pclk_mailbox clock: %d\n",
ret);
return ret;
}
ret = clk_prepare_enable(mb->pclk);
if (ret) {
dev_err(&pdev->dev, "failed to enable pclk: %d\n", ret);
return ret;
}
for (i = 0; i < mb->mbox.num_chans; i++) {
irq = platform_get_irq(pdev, i);
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(&pdev->dev, irq,
rockchip_mbox_irq,
rockchip_mbox_isr, IRQF_ONESHOT,
dev_name(&pdev->dev), mb);
if (ret < 0)
return ret;
mb->chans[i].idx = i;
mb->chans[i].irq = irq;
mb->chans[i].mb = mb;
mb->chans[i].msg = NULL;
}
ret = devm_mbox_controller_register(&pdev->dev, &mb->mbox);
if (ret < 0)
dev_err(&pdev->dev, "Failed to register mailbox: %d\n", ret);
return ret;
}