cpu_hibernate.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * ARM Cortex-A7 save/restore for suspend to disk (Hibernation)
  3. */
  4. #include <linux/kernel.h>
  5. #include <linux/module.h>
  6. #include <linux/init.h>
  7. #include <linux/types.h>
  8. #include <linux/spinlock.h>
  9. #include <linux/poll.h>
  10. #include <linux/delay.h>
  11. #include <linux/sysrq.h>
  12. #include <linux/proc_fs.h>
  13. #include <linux/pm.h>
  14. #include <linux/device.h>
  15. #include <linux/suspend.h>
  16. #include <linux/mm.h>
  17. #include <asm/irq.h>
  18. #include <asm/uaccess.h>
  19. #include <asm/tlbflush.h>
  20. #include <asm/suspend.h>
  21. #include <asm/cacheflush.h>
  22. #include <asm/system_misc.h>
  23. #include <asm/idmap.h>
  24. #include <mtk_hibernate_core.h>
  25. typedef struct fault_regs {
  26. unsigned dfar;
  27. unsigned ifar;
  28. unsigned ifsr;
  29. unsigned dfsr;
  30. unsigned adfsr;
  31. unsigned aifsr;
  32. } cp15_fault_regs;
  33. typedef struct ns_banked_cp15_context {
  34. unsigned int cp15_misc_regs[2]; /* cp15 miscellaneous registers */
  35. unsigned int cp15_ctrl_regs[20]; /* cp15 control registers */
  36. unsigned int cp15_mmu_regs[16]; /* cp15 mmu registers */
  37. cp15_fault_regs ns_cp15_fault_regs; /* cp15 fault status registers */
  38. } banked_cp15_context;
  39. typedef struct cpu_context {
  40. unsigned int banked_regs[32];
  41. unsigned int timer_data[8]; /* Global timers if the NS world has access to them */
  42. } core_context;
  43. static banked_cp15_context saved_cp15_context;
  44. static core_context saved_core_context;
  45. static void __save_processor_state(struct ns_banked_cp15_context *ctxt)
  46. {
  47. /* save preempt state and disable it */
  48. preempt_disable();
  49. mt_save_generic_timer(saved_core_context.timer_data, 0x0);
  50. mt_save_banked_registers(saved_core_context.banked_regs);
  51. }
  52. void notrace mtk_save_processor_state(void)
  53. {
  54. __save_processor_state(&saved_cp15_context);
  55. }
  56. EXPORT_SYMBOL(mtk_save_processor_state);
  57. static void __restore_processor_state(struct ns_banked_cp15_context *ctxt)
  58. {
  59. mt_restore_banked_registers(saved_core_context.banked_regs);
  60. mt_restore_generic_timer(saved_core_context.timer_data, 0x0);
  61. #ifdef CONFIG_MTK_ETM
  62. /* restore ETM module */
  63. trace_start_dormant();
  64. #endif
  65. /* restore preempt state */
  66. preempt_enable();
  67. }
  68. void notrace mtk_restore_processor_state(void)
  69. {
  70. __restore_processor_state(&saved_cp15_context);
  71. }
  72. EXPORT_SYMBOL(mtk_restore_processor_state);
  73. typedef void (*phys_reset_t)(unsigned long);
  74. /*
  75. * The framework loads the hibernation image into a linked list anchored
  76. * at restore_pblist, for swsusp_arch_resume() to copy back to the proper
  77. * destinations.
  78. *
  79. * To make this work if resume is triggered from initramfs, the
  80. * pagetables need to be switched to allow writes to kernel mem.
  81. */
  82. void notrace mtk_arch_restore_image(void)
  83. {
  84. phys_reset_t phys_reset;
  85. struct pbe *pbe;
  86. for (pbe = restore_pblist; pbe; pbe = pbe->next)
  87. copy_page(pbe->orig_address, pbe->address);
  88. #if 0 /* [ALPS01496758] since CA17 has cache bug, replace with the modified assemlby version */
  89. /* Clean and invalidate caches */
  90. flush_cache_all();
  91. /* Turn off caching */
  92. cpu_proc_fin();
  93. /* Push out any further dirty data, and ensure cache is empty */
  94. flush_cache_all();
  95. #else
  96. __disable_dcache__inner_flush_dcache_L1__inner_flush_dcache_L2();
  97. #endif
  98. /* Take out a flat memory mapping. */
  99. setup_mm_for_reboot();
  100. phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
  101. /* Return from cpu_suspend/swsusp_arch_suspend */
  102. phys_reset((unsigned long)virt_to_phys(cpu_resume));
  103. /* Should never get here. */
  104. BUG();
  105. }
  106. EXPORT_SYMBOL(mtk_arch_restore_image);