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

/*
* 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;
}