aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/wdrtas.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog/wdrtas.c')
-rw-r--r--drivers/watchdog/wdrtas.c105
1 files changed, 42 insertions, 63 deletions
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 1d64e277567d..5d3b1a8e28b0 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
58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); 58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
59static char wdrtas_expect_close = 0; 59static char wdrtas_expect_close;
60 60
61static int wdrtas_interval; 61static 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 */
89static int 89
90wdrtas_set_interval(int interval) 90static 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 */
119static int 119static int wdrtas_get_interval(int fallback_value)
120wdrtas_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 */
144static void 142static void wdrtas_timer_start(void)
145wdrtas_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 */
156static void 153static void wdrtas_timer_stop(void)
157wdrtas_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 */
168static void 164static void wdrtas_log_scanned_event(void)
169wdrtas_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 */
195static void 190static void wdrtas_timer_keepalive(void)
196wdrtas_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 */
221static int 215static int wdrtas_get_temperature(void)
222wdrtas_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 */
246static int 239static int wdrtas_get_status(void)
247wdrtas_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 */
258static int 250static int wdrtas_get_boot_status(void)
259wdrtas_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 */
279static ssize_t 270static ssize_t wdrtas_write(struct file *file, const char __user *buf,
280wdrtas_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,16 +304,16 @@ out:
315 * 304 *
316 * wdrtas_ioctl implements the watchdog API ioctls 305 * wdrtas_ioctl implements the watchdog API ioctls
317 */ 306 */
318static int 307
319wdrtas_ioctl(struct inode *inode, struct file *file, 308static 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;
324 static struct watchdog_info wdinfo = { 313 static struct watchdog_info wdinfo = {
325 .options = WDRTAS_SUPPORTED_MASK, 314 .options = WDRTAS_SUPPORTED_MASK,
326 .firmware_version = 0, 315 .firmware_version = 0,
327 .identity = "wdrtas" 316 .identity = "wdrtas",
328 }; 317 };
329 318
330 switch (cmd) { 319 switch (cmd) {
@@ -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 */
402static int 391static int wdrtas_open(struct inode *inode, struct file *file)
403wdrtas_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 */
426static int 414static int wdrtas_close(struct inode *inode, struct file *file)
427wdrtas_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 */
456static ssize_t 443static ssize_t wdrtas_temp_read(struct file *file, char __user *buf,
457wdrtas_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 */
481static int 467static int wdrtas_temp_open(struct inode *inode, struct file *file)
482wdrtas_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 */
496static int 481static int wdrtas_temp_close(struct inode *inode, struct file *file)
497wdrtas_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 */
512static int 496static int wdrtas_reboot(struct notifier_block *this,
513wdrtas_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 */
565static int 549static int wdrtas_get_tokens(void)
566wdrtas_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 */
606static void 589static void wdrtas_unregister_devs(void)
607wdrtas_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 */
622static int 604static int wdrtas_register_devs(void)
623wdrtas_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 */
654static int __init 635static int __init wdrtas_init(void)
655wdrtas_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 */
683static void __exit 663static void __exit wdrtas_exit(void)
684wdrtas_exit(void)
685{ 664{
686 if (!wdrtas_nowayout) 665 if (!wdrtas_nowayout)
687 wdrtas_timer_stop(); 666 wdrtas_timer_stop();