1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * loongson-specific suspend support 4 * 5 * Author: Huacai Chen <chenhuacai@loongson.cn> 6 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 7 */ 8 #include <linux/acpi.h> 9 #include <linux/pm.h> 10 #include <linux/suspend.h> 11 12 #include <asm/loongarch.h> 13 #include <asm/loongson.h> 14 #include <asm/setup.h> 15 #include <asm/time.h> 16 #include <asm/tlbflush.h> 17 18 u64 loongarch_suspend_addr; 19 20 struct saved_registers { 21 u32 ecfg; 22 u32 euen; 23 u64 pgd; 24 u64 kpgd; 25 u32 pwctl0; 26 u32 pwctl1; 27 }; 28 static struct saved_registers saved_regs; 29 30 static void arch_common_suspend(void) 31 { 32 save_counter(); 33 saved_regs.pgd = csr_read64(LOONGARCH_CSR_PGDL); 34 saved_regs.kpgd = csr_read64(LOONGARCH_CSR_PGDH); 35 saved_regs.pwctl0 = csr_read32(LOONGARCH_CSR_PWCTL0); 36 saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1); 37 saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG); 38 saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN); 39 40 loongarch_suspend_addr = loongson_sysconf.suspend_addr; 41 } 42 43 static void arch_common_resume(void) 44 { 45 sync_counter(); 46 local_flush_tlb_all(); 47 csr_write64(per_cpu_offset(0), PERCPU_BASE_KS); 48 csr_write64(eentry, LOONGARCH_CSR_EENTRY); 49 csr_write64(eentry, LOONGARCH_CSR_MERRENTRY); 50 csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY); 51 52 csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL); 53 csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH); 54 csr_write32(saved_regs.pwctl0, LOONGARCH_CSR_PWCTL0); 55 csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1); 56 csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG); 57 csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN); 58 } 59 60 int loongarch_acpi_suspend(void) 61 { 62 enable_gpe_wakeup(); 63 enable_pci_wakeup(); 64 65 arch_common_suspend(); 66 67 /* processor specific suspend */ 68 loongarch_suspend_enter(); 69 70 arch_common_resume(); 71 72 return 0; 73 } 74