The C-SKY architecture does not support ACPI and no other standardized mechanism for system poweroff. On QEMU a virtual device "csky_exit" is available which can be used for poweroff. Add a driver for this virtual device. There are more features provided by the device but these are not required at this time and therefore not supported yet. Signed-off-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx> --- The OF compatible will never show up in a DTS file, it is synthesized by QEMU. Therefore I think it doesn't need explicit documentation. --- drivers/virt/Kconfig | 11 ++++++++++ drivers/virt/Makefile | 1 + drivers/virt/csky_exit.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig index d8c848cf09a6afad65b28be20f5fd7e90a0c5307..652546c52d2e00138a782b949672d47c5f5d2189 100644 --- a/drivers/virt/Kconfig +++ b/drivers/virt/Kconfig @@ -41,6 +41,17 @@ config FSL_HV_MANAGER 4) A kernel interface for receiving callbacks when a managed partition shuts down. +config CSKY_EXIT + tristate "C-SKY QEMU shutdown driver" + depends on OF + depends on CSKY || COMPILE_TEST + help + This driver supports system shutdown via the virtual csky_exit device + provided by QEMU. + + To compile this driver as a module, choose M here: the module will + be called csky_exit. + source "drivers/virt/vboxguest/Kconfig" source "drivers/virt/nitro_enclaves/Kconfig" diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile index f29901bd782058d3552cdec2c2128ad47ce6fe27..5c62db9fbfa501a31c87c4902f835db91633daeb 100644 --- a/drivers/virt/Makefile +++ b/drivers/virt/Makefile @@ -3,6 +3,7 @@ # Makefile for drivers that support virtualization # +obj-$(CONFIG_CSKY_EXIT) += csky_exit.o obj-$(CONFIG_FSL_HV_MANAGER) += fsl_hypervisor.o obj-$(CONFIG_VMGENID) += vmgenid.o obj-y += vboxguest/ diff --git a/drivers/virt/csky_exit.c b/drivers/virt/csky_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..6f42eb74071ab9ac1b7e9ef03b32f9ba0ef2cf26 --- /dev/null +++ b/drivers/virt/csky_exit.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * C-SKY QEMU shutdown driver + * + * Copyright (C) 2024 Thomas Weißschuh <linux@xxxxxxxxxxxxxx> + */ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/reboot.h> +#include <linux/types.h> + +#define CSKY_EXIT_COMMAND_EXIT 0 + +static void csky_exit_command(void __iomem *base, u32 command, u64 value) +{ + writew(value, base + command); +} + +static int csky_exit_poweroff(struct sys_off_data *data) +{ + csky_exit_command(data->cb_data, CSKY_EXIT_COMMAND_EXIT, 0); + return 0; +} + +static int csky_exit_probe(struct platform_device *pdev) +{ + void __iomem *base; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_PLATFORM + 1, + csky_exit_poweroff, base); +} + +static const struct of_device_id csky_exit_match[] = { + { .compatible = "csky,qemu-exit" }, + { } +}; +MODULE_DEVICE_TABLE(of, csky_exit_match); + +static struct platform_driver csky_exit_driver = { + .driver.name = "csky_exit", + .driver.of_match_table = csky_exit_match, + .probe = csky_exit_probe, +}; +module_platform_driver(csky_exit_driver); + +MODULE_AUTHOR("Thomas Weißschuh <linux@xxxxxxxxxxxxxx>"); +MODULE_DESCRIPTION("C-SKY QEMU shutdown driver"); +MODULE_LICENSE("GPL"); -- 2.46.2