aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/cpuidle-qcom-spm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpuidle/cpuidle-qcom-spm.c')
-rw-r--r--drivers/cpuidle/cpuidle-qcom-spm.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c
index 01e77913a414..beedf22cbe78 100644
--- a/drivers/cpuidle/cpuidle-qcom-spm.c
+++ b/drivers/cpuidle/cpuidle-qcom-spm.c
@@ -122,10 +122,6 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
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);
}
@@ -136,6 +132,10 @@ static int spm_cpuidle_drv_probe(struct platform_device *pdev)
if (!qcom_scm_is_available())
return -EPROBE_DEFER;
+ ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "set warm boot addr failed");
+
for_each_possible_cpu(cpu) {
ret = spm_cpuidle_register(&pdev->dev, cpu);
if (ret && ret != -ENODEV) {
@@ -155,6 +155,22 @@ static struct platform_driver spm_cpuidle_driver = {
},
};
+static bool __init qcom_spm_find_any_cpu(void)
+{
+ struct device_node *cpu_node, *saw_node;
+
+ for_each_of_cpu_node(cpu_node) {
+ saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
+ if (of_device_is_available(saw_node)) {
+ of_node_put(saw_node);
+ of_node_put(cpu_node);
+ return true;
+ }
+ of_node_put(saw_node);
+ }
+ return false;
+}
+
static int __init qcom_spm_cpuidle_init(void)
{
struct platform_device *pdev;
@@ -164,6 +180,10 @@ static int __init qcom_spm_cpuidle_init(void)
if (ret)
return ret;
+ /* Make sure there is actually any CPU managed by the SPM */
+ if (!qcom_spm_find_any_cpu())
+ return 0;
+
pdev = platform_device_register_simple("qcom-spm-cpuidle",
-1, NULL, 0);
if (IS_ERR(pdev)) {