blob: a5b24c5d43755be71029cf0270c3af477eca3138 [file] [log] [blame]
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/hwinfo.h>
#include <fsl_ocotp.h>
#include <fsl_power.h>
/* 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;
}