in master/svc-i3c-master.c [1481:1570]
static int svc_i3c_master_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct svc_i3c_master *master;
int ret;
master = devm_kzalloc(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->pclk = devm_clk_get(dev, "pclk");
if (IS_ERR(master->pclk))
return PTR_ERR(master->pclk);
master->fclk = devm_clk_get(dev, "fast_clk");
if (IS_ERR(master->fclk))
return PTR_ERR(master->fclk);
master->sclk = devm_clk_get(dev, "slow_clk");
if (IS_ERR(master->sclk))
return PTR_ERR(master->sclk);
master->irq = platform_get_irq(pdev, 0);
if (master->irq <= 0)
return -ENOENT;
master->dev = dev;
ret = svc_i3c_master_prepare_clks(master);
if (ret)
return ret;
INIT_WORK(&master->hj_work, svc_i3c_master_hj_work);
INIT_WORK(&master->ibi_work, svc_i3c_master_ibi_work);
ret = devm_request_irq(dev, master->irq, svc_i3c_master_irq_handler,
IRQF_NO_SUSPEND, "svc-i3c-irq", master);
if (ret)
goto err_disable_clks;
master->free_slots = GENMASK(SVC_I3C_MAX_DEVS - 1, 0);
spin_lock_init(&master->xferqueue.lock);
INIT_LIST_HEAD(&master->xferqueue.list);
spin_lock_init(&master->ibi.lock);
master->ibi.num_slots = SVC_I3C_MAX_DEVS;
master->ibi.slots = devm_kcalloc(&pdev->dev, master->ibi.num_slots,
sizeof(*master->ibi.slots),
GFP_KERNEL);
if (!master->ibi.slots) {
ret = -ENOMEM;
goto err_disable_clks;
}
platform_set_drvdata(pdev, master);
pm_runtime_set_autosuspend_delay(&pdev->dev, SVC_I3C_PM_TIMEOUT_MS);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
svc_i3c_master_reset(master);
/* Register the master */
ret = i3c_master_register(&master->base, &pdev->dev,
&svc_i3c_master_ops, false);
if (ret)
goto rpm_disable;
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
return 0;
rpm_disable:
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_disable(&pdev->dev);
err_disable_clks:
svc_i3c_master_unprepare_clks(master);
return ret;
}