aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/vmwatchdog.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char/vmwatchdog.c')
-rw-r--r--drivers/s390/char/vmwatchdog.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 19f8389291b6..21a2a829bf4e 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/watchdog.h> 15#include <linux/watchdog.h>
16#include <linux/smp_lock.h>
16 17
17#include <asm/ebcdic.h> 18#include <asm/ebcdic.h>
18#include <asm/io.h> 19#include <asm/io.h>
@@ -92,23 +93,15 @@ static int vmwdt_keepalive(void)
92 93
93 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init; 94 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init;
94 ret = __diag288(func, vmwdt_interval, ebc_cmd, len); 95 ret = __diag288(func, vmwdt_interval, ebc_cmd, len);
96 WARN_ON(ret != 0);
95 kfree(ebc_cmd); 97 kfree(ebc_cmd);
96
97 if (ret) {
98 printk(KERN_WARNING "%s: problem setting interval %d, "
99 "cmd %s\n", __func__, vmwdt_interval,
100 vmwdt_cmd);
101 }
102 return ret; 98 return ret;
103} 99}
104 100
105static int vmwdt_disable(void) 101static int vmwdt_disable(void)
106{ 102{
107 int ret = __diag288(wdt_cancel, 0, "", 0); 103 int ret = __diag288(wdt_cancel, 0, "", 0);
108 if (ret) { 104 WARN_ON(ret != 0);
109 printk(KERN_WARNING "%s: problem disabling watchdog\n",
110 __func__);
111 }
112 return ret; 105 return ret;
113} 106}
114 107
@@ -121,21 +114,23 @@ static int __init vmwdt_probe(void)
121 static char __initdata ebc_begin[] = { 114 static char __initdata ebc_begin[] = {
122 194, 197, 199, 201, 213 115 194, 197, 199, 201, 213
123 }; 116 };
124 if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0) { 117 if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0)
125 printk(KERN_INFO "z/VM watchdog not available\n");
126 return -EINVAL; 118 return -EINVAL;
127 }
128 return vmwdt_disable(); 119 return vmwdt_disable();
129} 120}
130 121
131static int vmwdt_open(struct inode *i, struct file *f) 122static int vmwdt_open(struct inode *i, struct file *f)
132{ 123{
133 int ret; 124 int ret;
134 if (test_and_set_bit(0, &vmwdt_is_open)) 125 lock_kernel();
126 if (test_and_set_bit(0, &vmwdt_is_open)) {
127 unlock_kernel();
135 return -EBUSY; 128 return -EBUSY;
129 }
136 ret = vmwdt_keepalive(); 130 ret = vmwdt_keepalive();
137 if (ret) 131 if (ret)
138 clear_bit(0, &vmwdt_is_open); 132 clear_bit(0, &vmwdt_is_open);
133 unlock_kernel();
139 return ret ? ret : nonseekable_open(i, f); 134 return ret ? ret : nonseekable_open(i, f);
140} 135}
141 136