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