idle.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * The idle loop for all SuperH platforms.
  3. *
  4. * Copyright (C) 2002 - 2009 Paul Mundt
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/init.h>
  12. #include <linux/mm.h>
  13. #include <linux/pm.h>
  14. #include <linux/tick.h>
  15. #include <linux/preempt.h>
  16. #include <linux/thread_info.h>
  17. #include <linux/irqflags.h>
  18. #include <linux/smp.h>
  19. #include <asm/pgalloc.h>
  20. #include <asm/system.h>
  21. #include <asm/atomic.h>
  22. static int hlt_counter;
  23. void (*pm_idle)(void);
  24. void (*pm_power_off)(void);
  25. EXPORT_SYMBOL(pm_power_off);
  26. static int __init nohlt_setup(char *__unused)
  27. {
  28. hlt_counter = 1;
  29. return 1;
  30. }
  31. __setup("nohlt", nohlt_setup);
  32. static int __init hlt_setup(char *__unused)
  33. {
  34. hlt_counter = 0;
  35. return 1;
  36. }
  37. __setup("hlt", hlt_setup);
  38. void default_idle(void)
  39. {
  40. if (!hlt_counter) {
  41. clear_thread_flag(TIF_POLLING_NRFLAG);
  42. smp_mb__after_clear_bit();
  43. set_bl_bit();
  44. stop_critical_timings();
  45. while (!need_resched())
  46. cpu_sleep();
  47. start_critical_timings();
  48. clear_bl_bit();
  49. set_thread_flag(TIF_POLLING_NRFLAG);
  50. } else
  51. while (!need_resched())
  52. cpu_relax();
  53. }
  54. void cpu_idle(void)
  55. {
  56. set_thread_flag(TIF_POLLING_NRFLAG);
  57. /* endless idle loop with no priority at all */
  58. while (1) {
  59. void (*idle)(void) = pm_idle;
  60. if (!idle)
  61. idle = default_idle;
  62. tick_nohz_stop_sched_tick(1);
  63. while (!need_resched())
  64. idle();
  65. tick_nohz_restart_sched_tick();
  66. preempt_enable_no_resched();
  67. schedule();
  68. preempt_disable();
  69. check_pgt_cache();
  70. }
  71. }
  72. static void do_nothing(void *unused)
  73. {
  74. }
  75. /*
  76. * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
  77. * pm_idle and update to new pm_idle value. Required while changing pm_idle
  78. * handler on SMP systems.
  79. *
  80. * Caller must have changed pm_idle to the new value before the call. Old
  81. * pm_idle value will not be used by any CPU after the return of this function.
  82. */
  83. void cpu_idle_wait(void)
  84. {
  85. smp_mb();
  86. /* kick all the CPUs so that they exit out of pm_idle */
  87. smp_call_function(do_nothing, NULL, 1);
  88. }
  89. EXPORT_SYMBOL_GPL(cpu_idle_wait);