[PATCH 1/5] drivers/virt: introduce csky_exit system poweroff driver

Thomas Weißschuh posted 5 patches 1 month, 4 weeks ago
[PATCH 1/5] drivers/virt: introduce csky_exit system poweroff driver
Posted by Thomas Weißschuh 1 month, 4 weeks ago
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@weissschuh.net>

---
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@weissschuh.net>
+ */
+
+#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@weissschuh.net>");
+MODULE_DESCRIPTION("C-SKY QEMU shutdown driver");
+MODULE_LICENSE("GPL");

-- 
2.46.2