diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/watchdog/watchdog_core.c | 66 | ||||
| -rw-r--r-- | drivers/watchdog/watchdog_dev.c | 3 |
2 files changed, 58 insertions, 11 deletions
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 3796434991fa..05d18b4c661b 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c | |||
| @@ -36,12 +36,68 @@ | |||
| 36 | #include <linux/init.h> /* For __init/__exit/... */ | 36 | #include <linux/init.h> /* For __init/__exit/... */ |
| 37 | #include <linux/idr.h> /* For ida_* macros */ | 37 | #include <linux/idr.h> /* For ida_* macros */ |
| 38 | #include <linux/err.h> /* For IS_ERR macros */ | 38 | #include <linux/err.h> /* For IS_ERR macros */ |
| 39 | #include <linux/of.h> /* For of_get_timeout_sec */ | ||
| 39 | 40 | ||
| 40 | #include "watchdog_core.h" /* For watchdog_dev_register/... */ | 41 | #include "watchdog_core.h" /* For watchdog_dev_register/... */ |
| 41 | 42 | ||
| 42 | static DEFINE_IDA(watchdog_ida); | 43 | static DEFINE_IDA(watchdog_ida); |
| 43 | static struct class *watchdog_class; | 44 | static struct class *watchdog_class; |
| 44 | 45 | ||
| 46 | static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) | ||
| 47 | { | ||
| 48 | /* | ||
| 49 | * Check that we have valid min and max timeout values, if | ||
| 50 | * not reset them both to 0 (=not used or unknown) | ||
| 51 | */ | ||
| 52 | if (wdd->min_timeout > wdd->max_timeout) { | ||
| 53 | pr_info("Invalid min and max timeout values, resetting to 0!\n"); | ||
| 54 | wdd->min_timeout = 0; | ||
| 55 | wdd->max_timeout = 0; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | /** | ||
| 60 | * watchdog_init_timeout() - initialize the timeout field | ||
| 61 | * @timeout_parm: timeout module parameter | ||
| 62 | * @dev: Device that stores the timeout-sec property | ||
| 63 | * | ||
| 64 | * Initialize the timeout field of the watchdog_device struct with either the | ||
| 65 | * timeout module parameter (if it is valid value) or the timeout-sec property | ||
| 66 | * (only if it is a valid value and the timeout_parm is out of bounds). | ||
| 67 | * If none of them are valid then we keep the old value (which should normally | ||
| 68 | * be the default timeout value. | ||
| 69 | * | ||
| 70 | * A zero is returned on success and -EINVAL for failure. | ||
| 71 | */ | ||
| 72 | int watchdog_init_timeout(struct watchdog_device *wdd, | ||
| 73 | unsigned int timeout_parm, struct device *dev) | ||
| 74 | { | ||
| 75 | unsigned int t = 0; | ||
| 76 | int ret = 0; | ||
| 77 | |||
| 78 | watchdog_check_min_max_timeout(wdd); | ||
| 79 | |||
| 80 | /* try to get the tiemout module parameter first */ | ||
| 81 | if (!watchdog_timeout_invalid(wdd, timeout_parm)) { | ||
| 82 | wdd->timeout = timeout_parm; | ||
| 83 | return ret; | ||
| 84 | } | ||
| 85 | if (timeout_parm) | ||
| 86 | ret = -EINVAL; | ||
| 87 | |||
| 88 | /* try to get the timeout_sec property */ | ||
| 89 | if (dev == NULL || dev->of_node == NULL) | ||
| 90 | return ret; | ||
| 91 | of_property_read_u32(dev->of_node, "timeout-sec", &t); | ||
| 92 | if (!watchdog_timeout_invalid(wdd, t)) | ||
| 93 | wdd->timeout = t; | ||
| 94 | else | ||
| 95 | ret = -EINVAL; | ||
| 96 | |||
| 97 | return ret; | ||
| 98 | } | ||
| 99 | EXPORT_SYMBOL_GPL(watchdog_init_timeout); | ||
| 100 | |||
| 45 | /** | 101 | /** |
| 46 | * watchdog_register_device() - register a watchdog device | 102 | * watchdog_register_device() - register a watchdog device |
| 47 | * @wdd: watchdog device | 103 | * @wdd: watchdog device |
| @@ -63,15 +119,7 @@ int watchdog_register_device(struct watchdog_device *wdd) | |||
| 63 | if (wdd->ops->start == NULL || wdd->ops->stop == NULL) | 119 | if (wdd->ops->start == NULL || wdd->ops->stop == NULL) |
| 64 | return -EINVAL; | 120 | return -EINVAL; |
| 65 | 121 | ||
| 66 | /* | 122 | watchdog_check_min_max_timeout(wdd); |
| 67 | * Check that we have valid min and max timeout values, if | ||
| 68 | * not reset them both to 0 (=not used or unknown) | ||
| 69 | */ | ||
| 70 | if (wdd->min_timeout > wdd->max_timeout) { | ||
| 71 | pr_info("Invalid min and max timeout values, resetting to 0!\n"); | ||
| 72 | wdd->min_timeout = 0; | ||
| 73 | wdd->max_timeout = 0; | ||
| 74 | } | ||
| 75 | 123 | ||
| 76 | /* | 124 | /* |
| 77 | * Note: now that all watchdog_device data has been verified, we | 125 | * Note: now that all watchdog_device data has been verified, we |
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index ef8edecfc526..08b48bbf9f4b 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c | |||
| @@ -200,8 +200,7 @@ static int watchdog_set_timeout(struct watchdog_device *wddev, | |||
| 200 | !(wddev->info->options & WDIOF_SETTIMEOUT)) | 200 | !(wddev->info->options & WDIOF_SETTIMEOUT)) |
| 201 | return -EOPNOTSUPP; | 201 | return -EOPNOTSUPP; |
| 202 | 202 | ||
| 203 | if ((wddev->max_timeout != 0) && | 203 | if (watchdog_timeout_invalid(wddev, timeout)) |
| 204 | (timeout < wddev->min_timeout || timeout > wddev->max_timeout)) | ||
| 205 | return -EINVAL; | 204 | return -EINVAL; |
| 206 | 205 | ||
| 207 | mutex_lock(&wddev->lock); | 206 | mutex_lock(&wddev->lock); |
