1 // SPDX-License-Identifier: GPL-2.0 2 #include <asm/fpu.h> 3 #include <asm/loongson.h> 4 #include <asm/sections.h> 5 #include <asm/time.h> 6 #include <asm/tlbflush.h> 7 #include <linux/suspend.h> 8 9 static u32 saved_crmd; 10 static u32 saved_prmd; 11 static u32 saved_euen; 12 static u32 saved_ecfg; 13 static u64 saved_pcpu_base; 14 struct pt_regs saved_regs; 15 16 void save_processor_state(void) 17 { 18 save_counter(); 19 saved_crmd = csr_read32(LOONGARCH_CSR_CRMD); 20 saved_prmd = csr_read32(LOONGARCH_CSR_PRMD); 21 saved_euen = csr_read32(LOONGARCH_CSR_EUEN); 22 saved_ecfg = csr_read32(LOONGARCH_CSR_ECFG); 23 saved_pcpu_base = csr_read64(PERCPU_BASE_KS); 24 25 if (is_fpu_owner()) 26 save_fp(current); 27 } 28 29 void restore_processor_state(void) 30 { 31 sync_counter(); 32 csr_write32(saved_crmd, LOONGARCH_CSR_CRMD); 33 csr_write32(saved_prmd, LOONGARCH_CSR_PRMD); 34 csr_write32(saved_euen, LOONGARCH_CSR_EUEN); 35 csr_write32(saved_ecfg, LOONGARCH_CSR_ECFG); 36 csr_write64(saved_pcpu_base, PERCPU_BASE_KS); 37 38 if (is_fpu_owner()) 39 restore_fp(current); 40 } 41 42 int pfn_is_nosave(unsigned long pfn) 43 { 44 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin)); 45 unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end)); 46 47 return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); 48 } 49 50 extern int swsusp_asm_suspend(void); 51 52 int swsusp_arch_suspend(void) 53 { 54 enable_pci_wakeup(); 55 return swsusp_asm_suspend(); 56 } 57 58 extern int swsusp_asm_resume(void); 59 60 int swsusp_arch_resume(void) 61 { 62 /* Avoid TLB mismatch during and after kernel resume */ 63 local_flush_tlb_all(); 64 return swsusp_asm_resume(); 65 } 66