From 9a61ddc4a1adbb7e102bfdd3655afb86f2b216b2 Mon Sep 17 00:00:00 2001 From: Dai Xin Date: Tue, 13 Dec 2022 18:52:26 +0000 Subject: [PATCH] sw64: refactor platform dependent codes Sunway inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5XTK7 -------------------------------- This commit includes changes as follows: - Refactor machine power interface functions similarly to other architectures. - Keep legacy suspend implementation which may be deprecated some day. Signed-off-by: Dai Xin Reviewed-by: He Sheng Signed-off-by: Gu Zitao --- arch/sw_64/Kconfig | 7 +++ arch/sw_64/include/asm/platform.h | 12 ++++- arch/sw_64/kernel/smp.c | 5 +- arch/sw_64/platform/platform_xuelang.c | 60 --------------------- drivers/platform/Makefile | 1 + drivers/platform/sw64/Makefile | 2 + drivers/platform/sw64/legacy_xuelang.c | 74 ++++++++++++++++++++++++++ 7 files changed, 96 insertions(+), 65 deletions(-) create mode 100644 drivers/platform/sw64/Makefile create mode 100644 drivers/platform/sw64/legacy_xuelang.c diff --git a/arch/sw_64/Kconfig b/arch/sw_64/Kconfig index 832e7a7a02e0..53b2226f8516 100644 --- a/arch/sw_64/Kconfig +++ b/arch/sw_64/Kconfig @@ -254,6 +254,13 @@ config PLATFORM_XUELANG endchoice +config LEGACY_XUELANG + bool "Xuelang Reset Interface" + depends on SW64_CHIP3 + help + This enables the legacy reset driver for SW64 chip3 CRBs. This interface + as a temporary solution will be deprecated in the future. + config MIGHT_HAVE_PC_SERIO bool "Use PC serio device i8042" select ARCH_MIGHT_HAVE_PC_SERIO diff --git a/arch/sw_64/include/asm/platform.h b/arch/sw_64/include/asm/platform.h index 59418bba9de7..5cbf634fb34e 100644 --- a/arch/sw_64/include/asm/platform.h +++ b/arch/sw_64/include/asm/platform.h @@ -2,8 +2,10 @@ #ifndef _ASM_SW64_PLATFORM_H #define _ASM_SW64_PLATFORM_H +#include +#include + struct sw64_platform_ops { - void (*kill_arch)(int mode); void __iomem *(*ioportmap)(unsigned long); void (*register_platform_devices)(void); void (*ops_fixup)(void); @@ -14,4 +16,12 @@ extern struct sw64_platform_ops *sw64_platform; extern struct sw64_platform_ops xuelang_ops; +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); + #endif /* _ASM_SW64_PLATFORM_H */ diff --git a/arch/sw_64/kernel/smp.c b/arch/sw_64/kernel/smp.c index 79dc334c3375..1bf289b6a89e 100644 --- a/arch/sw_64/kernel/smp.c +++ b/arch/sw_64/kernel/smp.c @@ -366,10 +366,7 @@ void handle_ipi(struct pt_regs *regs) case IPI_CPU_STOP: local_irq_disable(); - pr_crit("other core panic, now halt...\n"); - while (1) - asm("nop"); - halt(); + asm("halt"); default: pr_crit("Unknown IPI on CPU %d: %lu\n", this_cpu, which); diff --git a/arch/sw_64/platform/platform_xuelang.c b/arch/sw_64/platform/platform_xuelang.c index ae8179b53b4c..28c30cddcff2 100644 --- a/arch/sw_64/platform/platform_xuelang.c +++ b/arch/sw_64/platform/platform_xuelang.c @@ -1,65 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include - -static void vt_mode_kill_arch(int mode) -{ - hcall(HCALL_SET_CLOCKEVENT, 0, 0, 0); - - switch (mode) { - case LINUX_REBOOT_CMD_RESTART: - hcall(HCALL_RESTART, 0, 0, 0); - mb(); - break; - case LINUX_REBOOT_CMD_HALT: - case LINUX_REBOOT_CMD_POWER_OFF: - hcall(HCALL_SHUTDOWN, 0, 0, 0); - mb(); - break; - default: - break; - } -} - -extern void cpld_write(uint8_t slave_addr, uint8_t reg, uint8_t data); - -static void xuelang_kill_arch(int mode) -{ - struct pci_dev *pdev; - struct pci_controller *hose; - int val; - - if (is_in_host()) { - switch (mode) { - case LINUX_REBOOT_CMD_RESTART: - pdev = pci_get_device(PCI_VENDOR_ID_JMICRON, - 0x0585, NULL); - if (pdev) { - hose = (struct pci_controller *)pdev->sysdata; - val = read_rc_conf(hose->node, hose->index, - RC_PORT_LINK_CTL); - write_rc_conf(hose->node, hose->index, - RC_PORT_LINK_CTL, val | 0x8); - write_rc_conf(hose->node, hose->index, - RC_PORT_LINK_CTL, val); - } - - cpld_write(0x64, 0x00, 0xc3); - mb(); - break; - case LINUX_REBOOT_CMD_HALT: - case LINUX_REBOOT_CMD_POWER_OFF: - cpld_write(0x64, 0x00, 0xf0); - mb(); - break; - default: - break; - } - } else { - vt_mode_kill_arch(mode); - } -} static inline void __iomem *xuelang_ioportmap(unsigned long addr) { @@ -74,7 +15,6 @@ static inline void __iomem *xuelang_ioportmap(unsigned long addr) } struct sw64_platform_ops xuelang_ops = { - .kill_arch = xuelang_kill_arch, .ioportmap = xuelang_ioportmap, .ops_fixup = sw64_init_noop, }; diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile index 6fda58c021ca..b91079eb3960 100644 --- a/drivers/platform/Makefile +++ b/drivers/platform/Makefile @@ -4,6 +4,7 @@ # obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_SW64) += sw64/ obj-$(CONFIG_MELLANOX_PLATFORM) += mellanox/ obj-$(CONFIG_MIPS) += mips/ obj-$(CONFIG_OLPC_EC) += olpc/ diff --git a/drivers/platform/sw64/Makefile b/drivers/platform/sw64/Makefile new file mode 100644 index 000000000000..8d166464e4c9 --- /dev/null +++ b/drivers/platform/sw64/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_LEGACY_XUELANG) += legacy_xuelang.o diff --git a/drivers/platform/sw64/legacy_xuelang.c b/drivers/platform/sw64/legacy_xuelang.c new file mode 100644 index 000000000000..cf78d1088f11 --- /dev/null +++ b/drivers/platform/sw64/legacy_xuelang.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +#include +#include + +static void vt_mode_kill_arch(int mode) +{ + hcall(HCALL_SET_CLOCKEVENT, 0, 0, 0); + + switch (mode) { + case LINUX_REBOOT_CMD_RESTART: + hcall(HCALL_RESTART, 0, 0, 0); + mb(); + break; + case LINUX_REBOOT_CMD_HALT: + case LINUX_REBOOT_CMD_POWER_OFF: + hcall(HCALL_SHUTDOWN, 0, 0, 0); + mb(); + break; + default: + break; + } +} + +void sw64_halt(void) +{ + if (is_in_host()) + cpld_write(0x64, 0x00, 0xf0); + else + vt_mode_kill_arch(LINUX_REBOOT_CMD_HALT); +} + +void sw64_poweroff(void) +{ + if (is_in_host()) + cpld_write(0x64, 0x00, 0xf0); + else + vt_mode_kill_arch(LINUX_REBOOT_CMD_POWER_OFF); +} + +void sw64_restart(void) +{ + struct pci_dev *pdev; + struct pci_controller *hose; + int val; + + if (is_in_host()) { + pdev = pci_get_device(PCI_VENDOR_ID_JMICRON, + 0x0585, NULL); + if (pdev) { + hose = (struct pci_controller *)pdev->sysdata; + val = read_rc_conf(hose->node, hose->index, + RC_PORT_LINK_CTL); + write_rc_conf(hose->node, hose->index, + RC_PORT_LINK_CTL, val | 0x8); + write_rc_conf(hose->node, hose->index, + RC_PORT_LINK_CTL, val); + } + cpld_write(0x64, 0x00, 0xc3); + } else + vt_mode_kill_arch(LINUX_REBOOT_CMD_RESTART); +} + +static int sw64_reset_init(void) +{ + pm_restart = sw64_restart; + pm_power_off = sw64_poweroff; + pm_halt = sw64_halt; + + return 0; +} +subsys_initcall(sw64_reset_init); -- GitLab