in master/dw-i3c-master.c [1115:1182]
static int dw_i3c_probe(struct platform_device *pdev)
{
struct dw_i3c_master *master;
int ret, irq;
master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
if (!master)
return -ENOMEM;
master->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(master->regs))
return PTR_ERR(master->regs);
master->core_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(master->core_clk))
return PTR_ERR(master->core_clk);
master->core_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
"core_rst");
if (IS_ERR(master->core_rst))
return PTR_ERR(master->core_rst);
ret = clk_prepare_enable(master->core_clk);
if (ret)
goto err_disable_core_clk;
reset_control_deassert(master->core_rst);
spin_lock_init(&master->xferqueue.lock);
INIT_LIST_HEAD(&master->xferqueue.list);
writel(INTR_ALL, master->regs + INTR_STATUS);
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(&pdev->dev, irq,
dw_i3c_master_irq_handler, 0,
dev_name(&pdev->dev), master);
if (ret)
goto err_assert_rst;
platform_set_drvdata(pdev, master);
/* Information regarding the FIFOs/QUEUEs depth */
ret = readl(master->regs + QUEUE_STATUS_LEVEL);
master->caps.cmdfifodepth = QUEUE_STATUS_LEVEL_CMD(ret);
ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL);
master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret);
ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
master->datstartaddr = ret;
master->maxdevs = ret >> 16;
master->free_pos = GENMASK(master->maxdevs - 1, 0);
ret = i3c_master_register(&master->base, &pdev->dev,
&dw_mipi_i3c_ops, false);
if (ret)
goto err_assert_rst;
return 0;
err_assert_rst:
reset_control_assert(master->core_rst);
err_disable_core_clk:
clk_disable_unprepare(master->core_clk);
return ret;
}