From 9607543496913a53d539aa7e6dcce9be90c87c83 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 5 Mar 2024 16:43:16 -0600 Subject: [PATCH] drivers: hwinfo: Add RW hwinfo driver Add RW hwinfo driver Signed-off-by: Declan Snyder --- drivers/hwinfo/CMakeLists.txt | 1 + drivers/hwinfo/Kconfig | 7 +++ drivers/hwinfo/hwinfo_rw61x.c | 88 +++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 drivers/hwinfo/hwinfo_rw61x.c diff --git a/drivers/hwinfo/CMakeLists.txt b/drivers/hwinfo/CMakeLists.txt index ab3b587dc75..2e7d91141be 100644 --- a/drivers/hwinfo/CMakeLists.txt +++ b/drivers/hwinfo/CMakeLists.txt @@ -28,3 +28,4 @@ zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM4L hwinfo_sam4l.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SMARTBOND hwinfo_smartbond.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_STM32 hwinfo_stm32.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_ANDES hwinfo_andes.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_RW61X hwinfo_rw61x.c) diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 81888bd3a78..467a36ad8af 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -192,4 +192,11 @@ config HWINFO_ANDES help Enable Andes hwinfo driver +config HWINFO_RW61X + bool "RW61X hwinfo" + default y + depends on SOC_SERIES_RW6XX + help + Enable RW61X hwinfo driver + endif diff --git a/drivers/hwinfo/hwinfo_rw61x.c b/drivers/hwinfo/hwinfo_rw61x.c new file mode 100644 index 00000000000..a5b24c5d437 --- /dev/null +++ b/drivers/hwinfo/hwinfo_rw61x.c @@ -0,0 +1,88 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +/* Because of the ROM clearing the reset register and using scratch register + * which cannot be cleared, we have to "fake" this to meet the hwinfo api. + * Technically all the reset causes are already cleared by the ROM, but we will + * still clear them ourselves on the first call to clear them by user. + */ +static bool reset_cleared; + +ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) +{ + uint32_t id_length = length; + + if (OCOTP_ReadUniqueID(buffer, &id_length)) { + return -EINVAL; + } + + return (ssize_t)id_length; +} + +int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) +{ + *supported = ( + RESET_SOFTWARE | + RESET_CPU_LOCKUP | + RESET_WATCHDOG | + RESET_SECURITY | + RESET_DEBUG | + RESET_HARDWARE + ); + + return 0; +} + +int z_impl_hwinfo_get_reset_cause(uint32_t *cause) +{ + if (reset_cleared) { + *cause = 0; + return 0; + } + + uint32_t reset_cause = POWER_GetResetCause(); + + switch (reset_cause) { + case kPOWER_ResetCauseSysResetReq: + *cause = RESET_SOFTWARE; + break; + case kPOWER_ResetCauseLockup: + *cause = RESET_CPU_LOCKUP; + break; + case kPOWER_ResetCauseWdt: + *cause = RESET_WATCHDOG; + break; + case kPOWER_ResetCauseApResetReq: + *cause = RESET_DEBUG; + break; + case kPOWER_ResetCauseCodeWdt: + case kPOWER_ResetCauseItrc: + *cause = RESET_SECURITY; + break; + case kPOWER_ResetCauseResetB: + *cause = RESET_HARDWARE; + break; + default: + *cause = 0; + break; + } + + return 0; +} + +int z_impl_hwinfo_clear_reset_cause(void) +{ + POWER_ClearResetCause(kPOWER_ResetCauseAll); + + reset_cleared = true; + + return 0; +}