162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <asm/fpu.h> 362306a36Sopenharmony_ci#include <asm/loongson.h> 462306a36Sopenharmony_ci#include <asm/sections.h> 562306a36Sopenharmony_ci#include <asm/tlbflush.h> 662306a36Sopenharmony_ci#include <linux/suspend.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_cistatic u32 saved_crmd; 962306a36Sopenharmony_cistatic u32 saved_prmd; 1062306a36Sopenharmony_cistatic u32 saved_euen; 1162306a36Sopenharmony_cistatic u32 saved_ecfg; 1262306a36Sopenharmony_cistatic u64 saved_pcpu_base; 1362306a36Sopenharmony_cistruct pt_regs saved_regs; 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_civoid save_processor_state(void) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci saved_crmd = csr_read32(LOONGARCH_CSR_CRMD); 1862306a36Sopenharmony_ci saved_prmd = csr_read32(LOONGARCH_CSR_PRMD); 1962306a36Sopenharmony_ci saved_euen = csr_read32(LOONGARCH_CSR_EUEN); 2062306a36Sopenharmony_ci saved_ecfg = csr_read32(LOONGARCH_CSR_ECFG); 2162306a36Sopenharmony_ci saved_pcpu_base = csr_read64(PERCPU_BASE_KS); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci if (is_fpu_owner()) 2462306a36Sopenharmony_ci save_fp(current); 2562306a36Sopenharmony_ci} 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_civoid restore_processor_state(void) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci csr_write32(saved_crmd, LOONGARCH_CSR_CRMD); 3062306a36Sopenharmony_ci csr_write32(saved_prmd, LOONGARCH_CSR_PRMD); 3162306a36Sopenharmony_ci csr_write32(saved_euen, LOONGARCH_CSR_EUEN); 3262306a36Sopenharmony_ci csr_write32(saved_ecfg, LOONGARCH_CSR_ECFG); 3362306a36Sopenharmony_ci csr_write64(saved_pcpu_base, PERCPU_BASE_KS); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci if (is_fpu_owner()) 3662306a36Sopenharmony_ci restore_fp(current); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ciint pfn_is_nosave(unsigned long pfn) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin)); 4262306a36Sopenharmony_ci unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end)); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciextern int swsusp_asm_suspend(void); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciint swsusp_arch_suspend(void) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci enable_pci_wakeup(); 5262306a36Sopenharmony_ci return swsusp_asm_suspend(); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ciextern int swsusp_asm_resume(void); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ciint swsusp_arch_resume(void) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci /* Avoid TLB mismatch during and after kernel resume */ 6062306a36Sopenharmony_ci local_flush_tlb_all(); 6162306a36Sopenharmony_ci return swsusp_asm_resume(); 6262306a36Sopenharmony_ci} 63