Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

driver: reset: th1520-aon: add driver for poweroff/reboot via AON FW

This driver implements poweroff/reboot support for T-Head TH1520 SoCs
running the AON firmware by sending a message to the AON firmware's WDG
part.

This is a auxiliary device driver, and expects the AON channel to be
passed via the platform_data of the auxiliary device.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Icenowy Zheng and committed by
Ulf Hansson
2d81a24a c60934d5

+107
+1
MAINTAINERS
··· 21732 21732 F: drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c 21733 21733 F: drivers/pinctrl/pinctrl-th1520.c 21734 21734 F: drivers/pmdomain/thead/ 21735 + F: drivers/power/reset/th1520-aon-reboot.c 21735 21736 F: drivers/power/sequencing/pwrseq-thead-gpu.c 21736 21737 F: drivers/reset/reset-th1520.c 21737 21738 F: include/dt-bindings/clock/thead,th1520-clk-ap.h
+7
drivers/power/reset/Kconfig
··· 225 225 help 226 226 Reset support for STMicroelectronics boards. 227 227 228 + config POWER_RESET_TH1520_AON 229 + tristate "T-Head TH1520 AON firmware poweroff and reset driver" 230 + depends on TH1520_PM_DOMAINS 231 + help 232 + This driver supports power-off and reset operations for T-Head 233 + TH1520 SoCs running the AON firmware. 234 + 228 235 config POWER_RESET_TORADEX_EC 229 236 tristate "Toradex Embedded Controller power-off and reset driver" 230 237 depends on ARCH_MXC || COMPILE_TEST
+1
drivers/power/reset/Makefile
··· 25 25 obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o 26 26 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o 27 27 obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o 28 + obj-$(CONFIG_POWER_RESET_TH1520_AON) += th1520-aon-reboot.o 28 29 obj-$(CONFIG_POWER_RESET_TORADEX_EC) += tdx-ec-poweroff.o 29 30 obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o 30 31 obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o
+98
drivers/power/reset/th1520-aon-reboot.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * T-HEAD TH1520 AON Firmware Reboot Driver 4 + * 5 + * Copyright (c) 2025 Icenowy Zheng <uwu@icenowy.me> 6 + */ 7 + 8 + #include <linux/auxiliary_bus.h> 9 + #include <linux/firmware/thead/thead,th1520-aon.h> 10 + #include <linux/module.h> 11 + #include <linux/notifier.h> 12 + #include <linux/of.h> 13 + #include <linux/reboot.h> 14 + #include <linux/slab.h> 15 + 16 + #define TH1520_AON_REBOOT_PRIORITY 200 17 + 18 + struct th1520_aon_msg_empty_body { 19 + struct th1520_aon_rpc_msg_hdr hdr; 20 + u16 reserved[12]; 21 + } __packed __aligned(1); 22 + 23 + static int th1520_aon_pwroff_handler(struct sys_off_data *data) 24 + { 25 + struct th1520_aon_chan *aon_chan = data->cb_data; 26 + struct th1520_aon_msg_empty_body msg = {}; 27 + 28 + msg.hdr.svc = TH1520_AON_RPC_SVC_WDG; 29 + msg.hdr.func = TH1520_AON_WDG_FUNC_POWER_OFF; 30 + msg.hdr.size = TH1520_AON_RPC_MSG_NUM; 31 + 32 + th1520_aon_call_rpc(aon_chan, &msg); 33 + 34 + return NOTIFY_DONE; 35 + } 36 + 37 + static int th1520_aon_restart_handler(struct sys_off_data *data) 38 + { 39 + struct th1520_aon_chan *aon_chan = data->cb_data; 40 + struct th1520_aon_msg_empty_body msg = {}; 41 + 42 + msg.hdr.svc = TH1520_AON_RPC_SVC_WDG; 43 + msg.hdr.func = TH1520_AON_WDG_FUNC_RESTART; 44 + msg.hdr.size = TH1520_AON_RPC_MSG_NUM; 45 + 46 + th1520_aon_call_rpc(aon_chan, &msg); 47 + 48 + return NOTIFY_DONE; 49 + } 50 + 51 + static int th1520_aon_reboot_probe(struct auxiliary_device *adev, 52 + const struct auxiliary_device_id *id) 53 + { 54 + struct device *dev = &adev->dev; 55 + int ret; 56 + 57 + /* Expect struct th1520_aon_chan to be passed via platform_data */ 58 + ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF, 59 + TH1520_AON_REBOOT_PRIORITY, 60 + th1520_aon_pwroff_handler, 61 + adev->dev.platform_data); 62 + 63 + if (ret) { 64 + dev_err(dev, "Failed to register power off handler\n"); 65 + return ret; 66 + } 67 + 68 + ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 69 + TH1520_AON_REBOOT_PRIORITY, 70 + th1520_aon_restart_handler, 71 + adev->dev.platform_data); 72 + 73 + if (ret) { 74 + dev_err(dev, "Failed to register restart handler\n"); 75 + return ret; 76 + } 77 + 78 + return 0; 79 + } 80 + 81 + static const struct auxiliary_device_id th1520_aon_reboot_id_table[] = { 82 + { .name = "th1520_pm_domains.reboot" }, 83 + {}, 84 + }; 85 + MODULE_DEVICE_TABLE(auxiliary, th1520_aon_reboot_id_table); 86 + 87 + static struct auxiliary_driver th1520_aon_reboot_driver = { 88 + .driver = { 89 + .name = "th1520-aon-reboot", 90 + }, 91 + .probe = th1520_aon_reboot_probe, 92 + .id_table = th1520_aon_reboot_id_table, 93 + }; 94 + module_auxiliary_driver(th1520_aon_reboot_driver); 95 + 96 + MODULE_AUTHOR("Icenowy Zheng <uwu@icenowy.me>"); 97 + MODULE_DESCRIPTION("T-HEAD TH1520 AON-firmware-based reboot driver"); 98 + MODULE_LICENSE("GPL");