cpuidle-arm.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ARM/ARM64 generic CPU idle driver.
  4. *
  5. * Copyright (C) 2014 ARM Ltd.
  6. * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
  7. */
  8. #define pr_fmt(fmt) "CPUidle arm: " fmt
  9. #include <linux/cpu_cooling.h>
  10. #include <linux/cpuidle.h>
  11. #include <linux/cpumask.h>
  12. #include <linux/cpu_pm.h>
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/slab.h>
  17. #include <asm/cpuidle.h>
  18. #include "dt_idle_states.h"
  19. /*
  20. * arm_enter_idle_state - Programs CPU to enter the specified state
  21. *
  22. * dev: cpuidle device
  23. * drv: cpuidle driver
  24. * idx: state index
  25. *
  26. * Called from the CPUidle framework to program the device to the
  27. * specified target state selected by the governor.
  28. */
  29. static int arm_enter_idle_state(struct cpuidle_device *dev,
  30. struct cpuidle_driver *drv, int idx)
  31. {
  32. /*
  33. * Pass idle state index to arm_cpuidle_suspend which in turn
  34. * will call the CPU ops suspend protocol with idle index as a
  35. * parameter.
  36. */
  37. return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, idx);
  38. }
  39. static struct cpuidle_driver arm_idle_driver __initdata = {
  40. .name = "arm_idle",
  41. .owner = THIS_MODULE,
  42. /*
  43. * State at index 0 is standby wfi and considered standard
  44. * on all ARM platforms. If in some platforms simple wfi
  45. * can't be used as "state 0", DT bindings must be implemented
  46. * to work around this issue and allow installing a special
  47. * handler for idle state index 0.
  48. */
  49. .states[0] = {
  50. .enter = arm_enter_idle_state,
  51. .exit_latency = 1,
  52. .target_residency = 1,
  53. .power_usage = UINT_MAX,
  54. .name = "WFI",
  55. .desc = "ARM WFI",
  56. }
  57. };
  58. static const struct of_device_id arm_idle_state_match[] __initconst = {
  59. { .compatible = "arm,idle-state",
  60. .data = arm_enter_idle_state },
  61. { },
  62. };
  63. /*
  64. * arm_idle_init_cpu
  65. *
  66. * Registers the arm specific cpuidle driver with the cpuidle
  67. * framework. It relies on core code to parse the idle states
  68. * and initialize them using driver data structures accordingly.
  69. */
  70. static int __init arm_idle_init_cpu(int cpu)
  71. {
  72. int ret;
  73. struct cpuidle_driver *drv;
  74. drv = kmemdup(&arm_idle_driver, sizeof(*drv), GFP_KERNEL);
  75. if (!drv)
  76. return -ENOMEM;
  77. drv->cpumask = (struct cpumask *)cpumask_of(cpu);
  78. /*
  79. * Initialize idle states data, starting at index 1. This
  80. * driver is DT only, if no DT idle states are detected (ret
  81. * == 0) let the driver initialization fail accordingly since
  82. * there is no reason to initialize the idle driver if only
  83. * wfi is supported.
  84. */
  85. ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
  86. if (ret <= 0) {
  87. ret = ret ? : -ENODEV;
  88. goto out_kfree_drv;
  89. }
  90. /*
  91. * Call arch CPU operations in order to initialize
  92. * idle states suspend back-end specific data
  93. */
  94. ret = arm_cpuidle_init(cpu);
  95. /*
  96. * Allow the initialization to continue for other CPUs, if the
  97. * reported failure is a HW misconfiguration/breakage (-ENXIO).
  98. *
  99. * Some platforms do not support idle operations
  100. * (arm_cpuidle_init() returning -EOPNOTSUPP), we should
  101. * not flag this case as an error, it is a valid
  102. * configuration.
  103. */
  104. if (ret) {
  105. if (ret != -EOPNOTSUPP)
  106. pr_err("CPU %d failed to init idle CPU ops\n", cpu);
  107. ret = ret == -ENXIO ? 0 : ret;
  108. goto out_kfree_drv;
  109. }
  110. ret = cpuidle_register(drv, NULL);
  111. if (ret)
  112. goto out_kfree_drv;
  113. cpuidle_cooling_register(drv);
  114. return 0;
  115. out_kfree_drv:
  116. kfree(drv);
  117. return ret;
  118. }
  119. /*
  120. * arm_idle_init - Initializes arm cpuidle driver
  121. *
  122. * Initializes arm cpuidle driver for all CPUs, if any CPU fails
  123. * to register cpuidle driver then rollback to cancel all CPUs
  124. * registeration.
  125. */
  126. static int __init arm_idle_init(void)
  127. {
  128. int cpu, ret;
  129. struct cpuidle_driver *drv;
  130. struct cpuidle_device *dev;
  131. for_each_possible_cpu(cpu) {
  132. ret = arm_idle_init_cpu(cpu);
  133. if (ret)
  134. goto out_fail;
  135. }
  136. return 0;
  137. out_fail:
  138. while (--cpu >= 0) {
  139. dev = per_cpu(cpuidle_devices, cpu);
  140. drv = cpuidle_get_cpu_driver(dev);
  141. cpuidle_unregister(drv);
  142. kfree(drv);
  143. }
  144. return ret;
  145. }
  146. device_initcall(arm_idle_init);