Commit b92c803ec61de59e6e4ab9b2748d8e633cec3f08
1 parent
d624584238
Exists in
master
and in
20 other branches
watchdog: txx9wdt: fix timeout
timeout should be an unsigned int. Set the timeout value properly in the watchdog_device struct so that we don't get an faulty values for the WDIOC_GETTIMEOUT ioctl call. Add check to see that timeout is a valid parameter after it is loaded as a module. Signed-off-by: Wim Van Sebroeck <wim@iguana.be> Acked-by: Wolfram Sang <w.sang@pengutronix.de>
Showing 1 changed file with 10 additions and 8 deletions Side-by-side Diff
drivers/watchdog/txx9wdt.c
| ... | ... | @@ -22,10 +22,13 @@ |
| 22 | 22 | #include <linux/io.h> |
| 23 | 23 | #include <asm/txx9tmr.h> |
| 24 | 24 | |
| 25 | +#define WD_TIMER_CCD 7 /* 1/256 */ | |
| 26 | +#define WD_TIMER_CLK (clk_get_rate(txx9_imclk) / (2 << WD_TIMER_CCD)) | |
| 27 | +#define WD_MAX_TIMEOUT ((0xffffffff >> (32 - TXX9_TIMER_BITS)) / WD_TIMER_CLK) | |
| 25 | 28 | #define TIMER_MARGIN 60 /* Default is 60 seconds */ |
| 26 | 29 | |
| 27 | -static int timeout = TIMER_MARGIN; /* in seconds */ | |
| 28 | -module_param(timeout, int, 0); | |
| 30 | +static unsigned int timeout = TIMER_MARGIN; /* in seconds */ | |
| 31 | +module_param(timeout, uint, 0); | |
| 29 | 32 | MODULE_PARM_DESC(timeout, |
| 30 | 33 | "Watchdog timeout in seconds. " |
| 31 | 34 | "(0<timeout<((2^" __MODULE_STRING(TXX9_TIMER_BITS) ")/(IMCLK/256)), " |
| ... | ... | @@ -37,10 +40,6 @@ |
| 37 | 40 | "Watchdog cannot be stopped once started " |
| 38 | 41 | "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 39 | 42 | |
| 40 | -#define WD_TIMER_CCD 7 /* 1/256 */ | |
| 41 | -#define WD_TIMER_CLK (clk_get_rate(txx9_imclk) / (2 << WD_TIMER_CCD)) | |
| 42 | -#define WD_MAX_TIMEOUT ((0xffffffff >> (32 - TXX9_TIMER_BITS)) / WD_TIMER_CLK) | |
| 43 | - | |
| 44 | 43 | static struct txx9_tmr_reg __iomem *txx9wdt_reg; |
| 45 | 44 | static struct clk *txx9_imclk; |
| 46 | 45 | static DEFINE_SPINLOCK(txx9_lock); |
| ... | ... | @@ -56,7 +55,7 @@ |
| 56 | 55 | static int txx9wdt_start(struct watchdog_device *wdt_dev) |
| 57 | 56 | { |
| 58 | 57 | spin_lock(&txx9_lock); |
| 59 | - __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); | |
| 58 | + __raw_writel(WD_TIMER_CLK * wdt_dev->timeout, &txx9wdt_reg->cpra); | |
| 60 | 59 | __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); |
| 61 | 60 | __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ |
| 62 | 61 | __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, |
| ... | ... | @@ -79,7 +78,7 @@ |
| 79 | 78 | static int txx9wdt_set_timeout(struct watchdog_device *wdt_dev, |
| 80 | 79 | unsigned int new_timeout) |
| 81 | 80 | { |
| 82 | - timeout = new_timeout; | |
| 81 | + wdt_dev->timeout = new_timeout; | |
| 83 | 82 | txx9wdt_stop(wdt_dev); |
| 84 | 83 | txx9wdt_start(wdt_dev); |
| 85 | 84 | return 0; |
| ... | ... | @@ -128,6 +127,9 @@ |
| 128 | 127 | goto exit; |
| 129 | 128 | } |
| 130 | 129 | |
| 130 | + if (timeout < 1 || timeout > WD_MAX_TIMEOUT) | |
| 131 | + timeout = TIMER_MARGIN; | |
| 132 | + txx9wdt.timeout = timeout; | |
| 131 | 133 | txx9wdt.min_timeout = 1; |
| 132 | 134 | txx9wdt.max_timeout = WD_MAX_TIMEOUT; |
| 133 | 135 | watchdog_set_nowayout(&txx9wdt, nowayout); |