mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 09:20:50 +07:00
watchdog: core: dt: add support for the timeout-sec dt property
Add support for watchdog drivers to initialize/set the timeout field of the watchdog_device structure. The timeout field is initialised either with the module timeout parameter value (if valid) or with the timeout-sec dt property (if valid). If both are invalid the initial value is unchanged. Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
This commit is contained in:
parent
e3e83d0001
commit
3048253ed9
@ -1,6 +1,6 @@
|
|||||||
The Linux WatchDog Timer Driver Core kernel API.
|
The Linux WatchDog Timer Driver Core kernel API.
|
||||||
===============================================
|
===============================================
|
||||||
Last reviewed: 22-May-2012
|
Last reviewed: 12-Feb-2013
|
||||||
|
|
||||||
Wim Van Sebroeck <wim@iguana.be>
|
Wim Van Sebroeck <wim@iguana.be>
|
||||||
|
|
||||||
@ -212,3 +212,15 @@ driver specific data to and a pointer to the data itself.
|
|||||||
The watchdog_get_drvdata function allows you to retrieve driver specific data.
|
The watchdog_get_drvdata function allows you to retrieve driver specific data.
|
||||||
The argument of this function is the watchdog device where you want to retrieve
|
The argument of this function is the watchdog device where you want to retrieve
|
||||||
data from. The function returns the pointer to the driver specific data.
|
data from. The function returns the pointer to the driver specific data.
|
||||||
|
|
||||||
|
To initialize the timeout field, the following function can be used:
|
||||||
|
|
||||||
|
extern int watchdog_init_timeout(struct watchdog_device *wdd,
|
||||||
|
unsigned int timeout_parm, struct device *dev);
|
||||||
|
|
||||||
|
The watchdog_init_timeout function allows you to initialize the timeout field
|
||||||
|
using the module timeout parameter or by retrieving the timeout-sec property from
|
||||||
|
the device tree (if the module timeout parameter is invalid). Best practice is
|
||||||
|
to set the default timeout value as timeout value in the watchdog_device and
|
||||||
|
then use this function to set the user "preferred" timeout value.
|
||||||
|
This routine returns zero on success and a negative errno code for failure.
|
||||||
|
@ -36,12 +36,68 @@
|
|||||||
#include <linux/init.h> /* For __init/__exit/... */
|
#include <linux/init.h> /* For __init/__exit/... */
|
||||||
#include <linux/idr.h> /* For ida_* macros */
|
#include <linux/idr.h> /* For ida_* macros */
|
||||||
#include <linux/err.h> /* For IS_ERR macros */
|
#include <linux/err.h> /* For IS_ERR macros */
|
||||||
|
#include <linux/of.h> /* For of_get_timeout_sec */
|
||||||
|
|
||||||
#include "watchdog_core.h" /* For watchdog_dev_register/... */
|
#include "watchdog_core.h" /* For watchdog_dev_register/... */
|
||||||
|
|
||||||
static DEFINE_IDA(watchdog_ida);
|
static DEFINE_IDA(watchdog_ida);
|
||||||
static struct class *watchdog_class;
|
static struct class *watchdog_class;
|
||||||
|
|
||||||
|
static void watchdog_check_min_max_timeout(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Check that we have valid min and max timeout values, if
|
||||||
|
* not reset them both to 0 (=not used or unknown)
|
||||||
|
*/
|
||||||
|
if (wdd->min_timeout > wdd->max_timeout) {
|
||||||
|
pr_info("Invalid min and max timeout values, resetting to 0!\n");
|
||||||
|
wdd->min_timeout = 0;
|
||||||
|
wdd->max_timeout = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watchdog_init_timeout() - initialize the timeout field
|
||||||
|
* @timeout_parm: timeout module parameter
|
||||||
|
* @dev: Device that stores the timeout-sec property
|
||||||
|
*
|
||||||
|
* Initialize the timeout field of the watchdog_device struct with either the
|
||||||
|
* timeout module parameter (if it is valid value) or the timeout-sec property
|
||||||
|
* (only if it is a valid value and the timeout_parm is out of bounds).
|
||||||
|
* If none of them are valid then we keep the old value (which should normally
|
||||||
|
* be the default timeout value.
|
||||||
|
*
|
||||||
|
* A zero is returned on success and -EINVAL for failure.
|
||||||
|
*/
|
||||||
|
int watchdog_init_timeout(struct watchdog_device *wdd,
|
||||||
|
unsigned int timeout_parm, struct device *dev)
|
||||||
|
{
|
||||||
|
unsigned int t = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
watchdog_check_min_max_timeout(wdd);
|
||||||
|
|
||||||
|
/* try to get the tiemout module parameter first */
|
||||||
|
if (!watchdog_timeout_invalid(wdd, timeout_parm)) {
|
||||||
|
wdd->timeout = timeout_parm;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (timeout_parm)
|
||||||
|
ret = -EINVAL;
|
||||||
|
|
||||||
|
/* try to get the timeout_sec property */
|
||||||
|
if (dev == NULL || dev->of_node == NULL)
|
||||||
|
return ret;
|
||||||
|
of_property_read_u32(dev->of_node, "timeout-sec", &t);
|
||||||
|
if (!watchdog_timeout_invalid(wdd, t))
|
||||||
|
wdd->timeout = t;
|
||||||
|
else
|
||||||
|
ret = -EINVAL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(watchdog_init_timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* watchdog_register_device() - register a watchdog device
|
* watchdog_register_device() - register a watchdog device
|
||||||
* @wdd: watchdog device
|
* @wdd: watchdog device
|
||||||
@ -63,15 +119,7 @@ int watchdog_register_device(struct watchdog_device *wdd)
|
|||||||
if (wdd->ops->start == NULL || wdd->ops->stop == NULL)
|
if (wdd->ops->start == NULL || wdd->ops->stop == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
watchdog_check_min_max_timeout(wdd);
|
||||||
* Check that we have valid min and max timeout values, if
|
|
||||||
* not reset them both to 0 (=not used or unknown)
|
|
||||||
*/
|
|
||||||
if (wdd->min_timeout > wdd->max_timeout) {
|
|
||||||
pr_info("Invalid min and max timeout values, resetting to 0!\n");
|
|
||||||
wdd->min_timeout = 0;
|
|
||||||
wdd->max_timeout = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: now that all watchdog_device data has been verified, we
|
* Note: now that all watchdog_device data has been verified, we
|
||||||
|
@ -200,8 +200,7 @@ static int watchdog_set_timeout(struct watchdog_device *wddev,
|
|||||||
!(wddev->info->options & WDIOF_SETTIMEOUT))
|
!(wddev->info->options & WDIOF_SETTIMEOUT))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if ((wddev->max_timeout != 0) &&
|
if (watchdog_timeout_invalid(wddev, timeout))
|
||||||
(timeout < wddev->min_timeout || timeout > wddev->max_timeout))
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&wddev->lock);
|
mutex_lock(&wddev->lock);
|
||||||
|
@ -118,6 +118,13 @@ static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool noway
|
|||||||
set_bit(WDOG_NO_WAY_OUT, &wdd->status);
|
set_bit(WDOG_NO_WAY_OUT, &wdd->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use the following function to check if a timeout value is invalid */
|
||||||
|
static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t)
|
||||||
|
{
|
||||||
|
return ((wdd->max_timeout != 0) &&
|
||||||
|
(t < wdd->min_timeout || t > wdd->max_timeout));
|
||||||
|
}
|
||||||
|
|
||||||
/* Use the following functions to manipulate watchdog driver specific data */
|
/* Use the following functions to manipulate watchdog driver specific data */
|
||||||
static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
|
static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
|
||||||
{
|
{
|
||||||
@ -130,6 +137,8 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* drivers/watchdog/watchdog_core.c */
|
/* drivers/watchdog/watchdog_core.c */
|
||||||
|
extern int watchdog_init_timeout(struct watchdog_device *wdd,
|
||||||
|
unsigned int timeout_parm, struct device *dev);
|
||||||
extern int watchdog_register_device(struct watchdog_device *);
|
extern int watchdog_register_device(struct watchdog_device *);
|
||||||
extern void watchdog_unregister_device(struct watchdog_device *);
|
extern void watchdog_unregister_device(struct watchdog_device *);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user