in cpuidle-qcom-spm.c [88:130]
static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
{
struct platform_device *pdev = NULL;
struct device_node *cpu_node, *saw_node;
struct cpuidle_qcom_spm_data *data = NULL;
int ret;
cpu_node = of_cpu_device_node_get(cpu);
if (!cpu_node)
return -ENODEV;
saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
if (!saw_node)
return -ENODEV;
pdev = of_find_device_by_node(saw_node);
of_node_put(saw_node);
of_node_put(cpu_node);
if (!pdev)
return -ENODEV;
data = devm_kzalloc(cpuidle_dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->spm = dev_get_drvdata(&pdev->dev);
if (!data->spm)
return -EINVAL;
data->cpuidle_driver = qcom_spm_idle_driver;
data->cpuidle_driver.cpumask = (struct cpumask *)cpumask_of(cpu);
ret = dt_init_idle_driver(&data->cpuidle_driver,
qcom_idle_state_match, 1);
if (ret <= 0)
return ret ? : -ENODEV;
ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm, cpumask_of(cpu));
if (ret)
return ret;
return cpuidle_register(&data->cpuidle_driver, NULL);
}