// SPDX-License-Identifier: GPL-2.0 /* * T-HEAD TH1520 AON Firmware Reboot Driver * * Copyright (c) 2025 Icenowy Zheng */ #include #include #include #include #include #include #include #define TH1520_AON_REBOOT_PRIORITY 200 struct th1520_aon_msg_empty_body { struct th1520_aon_rpc_msg_hdr hdr; u16 reserved[12]; } __packed __aligned(1); static int th1520_aon_pwroff_handler(struct sys_off_data *data) { struct th1520_aon_chan *aon_chan = data->cb_data; struct th1520_aon_msg_empty_body msg = {}; msg.hdr.svc = TH1520_AON_RPC_SVC_WDG; msg.hdr.func = TH1520_AON_WDG_FUNC_POWER_OFF; msg.hdr.size = TH1520_AON_RPC_MSG_NUM; th1520_aon_call_rpc(aon_chan, &msg); return NOTIFY_DONE; } static int th1520_aon_restart_handler(struct sys_off_data *data) { struct th1520_aon_chan *aon_chan = data->cb_data; struct th1520_aon_msg_empty_body msg = {}; msg.hdr.svc = TH1520_AON_RPC_SVC_WDG; msg.hdr.func = TH1520_AON_WDG_FUNC_RESTART; msg.hdr.size = TH1520_AON_RPC_MSG_NUM; th1520_aon_call_rpc(aon_chan, &msg); return NOTIFY_DONE; } static int th1520_aon_reboot_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) { struct device *dev = &adev->dev; int ret; /* Expect struct th1520_aon_chan to be passed via platform_data */ ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF, TH1520_AON_REBOOT_PRIORITY, th1520_aon_pwroff_handler, adev->dev.platform_data); if (ret) { dev_err(dev, "Failed to register power off handler\n"); return ret; } ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, TH1520_AON_REBOOT_PRIORITY, th1520_aon_restart_handler, adev->dev.platform_data); if (ret) { dev_err(dev, "Failed to register restart handler\n"); return ret; } return 0; } static const struct auxiliary_device_id th1520_aon_reboot_id_table[] = { { .name = "th1520_pm_domains.reboot" }, {}, }; MODULE_DEVICE_TABLE(auxiliary, th1520_aon_reboot_id_table); static struct auxiliary_driver th1520_aon_reboot_driver = { .driver = { .name = "th1520-aon-reboot", }, .probe = th1520_aon_reboot_probe, .id_table = th1520_aon_reboot_id_table, }; module_auxiliary_driver(th1520_aon_reboot_driver); MODULE_AUTHOR("Icenowy Zheng "); MODULE_DESCRIPTION("T-HEAD TH1520 AON-firmware-based reboot driver"); MODULE_LICENSE("GPL");