Skip to content

Commit 366bb35

Browse files
committed
LoongArch: Add suspend (ACPI S3) support
Add suspend (Suspend To RAM, aka ACPI S3) support for LoongArch. Signed-off-by: Huacai Chen <[email protected]>
1 parent 27cab43 commit 366bb35

File tree

13 files changed

+260
-3
lines changed

13 files changed

+260
-3
lines changed

arch/loongarch/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ config LOONGARCH
5656
select ARCH_WANTS_NO_INSTR
5757
select BUILDTIME_TABLE_SORT
5858
select COMMON_CLK
59+
select CPU_PM
5960
select EFI
6061
select GENERIC_CLOCKEVENTS
6162
select GENERIC_CMOS_UPDATE
@@ -517,6 +518,10 @@ config ARCH_MMAP_RND_BITS_MAX
517518

518519
menu "Power management options"
519520

521+
config ARCH_SUSPEND_POSSIBLE
522+
def_bool y
523+
524+
source "kernel/power/Kconfig"
520525
source "drivers/acpi/Kconfig"
521526

522527
endmenu

arch/loongarch/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ endif
104104
libs-y += arch/loongarch/lib/
105105
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
106106

107+
# suspend and hibernation support
108+
drivers-$(CONFIG_PM) += arch/loongarch/power/
109+
107110
ifeq ($(KBUILD_EXTMOD),)
108111
prepare: vdso_prepare
109112
vdso_prepare: prepare0

arch/loongarch/include/asm/acpi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,14 @@ extern struct list_head acpi_wakeup_device_list;
3535

3636
#define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT
3737

38+
extern int loongarch_acpi_suspend(void);
39+
extern int (*acpi_suspend_lowlevel)(void);
40+
extern void loongarch_suspend_enter(void);
41+
42+
static inline unsigned long acpi_get_wakeup_address(void)
43+
{
44+
extern void loongarch_wakeup_start(void);
45+
return (unsigned long)loongarch_wakeup_start;
46+
}
47+
3848
#endif /* _ASM_LOONGARCH_ACPI_H */

arch/loongarch/include/asm/bootinfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct loongson_system_configuration {
3232
int cores_per_node;
3333
int cores_per_package;
3434
unsigned long cores_io_master;
35+
unsigned long suspend_addr;
3536
const char *cpuname;
3637
};
3738

arch/loongarch/include/asm/loongson.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,7 @@ typedef enum {
136136
#define ls7a_writel(val, addr) *(volatile unsigned int *)TO_UNCACHE(addr) = (val)
137137
#define ls7a_writeq(val, addr) *(volatile unsigned long *)TO_UNCACHE(addr) = (val)
138138

139+
void enable_gpe_wakeup(void);
140+
void enable_pci_wakeup(void);
141+
139142
#endif /* __ASM_LOONGSON_H */

arch/loongarch/include/asm/time.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
extern u64 cpu_clock_freq;
1313
extern u64 const_clock_freq;
1414

15+
extern void save_counter(void);
1516
extern void sync_counter(void);
1617

1718
static inline unsigned int calc_const_freq(void)

arch/loongarch/kernel/acpi.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ static void __init acpi_process_madt(void)
140140
loongson_sysconf.nr_cpus = num_processors;
141141
}
142142

143+
#ifndef CONFIG_SUSPEND
144+
int (*acpi_suspend_lowlevel)(void);
145+
#else
146+
int (*acpi_suspend_lowlevel)(void) = loongarch_acpi_suspend;
147+
#endif
148+
143149
void __init acpi_boot_table_init(void)
144150
{
145151
/*

arch/loongarch/kernel/smp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/smp.h>
1717
#include <linux/threads.h>
1818
#include <linux/export.h>
19+
#include <linux/syscore_ops.h>
1920
#include <linux/time.h>
2021
#include <linux/tracepoint.h>
2122
#include <linux/sched/hotplug.h>

arch/loongarch/kernel/time.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,17 @@ static unsigned long __init get_loops_per_jiffy(void)
115115
return lpj;
116116
}
117117

118-
static long init_timeval;
118+
static long init_offset __nosavedata;
119+
120+
void save_counter(void)
121+
{
122+
init_offset = drdtime();
123+
}
119124

120125
void sync_counter(void)
121126
{
122127
/* Ensure counter begin at 0 */
123-
csr_write64(-init_timeval, LOONGARCH_CSR_CNTC);
128+
csr_write64(init_offset, LOONGARCH_CSR_CNTC);
124129
}
125130

126131
static int get_timer_irq(void)
@@ -219,7 +224,7 @@ void __init time_init(void)
219224
else
220225
const_clock_freq = calc_const_freq();
221226

222-
init_timeval = drdtime() - csr_read64(LOONGARCH_CSR_CNTC);
227+
init_offset = -(drdtime() - csr_read64(LOONGARCH_CSR_CNTC));
223228

224229
constant_clockevent_init();
225230
constant_clocksource_init();

arch/loongarch/power/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
obj-y += platform.o
2+
3+
obj-$(CONFIG_SUSPEND) += suspend.o suspend_asm.o

0 commit comments

Comments
 (0)