aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/at91rm9200_wdt.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-08-08 12:33:47 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-08-08 14:18:18 -0400
commit097d9eb537ff4d88b74c3fe67392e27c478ca3c5 (patch)
tree9034d676d9096857a380aab9d99e3e88fccb6bfe /drivers/watchdog/at91rm9200_wdt.c
parentc41107c2d4fd31924533f4dbc4c3428acc2b5894 (diff)
parentaeee90dfa01844168cd7f8051d0a0f969c573067 (diff)
Merge Linus' latest into master
Conflicts: drivers/watchdog/at91rm9200_wdt.c drivers/watchdog/davinci_wdt.c drivers/watchdog/ep93xx_wdt.c drivers/watchdog/ixp2000_wdt.c drivers/watchdog/ixp4xx_wdt.c drivers/watchdog/ks8695_wdt.c drivers/watchdog/omap_wdt.c drivers/watchdog/pnx4008_wdt.c drivers/watchdog/sa1100_wdt.c drivers/watchdog/wdt285.c
Diffstat (limited to 'drivers/watchdog/at91rm9200_wdt.c')
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c109
1 files changed, 54 insertions, 55 deletions
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index bf872aa2b9f3..bacd867dd22e 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -20,10 +20,9 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/watchdog.h> 22#include <linux/watchdog.h>
23#include <asm/uaccess.h> 23#include <linux/uaccess.h>
24#include <mach/at91_st.h> 24#include <mach/at91_st.h>
25 25
26
27#define WDT_DEFAULT_TIME 5 /* seconds */ 26#define WDT_DEFAULT_TIME 5 /* seconds */
28#define WDT_MAX_TIME 256 /* seconds */ 27#define WDT_MAX_TIME 256 /* seconds */
29 28
@@ -31,11 +30,14 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 30static int nowayout = WATCHDOG_NOWAYOUT;
32 31
33module_param(wdt_time, int, 0); 32module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
34 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 35
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 36#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 38MODULE_PARM_DESC(nowayout,
39 "Watchdog cannot be stopped once started (default="
40 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 41#endif
40 42
41 43
@@ -46,7 +48,7 @@ static unsigned long at91wdt_busy;
46/* 48/*
47 * Disable the watchdog. 49 * Disable the watchdog.
48 */ 50 */
49static void inline at91_wdt_stop(void) 51static inline void at91_wdt_stop(void)
50{ 52{
51 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); 53 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN);
52} 54}
@@ -54,16 +56,17 @@ static void inline at91_wdt_stop(void)
54/* 56/*
55 * Enable and reset the watchdog. 57 * Enable and reset the watchdog.
56 */ 58 */
57static void inline at91_wdt_start(void) 59static inline void at91_wdt_start(void)
58{ 60{
59 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); 61 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
62 (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
60 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 63 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
61} 64}
62 65
63/* 66/*
64 * Reload the watchdog timer. (ie, pat the watchdog) 67 * Reload the watchdog timer. (ie, pat the watchdog)
65 */ 68 */
66static void inline at91_wdt_reload(void) 69static inline void at91_wdt_reload(void)
67{ 70{
68 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 71 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
69} 72}
@@ -89,8 +92,9 @@ static int at91_wdt_open(struct inode *inode, struct file *file)
89 */ 92 */
90static int at91_wdt_close(struct inode *inode, struct file *file) 93static int at91_wdt_close(struct inode *inode, struct file *file)
91{ 94{
95 /* Disable the watchdog when file is closed */
92 if (!nowayout) 96 if (!nowayout)
93 at91_wdt_stop(); /* Disable the watchdog when file is closed */ 97 at91_wdt_stop();
94 98
95 clear_bit(0, &at91wdt_busy); 99 clear_bit(0, &at91wdt_busy);
96 return 0; 100 return 0;
@@ -110,7 +114,8 @@ static int at91_wdt_settimeout(int new_time)
110 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 114 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
111 return -EINVAL; 115 return -EINVAL;
112 116
113 /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ 117 /* Set new watchdog time. It will be used when
118 at91_wdt_start() is called. */
114 wdt_time = new_time; 119 wdt_time = new_time;
115 return 0; 120 return 0;
116} 121}
@@ -123,60 +128,52 @@ static struct watchdog_info at91_wdt_info = {
123/* 128/*
124 * Handle commands from user-space. 129 * Handle commands from user-space.
125 */ 130 */
126static int at91_wdt_ioctl(struct inode *inode, struct file *file, 131static long at91_wdt_ioct(struct file *file,
127 unsigned int cmd, unsigned long arg) 132 unsigned int cmd, unsigned long arg)
128{ 133{
129 void __user *argp = (void __user *)arg; 134 void __user *argp = (void __user *)arg;
130 int __user *p = argp; 135 int __user *p = argp;
131 int new_value; 136 int new_value;
132 137
133 switch(cmd) { 138 switch (cmd) {
134 case WDIOC_KEEPALIVE: 139 case WDIOC_GETSUPPORT:
135 at91_wdt_reload(); /* pat the watchdog */ 140 return copy_to_user(argp, &at91_wdt_info,
136 return 0; 141 sizeof(at91_wdt_info)) ? -EFAULT : 0;
137 142 case WDIOC_GETSTATUS:
138 case WDIOC_GETSUPPORT: 143 case WDIOC_GETBOOTSTATUS:
139 return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; 144 return put_user(0, p);
140 145 case WDIOC_SETOPTIONS:
141 case WDIOC_SETTIMEOUT: 146 if (get_user(new_value, p))
142 if (get_user(new_value, p)) 147 return -EFAULT;
143 return -EFAULT; 148 if (new_value & WDIOS_DISABLECARD)
144 149 at91_wdt_stop();
145 if (at91_wdt_settimeout(new_value)) 150 if (new_value & WDIOS_ENABLECARD)
146 return -EINVAL;
147
148 /* Enable new time value */
149 at91_wdt_start(); 151 at91_wdt_start();
150 152 return 0;
151 /* Return current value */ 153 case WDIOC_KEEPALIVE:
152 return put_user(wdt_time, p); 154 at91_wdt_reload(); /* pat the watchdog */
153 155 return 0;
154 case WDIOC_GETTIMEOUT: 156 case WDIOC_SETTIMEOUT:
155 return put_user(wdt_time, p); 157 if (get_user(new_value, p))
156 158 return -EFAULT;
157 case WDIOC_GETSTATUS: 159 if (at91_wdt_settimeout(new_value))
158 case WDIOC_GETBOOTSTATUS: 160 return -EINVAL;
159 return put_user(0, p); 161 /* Enable new time value */
160 162 at91_wdt_start();
161 case WDIOC_SETOPTIONS: 163 /* Return current value */
162 if (get_user(new_value, p)) 164 return put_user(wdt_time, p);
163 return -EFAULT; 165 case WDIOC_GETTIMEOUT:
164 166 return put_user(wdt_time, p);
165 if (new_value & WDIOS_DISABLECARD) 167 default:
166 at91_wdt_stop(); 168 return -ENOTTY;
167 if (new_value & WDIOS_ENABLECARD)
168 at91_wdt_start();
169 return 0;
170
171 default:
172 return -ENOTTY;
173 } 169 }
174} 170}
175 171
176/* 172/*
177 * Pat the watchdog whenever device is written to. 173 * Pat the watchdog whenever device is written to.
178 */ 174 */
179static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 175static ssize_t at91_wdt_write(struct file *file, const char *data,
176 size_t len, loff_t *ppos)
180{ 177{
181 at91_wdt_reload(); /* pat the watchdog */ 178 at91_wdt_reload(); /* pat the watchdog */
182 return len; 179 return len;
@@ -187,7 +184,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l
187static const struct file_operations at91wdt_fops = { 184static const struct file_operations at91wdt_fops = {
188 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
189 .llseek = no_llseek, 186 .llseek = no_llseek,
190 .ioctl = at91_wdt_ioctl, 187 .unlocked_ioctl = at91_wdt_ioctl,
191 .open = at91_wdt_open, 188 .open = at91_wdt_open,
192 .release = at91_wdt_close, 189 .release = at91_wdt_close,
193 .write = at91_wdt_write, 190 .write = at91_wdt_write,
@@ -211,7 +208,8 @@ static int __init at91wdt_probe(struct platform_device *pdev)
211 if (res) 208 if (res)
212 return res; 209 return res;
213 210
214 printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 211 printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
212 wdt_time, nowayout ? ", nowayout" : "");
215 return 0; 213 return 0;
216} 214}
217 215
@@ -265,7 +263,8 @@ static struct platform_driver at91wdt_driver = {
265 263
266static int __init at91_wdt_init(void) 264static int __init at91_wdt_init(void)
267{ 265{
268 /* Check that the heartbeat value is within range; if not reset to the default */ 266 /* Check that the heartbeat value is within range;
267 if not reset to the default */
269 if (at91_wdt_settimeout(wdt_time)) { 268 if (at91_wdt_settimeout(wdt_time)) {
270 at91_wdt_settimeout(WDT_DEFAULT_TIME); 269 at91_wdt_settimeout(WDT_DEFAULT_TIME);
271 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); 270 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);