diff --git a/arch/arm/src/s32k1xx/Make.defs b/arch/arm/src/s32k1xx/Make.defs index f2cf13047b..9b343813f9 100644 --- a/arch/arm/src/s32k1xx/Make.defs +++ b/arch/arm/src/s32k1xx/Make.defs @@ -93,6 +93,10 @@ ifeq ($(CONFIG_S32K1XX_EEEPROM),y) CHIP_CSRCS += s32k1xx_eeeprom.c endif +ifeq ($(CONFIG_RESET_CAUSE_PROC_FS), y) +CHIP_CSRCS += s32k1xx_resetcause.c +endif + # Source files specific to the ARM CPU family and to the S32K1xx chip family ifeq ($(CONFIG_ARCH_CHIP_S32K11X),y) diff --git a/arch/arm/src/s32k1xx/s32k1xx_resetcause.c b/arch/arm/src/s32k1xx/s32k1xx_resetcause.c new file mode 100644 index 0000000000..f29e5d9af1 --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k1xx_resetcause.c @@ -0,0 +1,334 @@ +/**************************************************************************** + * arch/arm/src/s32k1xx/s32k1xx_resetcause.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arm_arch.h" + +#include "hardware/s32k1xx_rcm.h" + +#include "s32k1xx_resetcause.h" + +#include "arm_internal.h" + +#include /* Include last: has dependencies */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determines the size of an intermediate buffer that must be large enough + * to handle the longest line generated by this logic. + */ +#define RESETCAUSE_LINELEN 6 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes one open "file" */ + +struct resetcause_file_s +{ + struct procfs_file_s base; /* Base open file structure */ + unsigned int linesize; /* Number of valid characters in line[] */ + char line[RESETCAUSE_LINELEN]; /* Pre-allocated buffer for formatted lines */ + unsigned int resetcause; /* Variable representing the MCU specific reset cause */ +}; + +static unsigned int g_reset_cause = 0; + +#if defined(CONFIG_RESET_CAUSE_PROC_FS) && defined(CONFIG_FS_PROCFS) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* File system methods */ + +static int resetcause_open(FAR struct file *filep, + FAR const char *relpath, int oflags, mode_t mode); +static int resetcause_close(FAR struct file *filep); +static ssize_t resetcause_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); + +static int resetcause_dup(FAR const struct file *oldp, + FAR struct file *newp); + +static int resetcause_stat(FAR const char *relpath, + FAR struct stat *buf); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct procfs_operations resetcause_operations = +{ + resetcause_open, /* open */ + resetcause_close, /* close */ + resetcause_read, /* read */ + NULL, /* write */ + + resetcause_dup, /* dup */ + + NULL, /* opendir */ + NULL, /* closedir */ + NULL, /* readdir */ + NULL, /* rewinddir */ + + resetcause_stat /* stat */ +}; + +static const struct procfs_entry_s g_resetcause_procfs = +{ + "resetcause", &resetcause_operations +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: resetcause_open + ****************************************************************************/ + +static int resetcause_open(FAR struct file *filep, FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct resetcause_file_s *attr; + + finfo("Open '%s'\n", relpath); + + /* PROCFS is read-only. Any attempt to open with any kind of write + * access is not permitted. + * + * REVISIT: Write-able proc files could be quite useful. + */ + + if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0) + { + ferr("ERROR: Only O_RDONLY supported\n"); + return -EACCES; + } + + /* "resetcause" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "resetcause") != 0) + { + ferr("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* Allocate a container to hold the file attributes */ + + attr = kmm_zalloc(sizeof(struct resetcause_file_s)); + if (!attr) + { + ferr("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* Save the attributes as the open-specific state in filep->f_priv */ + + filep->f_priv = (FAR void *)attr; + return OK; +} + +/**************************************************************************** + * Name: resetcause_close + ****************************************************************************/ + +static int resetcause_close(FAR struct file *filep) +{ + FAR struct resetcause_file_s *attr; + + /* Recover our private data from the struct file instance */ + + attr = (FAR struct resetcause_file_s *)filep->f_priv; + DEBUGASSERT(attr); + + /* Release the file attributes structure */ + + kmm_free(attr); + filep->f_priv = NULL; + return OK; +} + +/**************************************************************************** + * Name: resetcause_read + ****************************************************************************/ + +static ssize_t resetcause_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct resetcause_file_s *attr; + size_t linesize; + off_t offset; + ssize_t ret; + + finfo("buffer=%p buflen=%d\n", buffer, (int)buflen); + + /* Recover our private data from the struct file instance */ + + attr = (FAR struct resetcause_file_s *)filep->f_priv; + DEBUGASSERT(attr); + + /* Get the resetcause value and store it */ + + attr->resetcause = g_reset_cause; + + /* Convert the resetcause to a string */ + + linesize = snprintf(attr->line, RESETCAUSE_LINELEN, + "0x%x", attr->resetcause); + + /* Save the linesize in case we are re-entered with f_pos > 0 */ + + attr->linesize = linesize; + + /* Transfer the system reset cause to user receive buffer */ + + offset = filep->f_pos; + + ret = procfs_memcpy(attr->line, attr->linesize, buffer, buflen, &offset); + + return ret; +} + +/**************************************************************************** + * Name: resetcause_dup + * + * Description: + * Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int resetcause_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct resetcause_file_s *oldattr; + FAR struct resetcause_file_s *newattr; + + finfo("Dup %p->%p\n", oldp, newp); + + /* Recover our private data from the old struct file instance */ + + oldattr = (FAR struct resetcause_file_s *)oldp->f_priv; + DEBUGASSERT(oldattr); + + /* Allocate a new container to hold the task and attribute selection */ + + newattr = kmm_malloc(sizeof(struct resetcause_file_s)); + if (!newattr) + { + ferr("ERROR: Failed to allocate file attributes\n"); + return -ENOMEM; + } + + /* The copy the file attributes from the old attributes to the new */ + + memcpy(newattr, oldattr, sizeof(struct resetcause_file_s)); + + /* Save the new attributes in the new file structure */ + + newp->f_priv = (FAR void *)newattr; + return OK; +} + +/**************************************************************************** + * Name: resetcause_stat + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int resetcause_stat(FAR const char *relpath, FAR struct stat *buf) +{ + /* "resetcause" is the only acceptable value for the relpath */ + + if (strcmp(relpath, "resetcause") != 0) + { + ferr("ERROR: relpath is '%s'\n", relpath); + return -ENOENT; + } + + /* "resetcause" is the name for a read-only file */ + + memset(buf, 0, sizeof(struct stat)); + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k1xx_resetcause_init + * + * Description: This function initializes the resetcause + * It will get the resetcause and store it + * + ****************************************************************************/ + +void s32k1xx_resetcause_init(void) +{ + uint32_t reset_cause_register = 0; + + /* get the reset cause */ + + reset_cause_register = getreg32(S32K1XX_RCM_SRS); + + /* save it in the global variable */ + + g_reset_cause = (unsigned int) reset_cause_register; +} + +/**************************************************************************** + * Name: s32k1xx_resetcause_initialize_procfs + * + * Description: This function registrates the reset cause as a proc fs + * Returns 0 if OK, error number otherwise + * + ****************************************************************************/ + +int s32k1xx_resetcause_initialize_procfs(void) +{ + return procfs_register(&g_resetcause_procfs); +} + +#endif /* CONFIG_RESET_CAUSE_PROC_FS && CONFIG_FS_PROCFS */ diff --git a/arch/arm/src/s32k1xx/s32k1xx_resetcause.h b/arch/arm/src/s32k1xx/s32k1xx_resetcause.h new file mode 100644 index 0000000000..8e20e25a9a --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k1xx_resetcause.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/arm/src/s32k1xx/s32k1xx_resetcause.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_S32K1XX_RESETCAUSE_H +#define __ARCH_ARM_SRC_S32K1XX_RESETCAUSE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k1xx_resetcause_init + * + * Description: This function initializes the resetcause + * It will get the resetcause and store it + * + ****************************************************************************/ + +void s32k1xx_resetcause_init(void); + +/**************************************************************************** + * Name: s32k1xx_resetcause_initialize_procfs + * + * Description: This function registrates the reset cause as a proc fs + * Returns 0 if OK, error number otherwise + * + ****************************************************************************/ + +int s32k1xx_resetcause_initialize_procfs(void); + +#endif /* __ARCH_ARM_SRC_S32K1XX_RESETCAUSE_H */