in ti-sysc.c [3251:3377]
static int sysc_probe(struct platform_device *pdev)
{
struct ti_sysc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct sysc *ddata;
int error;
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
ddata->offsets[SYSC_REVISION] = -ENODEV;
ddata->offsets[SYSC_SYSCONFIG] = -ENODEV;
ddata->offsets[SYSC_SYSSTATUS] = -ENODEV;
ddata->dev = &pdev->dev;
platform_set_drvdata(pdev, ddata);
error = sysc_init_static_data(ddata);
if (error)
return error;
error = sysc_init_match(ddata);
if (error)
return error;
error = sysc_init_dts_quirks(ddata);
if (error)
return error;
error = sysc_map_and_check_registers(ddata);
if (error)
return error;
error = sysc_init_sysc_mask(ddata);
if (error)
return error;
error = sysc_init_idlemodes(ddata);
if (error)
return error;
error = sysc_init_syss_mask(ddata);
if (error)
return error;
error = sysc_init_pdata(ddata);
if (error)
return error;
sysc_init_early_quirks(ddata);
error = sysc_check_disabled_devices(ddata);
if (error)
return error;
error = sysc_check_active_timer(ddata);
if (error == -ENXIO)
ddata->reserved = true;
else if (error)
return error;
error = sysc_get_clocks(ddata);
if (error)
return error;
error = sysc_init_resets(ddata);
if (error)
goto unprepare;
error = sysc_init_module(ddata);
if (error)
goto unprepare;
pm_runtime_enable(ddata->dev);
error = pm_runtime_resume_and_get(ddata->dev);
if (error < 0) {
pm_runtime_disable(ddata->dev);
goto unprepare;
}
/* Balance use counts as PM runtime should have enabled these all */
if (!(ddata->cfg.quirks &
(SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
sysc_disable_main_clocks(ddata);
sysc_disable_opt_clocks(ddata);
sysc_clkdm_allow_idle(ddata);
}
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
sysc_show_registers(ddata);
ddata->dev->type = &sysc_device_type;
if (!ddata->reserved) {
error = of_platform_populate(ddata->dev->of_node,
sysc_match_table,
pdata ? pdata->auxdata : NULL,
ddata->dev);
if (error)
goto err;
}
INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle);
/* At least earlycon won't survive without deferred idle */
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE |
SYSC_QUIRK_NO_IDLE_ON_INIT |
SYSC_QUIRK_NO_RESET_ON_INIT)) {
schedule_delayed_work(&ddata->idle_work, 3000);
} else {
pm_runtime_put(&pdev->dev);
}
if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_CTX_LOST)
sysc_add_restored(ddata);
return 0;
err:
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
unprepare:
sysc_unprepare(ddata);
return error;
}