summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-16 18:11:01 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-16 18:11:01 +0300
commit090748e62f57a80286b2fcc32fe2be069f891200 (patch)
tree21ee5767113a51b8010de9979143e2dcf9ff1c89
parent948ef73f7ec39622ebd27bba4e94d78a983109f6 (diff)
parent56f295853f38d3202c20fd0d98939e7a4c56c3fb (diff)
downloadlinux-090748e62f57a80286b2fcc32fe2be069f891200.tar.xz
Merge tag 'm68k-for-v7.1-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
Pull m68k updates from Geert Uytterhoeven: - Add support for QEMU virt-ctrl, and use it for system reset and power off on the virt platform - defconfig updates - Miscellaneous fixes and improvements * tag 'm68k-for-v7.1-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: m68k: virt: Switch to qemu-virt-ctrl driver power: reset: Add QEMU virt-ctrl driver m68k: defconfig: Update defconfigs for v7.0-rc1 m68k: emu: Replace unbounded sprintf() in nfhd_init_one() m68k: uapi: Add ucontext.h m68k: defconfig: hp300: Enable monochrome and 16-color linux logos m68k: q40: Remove commented out code
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/m68k/Kconfig.machine2
-rw-r--r--arch/m68k/configs/amiga_defconfig2
-rw-r--r--arch/m68k/configs/apollo_defconfig2
-rw-r--r--arch/m68k/configs/atari_defconfig2
-rw-r--r--arch/m68k/configs/hp300_defconfig4
-rw-r--r--arch/m68k/configs/mac_defconfig2
-rw-r--r--arch/m68k/configs/multi_defconfig2
-rw-r--r--arch/m68k/configs/q40_defconfig2
-rw-r--r--arch/m68k/emu/nfblock.c3
-rw-r--r--arch/m68k/include/uapi/asm/ucontext.h (renamed from arch/m68k/include/asm/ucontext.h)5
-rw-r--r--arch/m68k/q40/config.c15
-rw-r--r--arch/m68k/virt/config.c42
-rw-r--r--arch/m68k/virt/platform.c20
-rw-r--r--drivers/power/reset/Kconfig10
-rw-r--r--drivers/power/reset/Makefile1
-rw-r--r--drivers/power/reset/qemu-virt-ctrl.c122
17 files changed, 178 insertions, 64 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 41f4600e8a03..06a8c74577aa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21592,6 +21592,12 @@ S: Maintained
F: drivers/firmware/qemu_fw_cfg.c
F: include/uapi/linux/qemu_fw_cfg.h
+QEMU VIRT MACHINE SYSTEM CONTROLLER DRIVER
+M: Kuan-Wei Chiu <visitorckw@gmail.com>
+L: linux-pm@vger.kernel.org
+S: Maintained
+F: drivers/power/reset/qemu-virt-ctrl.c
+
QLOGIC QL41xxx FCOE DRIVER
M: Saurav Kashyap <skashyap@marvell.com>
M: Javed Hasan <jhasan@marvell.com>
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index de39f23b180e..624e6b27f394 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -133,6 +133,8 @@ config VIRT
select GOLDFISH_TIMER
select GOLDFISH_TTY
select M68040
+ select POWER_RESET
+ select POWER_RESET_QEMU_VIRT_CTRL
select RTC_CLASS
select RTC_DRV_GOLDFISH
select TTY
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 0f85975abc63..47e48c18e55c 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -386,6 +386,8 @@ CONFIG_FB_FM2=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
CONFIG_SOUND=m
CONFIG_DMASOUND_PAULA=m
CONFIG_HID=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index ca08b130945a..161586d611ab 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -344,7 +344,7 @@ CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_MONO=y
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_HID=m
CONFIG_HIDRAW=y
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index a80b5517c242..c13c6deeac22 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -366,6 +366,8 @@ CONFIG_FB=y
CONFIG_FB_ATARI=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
CONFIG_SOUND=m
CONFIG_DMASOUND_ATARI=m
CONFIG_HID=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 7a54b00082dd..58288f83349d 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -346,8 +346,8 @@ CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
CONFIG_HID=m
CONFIG_HIDRAW=y
CONFIG_UHID=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 6916f55c7c9c..abb369fd1f55 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -365,6 +365,8 @@ CONFIG_FB_VALKYRIE=y
CONFIG_FB_MAC=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
CONFIG_HID=m
CONFIG_HIDRAW=y
CONFIG_UHID=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index bd08f46762f4..cb8de979700f 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -445,6 +445,8 @@ CONFIG_FB_MAC=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
CONFIG_SOUND=m
CONFIG_DMASOUND_ATARI=m
CONFIG_DMASOUND_PAULA=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 693fcc7fa8fb..d48f3cf5285b 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -353,6 +353,8 @@ CONFIG_PTP_1588_CLOCK=m
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
CONFIG_SOUND=m
CONFIG_DMASOUND_Q40=m
CONFIG_HID=m
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 93536cf2a38e..fa6256c5af22 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -132,7 +132,8 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
dev->disk->minors = 16;
dev->disk->fops = &nfhd_ops;
dev->disk->private_data = dev;
- sprintf(dev->disk->disk_name, "nfhd%u", dev_id);
+ snprintf(dev->disk->disk_name, sizeof(dev->disk->disk_name), "nfhd%u",
+ dev_id);
set_capacity(dev->disk, (sector_t)blocks * (bsize / 512));
err = add_disk(dev->disk);
if (err)
diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/uapi/asm/ucontext.h
index 1523a8e5ff22..ffac691604b4 100644
--- a/arch/m68k/include/asm/ucontext.h
+++ b/arch/m68k/include/uapi/asm/ucontext.h
@@ -1,7 +1,10 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _M68K_UCONTEXT_H
#define _M68K_UCONTEXT_H
+#include <asm/sigcontext.h>
+#include <asm/signal.h>
+
typedef int greg_t;
#define NGREG 18
typedef greg_t gregset_t[NGREG];
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 5a4258697622..ed59a742baae 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -74,7 +74,6 @@ static int __init q40_debug_setup(char *arg)
{
/* useful for early debugging stages - writes kernel messages into SRAM */
if (MACH_IS_Q40 && !strncmp(arg, "mem", 3)) {
- /*pr_info("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/
_cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4;
register_console(&q40_console_driver);
}
@@ -83,20 +82,6 @@ static int __init q40_debug_setup(char *arg)
early_param("debug", q40_debug_setup);
-#if 0
-void printq40(char *str)
-{
- int l = strlen(str);
- char *p = q40_mem_cptr;
-
- while (l-- > 0 && _cpleft-- > 0) {
- *p = *str++;
- p += 4;
- }
- q40_mem_cptr = p;
-}
-#endif
-
static int halted;
#ifdef CONFIG_HEARTBEAT
diff --git a/arch/m68k/virt/config.c b/arch/m68k/virt/config.c
index 632ba200ad42..b338e2a8da6a 100644
--- a/arch/m68k/virt/config.c
+++ b/arch/m68k/virt/config.c
@@ -13,18 +13,6 @@
struct virt_booter_data virt_bi_data;
-#define VIRT_CTRL_REG_FEATURES 0x00
-#define VIRT_CTRL_REG_CMD 0x04
-
-static struct resource ctrlres;
-
-enum {
- CMD_NOOP,
- CMD_RESET,
- CMD_HALT,
- CMD_PANIC,
-};
-
static void virt_get_model(char *str)
{
/* str is 80 characters long */
@@ -33,25 +21,9 @@ static void virt_get_model(char *str)
(u8)(virt_bi_data.qemu_version >> 16),
(u8)(virt_bi_data.qemu_version >> 8));
}
-
-static void virt_halt(void)
-{
- void __iomem *base = (void __iomem *)virt_bi_data.ctrl.mmio;
-
- iowrite32be(CMD_HALT, base + VIRT_CTRL_REG_CMD);
- local_irq_disable();
- while (1)
- ;
-}
-
static void virt_reset(void)
{
- void __iomem *base = (void __iomem *)virt_bi_data.ctrl.mmio;
-
- iowrite32be(CMD_RESET, base + VIRT_CTRL_REG_CMD);
- local_irq_disable();
- while (1)
- ;
+ do_kernel_restart(NULL);
}
/*
@@ -113,20 +85,8 @@ void __init config_virt(void)
virt_bi_data.tty.mmio);
setup_earlycon(earlycon);
- ctrlres = (struct resource)
- DEFINE_RES_MEM_NAMED(virt_bi_data.ctrl.mmio, 0x100,
- "virtctrl");
-
- if (request_resource(&iomem_resource, &ctrlres)) {
- pr_err("Cannot allocate virt controller resource\n");
- return;
- }
-
mach_init_IRQ = virt_init_IRQ;
mach_sched_init = virt_sched_init;
mach_get_model = virt_get_model;
mach_reset = virt_reset;
- mach_halt = virt_halt;
-
- register_platform_power_off(virt_halt);
}
diff --git a/arch/m68k/virt/platform.c b/arch/m68k/virt/platform.c
index 1560c4140ab9..764f556b4b32 100644
--- a/arch/m68k/virt/platform.c
+++ b/arch/m68k/virt/platform.c
@@ -30,7 +30,10 @@ static int __init virt_platform_init(void)
DEFINE_RES_MEM(virt_bi_data.rtc.mmio + 0x1000, 0x1000),
DEFINE_RES_IRQ(virt_bi_data.rtc.irq + 1),
};
- struct platform_device *pdev1, *pdev2;
+ const struct resource virt_ctrl_res[] = {
+ DEFINE_RES_MEM(virt_bi_data.ctrl.mmio, 0x100),
+ };
+ struct platform_device *pdev1, *pdev2, *pdev3;
struct platform_device *pdevs[VIRTIO_BUS_NB];
unsigned int i;
int ret = 0;
@@ -57,19 +60,30 @@ static int __init virt_platform_init(void)
goto err_unregister_tty;
}
+ pdev3 = platform_device_register_simple("qemu-virt-ctrl",
+ PLATFORM_DEVID_NONE,
+ virt_ctrl_res,
+ ARRAY_SIZE(virt_ctrl_res));
+ if (IS_ERR(pdev3)) {
+ ret = PTR_ERR(pdev3);
+ goto err_unregister_rtc;
+ }
+
for (i = 0; i < VIRTIO_BUS_NB; i++) {
pdevs[i] = virt_virtio_init(i);
if (IS_ERR(pdevs[i])) {
ret = PTR_ERR(pdevs[i]);
- goto err_unregister_rtc_virtio;
+ goto err_unregister_virtio;
}
}
return 0;
-err_unregister_rtc_virtio:
+err_unregister_virtio:
while (i > 0)
platform_device_unregister(pdevs[--i]);
+ platform_device_unregister(pdev3);
+err_unregister_rtc:
platform_device_unregister(pdev2);
err_unregister_tty:
platform_device_unregister(pdev1);
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index f6c1bcbb57de..99e3334726a5 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -354,4 +354,14 @@ config POWER_MLXBF
help
This driver supports reset or low power mode handling for Mellanox BlueField.
+config POWER_RESET_QEMU_VIRT_CTRL
+ tristate "QEMU Virt Machine System Controller"
+ depends on HAS_IOMEM
+ help
+ This driver supports the system reset and power off functionality
+ provided by the QEMU 'virt-ctrl' device.
+
+ Say Y here if you are running Linux on a QEMU virtual machine that
+ provides this controller, such as the m68k virt machine.
+
endif
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0e4ae6f6b5c5..d7ae97241a83 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -41,3 +41,4 @@ obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
obj-$(CONFIG_POWER_MLXBF) += pwr-mlxbf.o
+obj-$(CONFIG_POWER_RESET_QEMU_VIRT_CTRL) += qemu-virt-ctrl.o
diff --git a/drivers/power/reset/qemu-virt-ctrl.c b/drivers/power/reset/qemu-virt-ctrl.c
new file mode 100644
index 000000000000..01409dfe2265
--- /dev/null
+++ b/drivers/power/reset/qemu-virt-ctrl.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * QEMU Virt Machine System Controller Driver
+ *
+ * Copyright (C) 2026 Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+
+/* Registers */
+#define VIRT_CTRL_REG_FEATURES 0x00
+#define VIRT_CTRL_REG_CMD 0x04
+
+/* Commands */
+#define CMD_NOOP 0
+#define CMD_RESET 1
+#define CMD_HALT 2
+#define CMD_PANIC 3
+
+struct qemu_virt_ctrl {
+ void __iomem *base;
+ struct notifier_block reboot_nb;
+};
+
+static inline void virt_ctrl_write32(u32 val, void __iomem *addr)
+{
+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+ iowrite32be(val, addr);
+ else
+ iowrite32(val, addr);
+}
+
+static int qemu_virt_ctrl_power_off(struct sys_off_data *data)
+{
+ struct qemu_virt_ctrl *ctrl = data->cb_data;
+
+ virt_ctrl_write32(CMD_HALT, ctrl->base + VIRT_CTRL_REG_CMD);
+
+ return NOTIFY_DONE;
+}
+
+static int qemu_virt_ctrl_restart(struct sys_off_data *data)
+{
+ struct qemu_virt_ctrl *ctrl = data->cb_data;
+
+ virt_ctrl_write32(CMD_RESET, ctrl->base + VIRT_CTRL_REG_CMD);
+
+ return NOTIFY_DONE;
+}
+
+static int qemu_virt_ctrl_reboot_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct qemu_virt_ctrl *ctrl = container_of(nb, struct qemu_virt_ctrl, reboot_nb);
+
+ if (action == SYS_HALT)
+ virt_ctrl_write32(CMD_HALT, ctrl->base + VIRT_CTRL_REG_CMD);
+
+ return NOTIFY_DONE;
+}
+
+static int qemu_virt_ctrl_probe(struct platform_device *pdev)
+{
+ struct qemu_virt_ctrl *ctrl;
+ int ret;
+
+ ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
+ if (!ctrl)
+ return -ENOMEM;
+
+ ctrl->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ctrl->base))
+ return PTR_ERR(ctrl->base);
+
+ ret = devm_register_sys_off_handler(&pdev->dev,
+ SYS_OFF_MODE_RESTART,
+ SYS_OFF_PRIO_DEFAULT,
+ qemu_virt_ctrl_restart,
+ ctrl);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "cannot register restart handler\n");
+
+ ret = devm_register_sys_off_handler(&pdev->dev,
+ SYS_OFF_MODE_POWER_OFF,
+ SYS_OFF_PRIO_DEFAULT,
+ qemu_virt_ctrl_power_off,
+ ctrl);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "cannot register power-off handler\n");
+
+ ctrl->reboot_nb.notifier_call = qemu_virt_ctrl_reboot_notify;
+ ret = devm_register_reboot_notifier(&pdev->dev, &ctrl->reboot_nb);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "cannot register reboot notifier\n");
+
+ return 0;
+}
+
+static const struct platform_device_id qemu_virt_ctrl_id[] = {
+ { "qemu-virt-ctrl", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, qemu_virt_ctrl_id);
+
+static struct platform_driver qemu_virt_ctrl_driver = {
+ .probe = qemu_virt_ctrl_probe,
+ .driver = {
+ .name = "qemu-virt-ctrl",
+ },
+ .id_table = qemu_virt_ctrl_id,
+};
+module_platform_driver(qemu_virt_ctrl_driver);
+
+MODULE_AUTHOR("Kuan-Wei Chiu <visitorckw@gmail.com>");
+MODULE_DESCRIPTION("QEMU Virt Machine System Controller Driver");
+MODULE_LICENSE("GPL");