/* * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2026 Metanoia Communications Inc. * */ #include #include #include #include #include #define SWRSTREQ_CTRL_REG_OFFSET 0x00 #define SWRSTREQ_REG_OFFSET 0x04 struct reset_metanoia_data { u8 *reg_base; }; static struct reset_metanoia_data reset_data; static int metanoia_system_reset_check(u32 type, u32 reason) { switch (type) { case SBI_SRST_RESET_TYPE_WARM_REBOOT: case SBI_SRST_RESET_TYPE_COLD_REBOOT: return 1; case SBI_SRST_RESET_TYPE_SHUTDOWN: default: return 0; } } static void metanoia_system_reset(u32 type, u32 reason) { writew(0x1, reset_data.reg_base + SWRSTREQ_CTRL_REG_OFFSET); writew(0x1, reset_data.reg_base + SWRSTREQ_REG_OFFSET); } static struct sbi_system_reset_device metanoia_reset = { .name = "metanoia-mt2824-reboot", .system_reset_check = metanoia_system_reset_check, .system_reset = metanoia_system_reset, }; static int metanoia_reset_init(const void *fdt, int nodeoff, const struct fdt_match *match) { u64 reg_addr; int rc; rc = fdt_get_node_addr_size(fdt, nodeoff, 0, ®_addr, NULL); if (rc < 0 || !reg_addr) return SBI_ENODEV; reset_data.reg_base = (u8 *)(ulong)reg_addr; sbi_system_reset_add_device(&metanoia_reset); return 0; } static const struct fdt_match metanoia_reset_match[] = { { .compatible = "metanoia,mt2824-reboot" }, { /* sentinel */ } }; const struct fdt_driver fdt_reset_metanoia = { .match_table = metanoia_reset_match, .init = metanoia_reset_init, };