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:
Родитель
e3e83d0001
Коммит
3048253ed9
|
@ -1,6 +1,6 @@
|
|||
The Linux WatchDog Timer Driver Core kernel API.
|
||||
===============================================
|
||||
Last reviewed: 22-May-2012
|
||||
Last reviewed: 12-Feb-2013
|
||||
|
||||
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 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.
|
||||
|
||||
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/idr.h> /* For ida_* 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/... */
|
||||
|
||||
static DEFINE_IDA(watchdog_ida);
|
||||
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
|
||||
* @wdd: watchdog device
|
||||
|
@ -63,15 +119,7 @@ int watchdog_register_device(struct watchdog_device *wdd)
|
|||
if (wdd->ops->start == NULL || wdd->ops->stop == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* 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_check_min_max_timeout(wdd);
|
||||
|
||||
/*
|
||||
* 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))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((wddev->max_timeout != 0) &&
|
||||
(timeout < wddev->min_timeout || timeout > wddev->max_timeout))
|
||||
if (watchdog_timeout_invalid(wddev, timeout))
|
||||
return -EINVAL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
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 void watchdog_unregister_device(struct watchdog_device *);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче