diff options
Diffstat (limited to 'drivers/watchdog/wdrtas.c')
-rw-r--r-- | drivers/watchdog/wdrtas.c | 103 |
1 files changed, 41 insertions, 62 deletions
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 1d64e277567d..20fd6715f25f 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include <linux/reboot.h> | 35 | #include <linux/reboot.h> |
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/watchdog.h> | 37 | #include <linux/watchdog.h> |
38 | #include <linux/uaccess.h> | ||
38 | 39 | ||
39 | #include <asm/rtas.h> | 40 | #include <asm/rtas.h> |
40 | #include <asm/uaccess.h> | ||
41 | 41 | ||
42 | #define WDRTAS_MAGIC_CHAR 42 | 42 | #define WDRTAS_MAGIC_CHAR 42 |
43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ | 43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ |
@@ -56,7 +56,7 @@ static int wdrtas_nowayout = 0; | |||
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); | 58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); |
59 | static char wdrtas_expect_close = 0; | 59 | static char wdrtas_expect_close; |
60 | 60 | ||
61 | static int wdrtas_interval; | 61 | static int wdrtas_interval; |
62 | 62 | ||
@@ -86,8 +86,8 @@ static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN]; | |||
86 | * RTAS function set-indicator (surveillance). The unit of interval is | 86 | * RTAS function set-indicator (surveillance). The unit of interval is |
87 | * seconds. | 87 | * seconds. |
88 | */ | 88 | */ |
89 | static int | 89 | |
90 | wdrtas_set_interval(int interval) | 90 | static int wdrtas_set_interval(int interval) |
91 | { | 91 | { |
92 | long result; | 92 | long result; |
93 | static int print_msg = 10; | 93 | static int print_msg = 10; |
@@ -97,7 +97,7 @@ wdrtas_set_interval(int interval) | |||
97 | 97 | ||
98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, | 98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, |
99 | WDRTAS_SURVEILLANCE_IND, 0, interval); | 99 | WDRTAS_SURVEILLANCE_IND, 0, interval); |
100 | if ( (result < 0) && (print_msg) ) { | 100 | if (result < 0 && print_msg) { |
101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " | 101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " |
102 | "timeout failed: %li\n", interval, result); | 102 | "timeout failed: %li\n", interval, result); |
103 | print_msg--; | 103 | print_msg--; |
@@ -116,16 +116,14 @@ wdrtas_set_interval(int interval) | |||
116 | * as reported by the RTAS function ibm,get-system-parameter. The unit | 116 | * as reported by the RTAS function ibm,get-system-parameter. The unit |
117 | * of the return value is seconds. | 117 | * of the return value is seconds. |
118 | */ | 118 | */ |
119 | static int | 119 | static int wdrtas_get_interval(int fallback_value) |
120 | wdrtas_get_interval(int fallback_value) | ||
121 | { | 120 | { |
122 | long result; | 121 | long result; |
123 | char value[4]; | 122 | char value[4]; |
124 | 123 | ||
125 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, | 124 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, |
126 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); | 125 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); |
127 | if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || | 126 | if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) { |
128 | (result < 0) ) { | ||
129 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " | 127 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " |
130 | "timeout (%li). Continuing\n", result); | 128 | "timeout (%li). Continuing\n", result); |
131 | return fallback_value; | 129 | return fallback_value; |
@@ -141,8 +139,7 @@ wdrtas_get_interval(int fallback_value) | |||
141 | * wdrtas_timer_start starts the watchdog by calling the RTAS function | 139 | * wdrtas_timer_start starts the watchdog by calling the RTAS function |
142 | * set-interval (surveillance) | 140 | * set-interval (surveillance) |
143 | */ | 141 | */ |
144 | static void | 142 | static void wdrtas_timer_start(void) |
145 | wdrtas_timer_start(void) | ||
146 | { | 143 | { |
147 | wdrtas_set_interval(wdrtas_interval); | 144 | wdrtas_set_interval(wdrtas_interval); |
148 | } | 145 | } |
@@ -153,8 +150,7 @@ wdrtas_timer_start(void) | |||
153 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function | 150 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function |
154 | * set-interval (surveillance) | 151 | * set-interval (surveillance) |
155 | */ | 152 | */ |
156 | static void | 153 | static void wdrtas_timer_stop(void) |
157 | wdrtas_timer_stop(void) | ||
158 | { | 154 | { |
159 | wdrtas_set_interval(0); | 155 | wdrtas_set_interval(0); |
160 | } | 156 | } |
@@ -165,8 +161,7 @@ wdrtas_timer_stop(void) | |||
165 | * wdrtas_log_scanned_event prints a message to the log buffer dumping | 161 | * wdrtas_log_scanned_event prints a message to the log buffer dumping |
166 | * the results of the last event-scan call | 162 | * the results of the last event-scan call |
167 | */ | 163 | */ |
168 | static void | 164 | static void wdrtas_log_scanned_event(void) |
169 | wdrtas_log_scanned_event(void) | ||
170 | { | 165 | { |
171 | int i; | 166 | int i; |
172 | 167 | ||
@@ -175,13 +170,13 @@ wdrtas_log_scanned_event(void) | |||
175 | "%02x %02x %02x %02x %02x %02x %02x %02x " | 170 | "%02x %02x %02x %02x %02x %02x %02x %02x " |
176 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | 171 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
177 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), | 172 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), |
178 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], | 173 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], |
179 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], | 174 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], |
180 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], | 175 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], |
181 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], | 176 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], |
182 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], | 177 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], |
183 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], | 178 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], |
184 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], | 179 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], |
185 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); | 180 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); |
186 | } | 181 | } |
187 | 182 | ||
@@ -192,8 +187,7 @@ wdrtas_log_scanned_event(void) | |||
192 | * RTAS function event-scan and repeats these calls as long as there are | 187 | * RTAS function event-scan and repeats these calls as long as there are |
193 | * events available. All events will be dumped. | 188 | * events available. All events will be dumped. |
194 | */ | 189 | */ |
195 | static void | 190 | static void wdrtas_timer_keepalive(void) |
196 | wdrtas_timer_keepalive(void) | ||
197 | { | 191 | { |
198 | long result; | 192 | long result; |
199 | 193 | ||
@@ -218,8 +212,7 @@ wdrtas_timer_keepalive(void) | |||
218 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It | 212 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It |
219 | * uses the RTAS call get-sensor-state, token 3 to do so | 213 | * uses the RTAS call get-sensor-state, token 3 to do so |
220 | */ | 214 | */ |
221 | static int | 215 | static int wdrtas_get_temperature(void) |
222 | wdrtas_get_temperature(void) | ||
223 | { | 216 | { |
224 | long result; | 217 | long result; |
225 | int temperature = 0; | 218 | int temperature = 0; |
@@ -243,8 +236,7 @@ wdrtas_get_temperature(void) | |||
243 | * returns a bitmask of defines WDIOF_... as defined in | 236 | * returns a bitmask of defines WDIOF_... as defined in |
244 | * include/linux/watchdog.h | 237 | * include/linux/watchdog.h |
245 | */ | 238 | */ |
246 | static int | 239 | static int wdrtas_get_status(void) |
247 | wdrtas_get_status(void) | ||
248 | { | 240 | { |
249 | return 0; /* TODO */ | 241 | return 0; /* TODO */ |
250 | } | 242 | } |
@@ -255,8 +247,7 @@ wdrtas_get_status(void) | |||
255 | * returns a bitmask of defines WDIOF_... as defined in | 247 | * returns a bitmask of defines WDIOF_... as defined in |
256 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system | 248 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system |
257 | */ | 249 | */ |
258 | static int | 250 | static int wdrtas_get_boot_status(void) |
259 | wdrtas_get_boot_status(void) | ||
260 | { | 251 | { |
261 | return 0; /* TODO */ | 252 | return 0; /* TODO */ |
262 | } | 253 | } |
@@ -276,8 +267,7 @@ wdrtas_get_boot_status(void) | |||
276 | * character 'V'. This character allows the watchdog device to be closed | 267 | * character 'V'. This character allows the watchdog device to be closed |
277 | * properly. | 268 | * properly. |
278 | */ | 269 | */ |
279 | static ssize_t | 270 | static ssize_t wdrtas_write(struct file *file, const char __user *buf, |
280 | wdrtas_write(struct file *file, const char __user *buf, | ||
281 | size_t len, loff_t *ppos) | 271 | size_t len, loff_t *ppos) |
282 | { | 272 | { |
283 | int i; | 273 | int i; |
@@ -306,7 +296,6 @@ out: | |||
306 | 296 | ||
307 | /** | 297 | /** |
308 | * wdrtas_ioctl - ioctl function for the watchdog device | 298 | * wdrtas_ioctl - ioctl function for the watchdog device |
309 | * @inode: inode structure | ||
310 | * @file: file structure | 299 | * @file: file structure |
311 | * @cmd: command for ioctl | 300 | * @cmd: command for ioctl |
312 | * @arg: argument pointer | 301 | * @arg: argument pointer |
@@ -315,9 +304,9 @@ out: | |||
315 | * | 304 | * |
316 | * wdrtas_ioctl implements the watchdog API ioctls | 305 | * wdrtas_ioctl implements the watchdog API ioctls |
317 | */ | 306 | */ |
318 | static int | 307 | |
319 | wdrtas_ioctl(struct inode *inode, struct file *file, | 308 | static long wdrtas_ioctl(struct file *file, unsigned int cmd, |
320 | unsigned int cmd, unsigned long arg) | 309 | unsigned long arg) |
321 | { | 310 | { |
322 | int __user *argp = (void __user *)arg; | 311 | int __user *argp = (void __user *)arg; |
323 | int i; | 312 | int i; |
@@ -357,9 +346,9 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
357 | wdrtas_timer_keepalive(); | 346 | wdrtas_timer_keepalive(); |
358 | wdrtas_timer_start(); | 347 | wdrtas_timer_start(); |
359 | } | 348 | } |
349 | /* not implemented. Done by H8 | ||
360 | if (i & WDIOS_TEMPPANIC) { | 350 | if (i & WDIOS_TEMPPANIC) { |
361 | /* not implemented. Done by H8 */ | 351 | } */ |
362 | } | ||
363 | return 0; | 352 | return 0; |
364 | 353 | ||
365 | case WDIOC_KEEPALIVE: | 354 | case WDIOC_KEEPALIVE: |
@@ -399,8 +388,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
399 | * | 388 | * |
400 | * function called when watchdog device is opened | 389 | * function called when watchdog device is opened |
401 | */ | 390 | */ |
402 | static int | 391 | static int wdrtas_open(struct inode *inode, struct file *file) |
403 | wdrtas_open(struct inode *inode, struct file *file) | ||
404 | { | 392 | { |
405 | /* only open once */ | 393 | /* only open once */ |
406 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { | 394 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { |
@@ -423,8 +411,7 @@ wdrtas_open(struct inode *inode, struct file *file) | |||
423 | * | 411 | * |
424 | * close function. Always succeeds | 412 | * close function. Always succeeds |
425 | */ | 413 | */ |
426 | static int | 414 | static int wdrtas_close(struct inode *inode, struct file *file) |
427 | wdrtas_close(struct inode *inode, struct file *file) | ||
428 | { | 415 | { |
429 | /* only stop watchdog, if this was announced using 'V' before */ | 416 | /* only stop watchdog, if this was announced using 'V' before */ |
430 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) | 417 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) |
@@ -453,8 +440,7 @@ wdrtas_close(struct inode *inode, struct file *file) | |||
453 | * wdrtas_temp_read gives the temperature to the users by copying this | 440 | * wdrtas_temp_read gives the temperature to the users by copying this |
454 | * value as one byte into the user space buffer. The unit is Fahrenheit... | 441 | * value as one byte into the user space buffer. The unit is Fahrenheit... |
455 | */ | 442 | */ |
456 | static ssize_t | 443 | static ssize_t wdrtas_temp_read(struct file *file, char __user *buf, |
457 | wdrtas_temp_read(struct file *file, char __user *buf, | ||
458 | size_t count, loff_t *ppos) | 444 | size_t count, loff_t *ppos) |
459 | { | 445 | { |
460 | int temperature = 0; | 446 | int temperature = 0; |
@@ -478,8 +464,7 @@ wdrtas_temp_read(struct file *file, char __user *buf, | |||
478 | * | 464 | * |
479 | * function called when temperature device is opened | 465 | * function called when temperature device is opened |
480 | */ | 466 | */ |
481 | static int | 467 | static int wdrtas_temp_open(struct inode *inode, struct file *file) |
482 | wdrtas_temp_open(struct inode *inode, struct file *file) | ||
483 | { | 468 | { |
484 | return nonseekable_open(inode, file); | 469 | return nonseekable_open(inode, file); |
485 | } | 470 | } |
@@ -493,8 +478,7 @@ wdrtas_temp_open(struct inode *inode, struct file *file) | |||
493 | * | 478 | * |
494 | * close function. Always succeeds | 479 | * close function. Always succeeds |
495 | */ | 480 | */ |
496 | static int | 481 | static int wdrtas_temp_close(struct inode *inode, struct file *file) |
497 | wdrtas_temp_close(struct inode *inode, struct file *file) | ||
498 | { | 482 | { |
499 | return 0; | 483 | return 0; |
500 | } | 484 | } |
@@ -509,10 +493,10 @@ wdrtas_temp_close(struct inode *inode, struct file *file) | |||
509 | * | 493 | * |
510 | * wdrtas_reboot stops the watchdog in case of a reboot | 494 | * wdrtas_reboot stops the watchdog in case of a reboot |
511 | */ | 495 | */ |
512 | static int | 496 | static int wdrtas_reboot(struct notifier_block *this, |
513 | wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) | 497 | unsigned long code, void *ptr) |
514 | { | 498 | { |
515 | if ( (code==SYS_DOWN) || (code==SYS_HALT) ) | 499 | if (code == SYS_DOWN || code == SYS_HALT) |
516 | wdrtas_timer_stop(); | 500 | wdrtas_timer_stop(); |
517 | 501 | ||
518 | return NOTIFY_DONE; | 502 | return NOTIFY_DONE; |
@@ -524,7 +508,7 @@ static const struct file_operations wdrtas_fops = { | |||
524 | .owner = THIS_MODULE, | 508 | .owner = THIS_MODULE, |
525 | .llseek = no_llseek, | 509 | .llseek = no_llseek, |
526 | .write = wdrtas_write, | 510 | .write = wdrtas_write, |
527 | .ioctl = wdrtas_ioctl, | 511 | .unlocked_ioctl = wdrtas_ioctl, |
528 | .open = wdrtas_open, | 512 | .open = wdrtas_open, |
529 | .release = wdrtas_close, | 513 | .release = wdrtas_close, |
530 | }; | 514 | }; |
@@ -562,8 +546,7 @@ static struct notifier_block wdrtas_notifier = { | |||
562 | * this watchdog driver. It tolerates, if "get-sensor-state" and | 546 | * this watchdog driver. It tolerates, if "get-sensor-state" and |
563 | * "ibm,get-system-parameter" are not available. | 547 | * "ibm,get-system-parameter" are not available. |
564 | */ | 548 | */ |
565 | static int | 549 | static int wdrtas_get_tokens(void) |
566 | wdrtas_get_tokens(void) | ||
567 | { | 550 | { |
568 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); | 551 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); |
569 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { | 552 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { |
@@ -603,8 +586,7 @@ wdrtas_get_tokens(void) | |||
603 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog | 586 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog |
604 | * misc devs | 587 | * misc devs |
605 | */ | 588 | */ |
606 | static void | 589 | static void wdrtas_unregister_devs(void) |
607 | wdrtas_unregister_devs(void) | ||
608 | { | 590 | { |
609 | misc_deregister(&wdrtas_miscdev); | 591 | misc_deregister(&wdrtas_miscdev); |
610 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) | 592 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) |
@@ -619,8 +601,7 @@ wdrtas_unregister_devs(void) | |||
619 | * wdrtas_register_devs registers the watchdog and temperature watchdog | 601 | * wdrtas_register_devs registers the watchdog and temperature watchdog |
620 | * misc devs | 602 | * misc devs |
621 | */ | 603 | */ |
622 | static int | 604 | static int wdrtas_register_devs(void) |
623 | wdrtas_register_devs(void) | ||
624 | { | 605 | { |
625 | int result; | 606 | int result; |
626 | 607 | ||
@@ -651,8 +632,7 @@ wdrtas_register_devs(void) | |||
651 | * | 632 | * |
652 | * registers the file handlers and the reboot notifier | 633 | * registers the file handlers and the reboot notifier |
653 | */ | 634 | */ |
654 | static int __init | 635 | static int __init wdrtas_init(void) |
655 | wdrtas_init(void) | ||
656 | { | 636 | { |
657 | if (wdrtas_get_tokens()) | 637 | if (wdrtas_get_tokens()) |
658 | return -ENODEV; | 638 | return -ENODEV; |
@@ -680,8 +660,7 @@ wdrtas_init(void) | |||
680 | * | 660 | * |
681 | * unregisters the file handlers and the reboot notifier | 661 | * unregisters the file handlers and the reboot notifier |
682 | */ | 662 | */ |
683 | static void __exit | 663 | static void __exit wdrtas_exit(void) |
684 | wdrtas_exit(void) | ||
685 | { | 664 | { |
686 | if (!wdrtas_nowayout) | 665 | if (!wdrtas_nowayout) |
687 | wdrtas_timer_stop(); | 666 | wdrtas_timer_stop(); |