hotplug.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Copyright 2011 Freescale Semiconductor, Inc.
  3. * Copyright 2011 Linaro Ltd.
  4. *
  5. * The code contained herein is licensed under the GNU General Public
  6. * License. You may obtain a copy of the GNU General Public License
  7. * Version 2 or later at the following locations:
  8. *
  9. * http://www.opensource.org/licenses/gpl-license.html
  10. * http://www.gnu.org/copyleft/gpl.html
  11. */
  12. #include <linux/errno.h>
  13. #include <linux/jiffies.h>
  14. #include <asm/cp15.h>
  15. #include <asm/proc-fns.h>
  16. #include "common.h"
  17. static inline void cpu_enter_lowpower(void)
  18. {
  19. unsigned int v;
  20. asm volatile(
  21. "mcr p15, 0, %1, c7, c5, 0\n"
  22. " mcr p15, 0, %1, c7, c10, 4\n"
  23. /*
  24. * Turn off coherency
  25. */
  26. " mrc p15, 0, %0, c1, c0, 1\n"
  27. " bic %0, %0, %3\n"
  28. " mcr p15, 0, %0, c1, c0, 1\n"
  29. " mrc p15, 0, %0, c1, c0, 0\n"
  30. " bic %0, %0, %2\n"
  31. " mcr p15, 0, %0, c1, c0, 0\n"
  32. : "=&r" (v)
  33. : "r" (0), "Ir" (CR_C), "Ir" (0x40)
  34. : "cc");
  35. }
  36. /*
  37. * platform-specific code to shutdown a CPU
  38. *
  39. * Called with IRQs disabled
  40. */
  41. void imx_cpu_die(unsigned int cpu)
  42. {
  43. cpu_enter_lowpower();
  44. /*
  45. * We use the cpu jumping argument register to sync with
  46. * imx_cpu_kill() which is running on cpu0 and waiting for
  47. * the register being cleared to kill the cpu.
  48. */
  49. imx_set_cpu_arg(cpu, ~0);
  50. while (1)
  51. cpu_do_idle();
  52. }
  53. int imx_cpu_kill(unsigned int cpu)
  54. {
  55. unsigned long timeout = jiffies + msecs_to_jiffies(50);
  56. while (imx_get_cpu_arg(cpu) == 0)
  57. if (time_after(jiffies, timeout))
  58. return 0;
  59. imx_enable_cpu(cpu, false);
  60. imx_set_cpu_arg(cpu, 0);
  61. return 1;
  62. }