Commit 7889c0e6 authored by Jing Li's avatar Jing Li Committed by guzitao
Browse files

sw64: refactor reset routines with new API

Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IB73UR



--------------------------------

Refactor reset routines by using new do_kernel_power_off() instead of
old pm_power_off(), simplifying the source file (reset.c). In addition,
the routines of virtual and physical machine are separated, and the
legacy routines (legacy_xuelang.c and legacy_junzhang.c) are removed.

Signed-off-by: default avatarJing Li <jingli@wxiat.com>
Reviewed-by: default avatarHe Sheng <hesheng@wxiat.com>
Signed-off-by: default avatarGu Zitao <guzitao@wxiat.com>
parent 20f7f9be
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -4,16 +4,22 @@

#include <asm/io.h>
#include <asm/early_ioremap.h>

#ifdef CONFIG_EFI

extern void efi_init(void);
extern unsigned long entSuspend;

#define SLEEP_ENTRY_GUID	EFI_GUID(0x59cb76bb, 0x9c3a, 0x4c8f, 0xbd, 0x5c, 0xc0, 0x0f, 0x20, 0x61, 0x18, 0x4b)
#define BIOS_VERSION_GUID	EFI_GUID(0xc47a23c3, 0xcebb, 0x4cc9, 0xa5, 0xe2, 0xde, 0xd0, 0x8f, 0xe4, 0x20, 0xb5)

extern unsigned long sunway_bios_version;

#else
#define efi_init()
#define efi_idmap_init()
#endif
#define sunway_bios_version	(0)
#endif /* CONFIG_EFI */

#define arch_efi_call_virt_setup()
#define arch_efi_call_virt_teardown()
+1 −15
Original line number Diff line number Diff line
@@ -9,26 +9,12 @@
#include <asm/uncore_io_junzhang.h>
#endif

#ifdef CONFIG_EFI
#define BIOS_VERSION_GUID       EFI_GUID(0xc47a23c3, 0xcebb, 0x4cc9, 0xa5, 0xe2, 0xde, 0xd0, 0x8f, 0xe4, 0x20, 0xb5)

#define BIOS_SUPPORT_RESET_CLALLBACK(bios_version) ((bios_version) != NULL)

extern unsigned long bios_version;

#endif

extern struct boot_params *sunway_boot_params;
extern unsigned long sunway_boot_magic;
extern unsigned long sunway_dtb_address;

extern void sw64_halt(void);
extern void sw64_poweroff(void);
extern void sw64_restart(void);
extern void (*pm_restart)(void);
extern void (*pm_halt)(void);
extern int i2c_set_adapter(void);
extern void cpld_write(uint8_t slave_addr, uint8_t reg, uint8_t data);

extern void early_parse_fdt_property(const void *fdt, const char *path,
		const char *prop_name, u64 *property, int size);

+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ obj-$(CONFIG_RELOCATABLE) += relocate.o
obj-$(CONFIG_DEBUG_FS)	+= segvdbg.o unaligned.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_DEBUG_MATCH)	+= match.o
obj-$(CONFIG_EFI)	+= efi.o

ifdef CONFIG_PERF_EVENTS
obj-$(CONFIG_SUBARCH_C3B) += perf_event.o
+19 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <linux/acpi.h>
#include <linux/efi.h>

#include <asm/hw_init.h>

bool efi_poweroff_required(void)
{
	/* VM has its own poweroff interface */
	if (!is_in_host())
		return false;

	/* Prefer ACPI S5 */
	if (acpi_sleep_state_supported(ACPI_STATE_S5))
		return false;

	return efi_enabled(EFI_RUNTIME_SERVICES);
}
+69 −49
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2022 Sunway Technology Corporation Limited
 * Copyright (C) 2020-2024 Sunway Technology Corporation Limited
 */

#include <linux/acpi.h>
#include <linux/console.h>
#include <linux/delay.h>
@@ -14,10 +15,16 @@

#include <acpi/reboot.h>
#include <asm/idle.h>
#include <asm/efi.h>

void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);

static void default_halt(void)
void machine_halt(void)
{
	preempt_disable();
	local_irq_disable();
	smp_send_stop();

	pr_notice("\n\n** You can safely turn off the power now **\n\n");

@@ -25,74 +32,87 @@ static void default_halt(void)
		arch_cpu_idle();
}

static void default_poweroff(void)
void machine_power_off(void)
{
	/* No point in taking interrupts anymore. */
	preempt_disable();
	local_irq_disable();
#ifdef CONFIG_EFI
	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
#endif
	while (true)
		arch_cpu_idle();
}
	smp_send_stop();

static void default_restart(void)
{
#ifdef CONFIG_EFI
	if (efi_capsule_pending(NULL))
		efi_reboot(REBOOT_WARM, NULL);
	else
		efi_reboot(REBOOT_COLD, NULL);
#endif
	do_kernel_power_off();

	/* VM cannot reach here */
	WARN_ON(!is_in_host());

	/**
	 * Compatibility with old firmware, can be removed
	 * when no longer support SW3231.
	 */
	if (!sunway_bios_version)
		cpld_write(0x64, 0x00, 0xf0);

	while (true)
		arch_cpu_idle();
}

void (*pm_restart)(void);

void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);

void (*pm_halt)(void);

void machine_halt(void)
void machine_restart(char *command)
{
#ifdef CONFIG_SMP
	preempt_disable();
	local_irq_disable();
	smp_send_stop();
#endif
	pm_halt();

	do_kernel_restart(command);

	/* VM cannot reach here */
	WARN_ON(!is_in_host());

	/**
	 * Compatibility with old firmware, can be removed
	 * when no longer support SW3231.
	 */
	if (!sunway_bios_version)
		cpld_write(0x64, 0x00, 0xc3);
	else if (efi_enabled(EFI_RUNTIME_SERVICES))
		efi_reboot(reboot_mode, NULL);

	while (true)
		arch_cpu_idle();
}

void machine_power_off(void)
static int vm_restart(struct sys_off_data *data)
{
#ifdef CONFIG_SMP
	preempt_disable();
	smp_send_stop();
#endif
	pm_power_off();
	hcall(HCALL_SET_CLOCKEVENT, 0, 0, 0);
	hcall(HCALL_RESTART, 0, 0, 0);
	mb();

	return NOTIFY_DONE;
}

void machine_restart(char *command)
static int vm_power_off(struct sys_off_data *data)
{
#ifdef CONFIG_SMP
	preempt_disable();
	smp_send_stop();
#endif
	/* No point in taking interrupts anymore. */
	local_irq_disable();
	hcall(HCALL_SET_CLOCKEVENT, 0, 0, 0);
	hcall(HCALL_SHUTDOWN, 0, 0, 0);
	mb();

	do_kernel_restart(command);
	pm_restart();
	return NOTIFY_DONE;
}

static int __init sw64_reboot_setup(void)
static int __init vm_power_init(void)
{
	pm_restart = default_restart;
	pm_power_off = default_poweroff;
	pm_halt = default_halt;
	struct sys_off_handler *handler;

	if (is_in_host())
		return 0;

	handler = register_sys_off_handler(SYS_OFF_MODE_RESTART,
			SYS_OFF_PRIO_DEFAULT, vm_restart, NULL);
	if (WARN_ON(IS_ERR(handler)))
		return PTR_ERR(handler);

	handler = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
			SYS_OFF_PRIO_DEFAULT, vm_power_off, NULL);
	if (WARN_ON(IS_ERR(handler)))
		return PTR_ERR(handler);

	return 0;
}
arch_initcall(sw64_reboot_setup);
arch_initcall(vm_power_init);
Loading