| /* |
| * SPDX-License-Identifier: BSD-2-Clause |
| * |
| * Copyright (c) 2026 Metanoia Communications Inc. |
| * |
| */ |
| |
| #include <sbi/riscv_io.h> |
| #include <sbi/sbi_platform.h> |
| #include <sbi/sbi_system.h> |
| #include <sbi_utils/fdt/fdt_helper.h> |
| #include <sbi_utils/fdt/fdt_driver.h> |
| |
| #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, |
| }; |