You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
434 lines
9.8 KiB
434 lines
9.8 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2004-2021. All rights reserved.
|
|
* Description:wdg mpi layer api define
|
|
*/
|
|
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <pthread.h>
|
|
#include <linux/watchdog.h>
|
|
|
|
#include "soc_log.h"
|
|
#include "td_type.h"
|
|
#include "soc_errno.h"
|
|
|
|
static td_s32 g_wdg_dev_fd = 0;
|
|
#undef LOG_MODULE_ID
|
|
#define LOG_MODULE_ID SOC_ID_WDG
|
|
#define WATCHDOG_TIMEOUT_MAX 179000
|
|
#define WATCHDOG_TIMEOUT_MIN 1000
|
|
#define EXT_WDG_NUM 1
|
|
|
|
static pthread_mutex_t g_wdg_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
static td_void ext_wdg_lock(td_void)
|
|
{
|
|
(void)pthread_mutex_lock(&g_wdg_mutex);
|
|
}
|
|
|
|
static td_void ext_wdg_unlock(td_void)
|
|
{
|
|
(void)pthread_mutex_unlock(&g_wdg_mutex);
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_init
|
|
* Description: Init WDG devide
|
|
* Calls: EXT_WDG_Open
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_init(td_void)
|
|
{
|
|
td_s32 dev_fd = 0;
|
|
td_s32 ret = 0;
|
|
td_s32 option = 0;
|
|
|
|
ext_wdg_lock();
|
|
if (g_wdg_dev_fd > 0) {
|
|
ret = TD_SUCCESS;
|
|
goto exit;
|
|
}
|
|
|
|
dev_fd = open("/dev/watchdog", O_RDWR, 0);
|
|
if (dev_fd < 0) {
|
|
soc_log_err("open /dev/watchdog faild:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_INIT;
|
|
goto exit;
|
|
}
|
|
|
|
g_wdg_dev_fd = dev_fd;
|
|
|
|
option = WDIOS_DISABLECARD;
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_SETOPTIONS, &option);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("wdg disable failed:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_DISABLE;
|
|
close(dev_fd);
|
|
g_wdg_dev_fd = 0;
|
|
goto exit;
|
|
}
|
|
|
|
ret = TD_SUCCESS;
|
|
|
|
exit:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_deinit
|
|
* Description: Deinit WDG device
|
|
* Calls: EXT_WDG_Close
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_deinit(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ext_wdg_lock();
|
|
if (g_wdg_dev_fd <= 0) {
|
|
ret = TD_SUCCESS;
|
|
goto exit;
|
|
}
|
|
|
|
ret = close(g_wdg_dev_fd);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_fatal("DeInit WDG err:%d\n", ret);
|
|
ret = SOC_ERR_WDG_FAILED_DEINIT;
|
|
goto exit;
|
|
}
|
|
|
|
g_wdg_dev_fd = 0;
|
|
ret = TD_SUCCESS;
|
|
|
|
exit:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_get_num
|
|
* Description: get WDG device capability
|
|
* Calls: EXT_WDG_Enable
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_get_num(td_u32 *wdg_num)
|
|
{
|
|
td_s32 ret;
|
|
ext_wdg_lock();
|
|
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if (wdg_num == TD_NULL) {
|
|
soc_log_err("para value is null.\n");
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
*wdg_num = EXT_WDG_NUM;
|
|
ret = TD_SUCCESS;
|
|
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_enable
|
|
* Description: enable WDG device
|
|
* Calls: EXT_WDG_Enable
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_enable(td_u32 wdg_num)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 option;
|
|
|
|
ext_wdg_lock();
|
|
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if (wdg_num >= EXT_WDG_NUM) {
|
|
soc_log_err("Input parameter(wdg_num) invalid: %d\n", wdg_num);
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
option = WDIOS_ENABLECARD;
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_SETOPTIONS, &option);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("wdg enable failed:%d, ret:%d\n", errno, ret);
|
|
ret = SOC_ERR_WDG_FAILED_ENABLE;
|
|
goto err;
|
|
}
|
|
|
|
ret = TD_SUCCESS;
|
|
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_disable
|
|
* Description: disable WDG device
|
|
* Calls: EXT_WDG_Disable
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_disable(td_u32 wdg_num)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 option;
|
|
|
|
ext_wdg_lock();
|
|
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if (wdg_num >= EXT_WDG_NUM) {
|
|
soc_log_err("Input parameter(wdg_num) invalid: %d\n", wdg_num);
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
option = WDIOS_DISABLECARD;
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_SETOPTIONS, &option);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("wdg disable failed:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_DISABLE;
|
|
goto err;
|
|
}
|
|
|
|
ret = TD_SUCCESS;
|
|
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_set_timeout
|
|
* Description: set the time interval of feeding the WDG
|
|
* Calls: EXT_WDG_SetTimeout
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_set_timeout(td_u32 wdg_num, td_u32 value)
|
|
{
|
|
td_s32 ret = 0;
|
|
td_u32 value_in_sec;
|
|
|
|
ext_wdg_lock();
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if ((wdg_num >= EXT_WDG_NUM) ||
|
|
(value > WATCHDOG_TIMEOUT_MAX) ||
|
|
(value < WATCHDOG_TIMEOUT_MIN)) {
|
|
soc_log_err("Input parameter(value) invalid: %d\n", value);
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
/* convert ms to s */
|
|
value_in_sec = (value + 999) / 1000; /* 999 1000 convert ms to s */
|
|
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_SETTIMEOUT, &value_in_sec);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("wdg set timeout failed:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_SETTIMEOUT;
|
|
goto err;
|
|
}
|
|
|
|
ret = TD_SUCCESS;
|
|
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_get_timeout
|
|
* Description: get the time interval of feeding the WDG
|
|
* Calls: EXT_WDG_GetTimeout
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_get_timeout(td_u32 wdg_num, td_u32 *value)
|
|
{
|
|
td_s32 ret = 0;
|
|
td_u32 temp_value = 0;
|
|
|
|
ext_wdg_lock();
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if ((wdg_num >= EXT_WDG_NUM) || (value == TD_NULL)) {
|
|
soc_log_err("para value is null.\n");
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_GETTIMEOUT, &temp_value);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("wdg get timeout failed:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_GETTIMEOUT;
|
|
goto err;
|
|
}
|
|
|
|
/* convert s to ms */
|
|
*value = 1000 * temp_value; /* 1s equal to 1000ms */
|
|
ret = TD_SUCCESS;
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_clear
|
|
* Description: clear the WDG
|
|
* Calls: EXT_WDG_ClearWatchDog
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_clear(td_u32 wdg_num)
|
|
{
|
|
td_s32 ret = 0;
|
|
|
|
ext_wdg_lock();
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if (wdg_num >= EXT_WDG_NUM) {
|
|
soc_log_err("Input parameter(wdg_num) invalid: %d\n", wdg_num);
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_KEEPALIVE, NULL);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("clear wdg failed:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_CLEARWDG;
|
|
goto err;
|
|
}
|
|
|
|
ret = TD_SUCCESS;
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Function: ext_mpi_wdg_reset
|
|
* Description: reset WDG
|
|
* Calls: EXT_WDG_Reset
|
|
* Data Accessed: NA
|
|
* Data Updated: NA
|
|
* Input: NA
|
|
* Output: NA
|
|
* Return: ErrorCode(reference to document)
|
|
* Others: NA
|
|
*/
|
|
td_s32 ext_mpi_wdg_reset(td_u32 wdg_num)
|
|
{
|
|
td_s32 ret = 0;
|
|
td_s32 option = 0;
|
|
td_s32 timeout = 0;
|
|
|
|
ext_wdg_lock();
|
|
if (g_wdg_dev_fd <= 0) {
|
|
soc_log_err("file descriptor is illegal\n");
|
|
ret = SOC_ERR_WDG_NOT_INIT;
|
|
goto err;
|
|
}
|
|
|
|
if (wdg_num >= EXT_WDG_NUM) {
|
|
soc_log_err("Input parameter(wdg_num) invalid: %d\n", wdg_num);
|
|
ret = SOC_ERR_WDG_INVALID_PARA;
|
|
goto err;
|
|
}
|
|
|
|
option = WDIOS_ENABLECARD;
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_SETOPTIONS, &option);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("enable failed:%d\n", errno);
|
|
ret = SOC_ERR_WDG_FAILED_RESET;
|
|
goto err;
|
|
}
|
|
|
|
timeout = 1;
|
|
ret = ioctl(g_wdg_dev_fd, WDIOC_SETTIMEOUT, &timeout);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("reset failed\n");
|
|
ret = SOC_ERR_WDG_FAILED_RESET;
|
|
goto err;
|
|
}
|
|
|
|
ret = TD_SUCCESS;
|
|
err:
|
|
ext_wdg_unlock();
|
|
return ret;
|
|
}
|