From: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> Some architectures have some cpus which does not support idle states or may be ready to do idle states only when the platform dependencies are probed. Let the underlying low level code return -ENOSYS when it is not possible to set an idle state at this time. Signed-off-by: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> Signed-off-by: Lina Iyer <lina.iyer@xxxxxxxxxx> [Minor clean ups] --- drivers/cpuidle/cpuidle-arm.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index 1c94b88..e176469 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -17,6 +17,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/slab.h> +#include <linux/device.h> +#include <linux/cpu.h> #include <asm/cpuidle.h> @@ -93,6 +96,7 @@ static const struct of_device_id arm_idle_state_match[] __initconst = { static int __init arm_idle_init(void) { int cpu, ret; + struct cpuidle_device *dev; struct cpuidle_driver *drv = &arm_idle_driver; /* @@ -105,18 +109,49 @@ static int __init arm_idle_init(void) if (ret <= 0) return ret ? : -ENODEV; + + ret = cpuidle_register_driver(drv); + if (ret) { + pr_err("Failed to register cpuidle driver\n"); + return ret; + } + /* * Call arch CPU operations in order to initialize * idle states suspend back-end specific data */ for_each_possible_cpu(cpu) { ret = arm_cpuidle_init(cpu); + + /* + * -ENOSYS: Either the platform driver shall register + * a cpuidle device for this cpu, or there are no + * supported idle states. + */ + if (ret == -ENOSYS) + continue; + if (ret) { - pr_err("CPU %d failed to init idle CPU ops\n", cpu); + pr_err("CPU %d failed to init idle CPU ops, err=%d\n", + cpu, ret); return ret; } + + dev = devm_kzalloc(get_cpu_device(cpu), sizeof(*dev), + GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->cpu = cpu; + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("Failed to register cpuidle device for CPU %d, err=%d\n", + cpu, ret); + kfree(dev); + continue; + } } - return cpuidle_register(drv, NULL); + return ret; } device_initcall(arm_idle_init); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html