Blame view

drivers/watchdog/wdt285.c 4.57 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
  /*
   *	Intel 21285 watchdog driver
   *	Copyright (c) Phil Blundell <pb@nexus.co.uk>, 1998
   *
   *	based on
   *
   *	SoftDog	0.05:	A Software Watchdog Device
   *
29fa0586d   Alan Cox   [PATCH] Switch al...
10
11
   *	(c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
   *						All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
   */
27c766aaa   Joe Perches   watchdog: Use pr_...
13
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
19
20
21
22
23
24
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/fs.h>
  #include <linux/mm.h>
  #include <linux/miscdevice.h>
  #include <linux/watchdog.h>
  #include <linux/reboot.h>
  #include <linux/init.h>
  #include <linux/interrupt.h>
d0e58eed0   Alan Cox   [WATCHDOG 55/57] ...
25
26
  #include <linux/uaccess.h>
  #include <linux/irq.h>
a09e64fbc   Russell King   [ARM] Move includ...
27
  #include <mach/hardware.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include <asm/mach-types.h>
9f97da78b   David Howells   Disintegrate asm/...
30
  #include <asm/system_info.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  #include <asm/hardware/dec21285.h>
  
  /*
   * Define this to stop the watchdog actually rebooting the machine.
   */
  #undef ONLY_TESTING
  
  static unsigned int soft_margin = 60;		/* in seconds */
  static unsigned int reload;
  static unsigned long timer_alive;
  
  #ifdef ONLY_TESTING
  /*
   *	If the timer expires..
   */
7d12e780e   David Howells   IRQ: Maintain reg...
46
  static void watchdog_fire(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
  {
27c766aaa   Joe Perches   watchdog: Use pr_...
48
49
  	pr_crit("Would Reboot
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  	*CSR_TIMER4_CNTL = 0;
  	*CSR_TIMER4_CLR = 0;
  }
  #endif
  
  /*
   *	Refresh the timer.
   */
  static void watchdog_ping(void)
  {
  	*CSR_TIMER4_LOAD = reload;
  }
  
  /*
   *	Allow only one person to hold it open
   */
  static int watchdog_open(struct inode *inode, struct file *file)
  {
  	int ret;
  
  	if (*CSR_SA110_CNTL & (1 << 13))
  		return -EBUSY;
  
  	if (test_and_set_bit(1, &timer_alive))
  		return -EBUSY;
  
  	reload = soft_margin * (mem_fclk_21285 / 256);
  
  	*CSR_TIMER4_CLR = 0;
  	watchdog_ping();
  	*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD
  		| TIMER_CNTL_DIV256;
  
  #ifdef ONLY_TESTING
  	ret = request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL);
  	if (ret) {
  		*CSR_TIMER4_CNTL = 0;
  		clear_bit(1, &timer_alive);
  	}
  #else
  	/*
  	 * Setting this bit is irreversible; once enabled, there is
  	 * no way to disable the watchdog.
  	 */
  	*CSR_SA110_CNTL |= 1 << 13;
  
  	ret = 0;
  #endif
c5bf68fe0   Kirill Smelkov   *: convert stream...
98
  	stream_open(inode, file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  	return ret;
  }
  
  /*
   *	Shut off the timer.
   *	Note: if we really have enabled the watchdog, there
   *	is no way to turn off.
   */
  static int watchdog_release(struct inode *inode, struct file *file)
  {
  #ifdef ONLY_TESTING
  	free_irq(IRQ_TIMER4, NULL);
  	clear_bit(1, &timer_alive);
  #endif
  	return 0;
  }
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
115
116
  static ssize_t watchdog_write(struct file *file, const char __user *data,
  			      size_t len, loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
121
122
123
124
125
  {
  	/*
  	 *	Refresh the timer.
  	 */
  	if (len)
  		watchdog_ping();
  
  	return len;
  }
d0e58eed0   Alan Cox   [WATCHDOG 55/57] ...
126
  static const struct watchdog_info ident = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
  	.options	= WDIOF_SETTIMEOUT,
  	.identity	= "Footbridge Watchdog",
  };
d0e58eed0   Alan Cox   [WATCHDOG 55/57] ...
130
  static long watchdog_ioctl(struct file *file, unsigned int cmd,
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
131
  			   unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  {
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
133
  	int __user *int_arg = (int __user *)arg;
70605d9ba   Alexander Shiyan   watchdog: wdt285:...
134
  	int new_margin, ret = -ENOTTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135

d0e58eed0   Alan Cox   [WATCHDOG 55/57] ...
136
  	switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
  	case WDIOC_GETSUPPORT:
  		ret = 0;
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
139
  		if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
144
  			ret = -EFAULT;
  		break;
  
  	case WDIOC_GETSTATUS:
  	case WDIOC_GETBOOTSTATUS:
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
145
  		ret = put_user(0, int_arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
148
149
150
151
152
153
  		break;
  
  	case WDIOC_KEEPALIVE:
  		watchdog_ping();
  		ret = 0;
  		break;
  
  	case WDIOC_SETTIMEOUT:
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
154
  		ret = get_user(new_margin, int_arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
156
157
158
159
160
161
162
163
164
165
166
  		if (ret)
  			break;
  
  		/* Arbitrary, can't find the card's limits */
  		if (new_margin < 0 || new_margin > 60) {
  			ret = -EINVAL;
  			break;
  		}
  
  		soft_margin = new_margin;
  		reload = soft_margin * (mem_fclk_21285 / 256);
  		watchdog_ping();
bd490f822   Gustavo A. R. Silva   watchdog: Use fal...
167
  		fallthrough;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  	case WDIOC_GETTIMEOUT:
edf86c9b9   Ben Dooks   [WATCHDOG] wdt285...
169
  		ret = put_user(soft_margin, int_arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
173
  		break;
  	}
  	return ret;
  }
62322d255   Arjan van de Ven   [PATCH] make more...
174
  static const struct file_operations watchdog_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
  	.owner		= THIS_MODULE,
  	.llseek		= no_llseek,
  	.write		= watchdog_write,
d0e58eed0   Alan Cox   [WATCHDOG 55/57] ...
178
  	.unlocked_ioctl	= watchdog_ioctl,
b6dfb2477   Arnd Bergmann   compat_ioctl: mov...
179
  	.compat_ioctl	= compat_ptr_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  	.open		= watchdog_open,
  	.release	= watchdog_release,
  };
  
  static struct miscdevice watchdog_miscdev = {
  	.minor		= WATCHDOG_MINOR,
  	.name		= "watchdog",
  	.fops		= &watchdog_fops,
  };
  
  static int __init footbridge_watchdog_init(void)
  {
  	int retval;
  
  	if (machine_is_netwinder())
  		return -ENODEV;
  
  	retval = misc_register(&watchdog_miscdev);
  	if (retval < 0)
  		return retval;
27c766aaa   Joe Perches   watchdog: Use pr_...
200
201
202
  	pr_info("Footbridge Watchdog Timer: 0.01, timer margin: %d sec
  ",
  		soft_margin);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
  
  	if (machine_is_cats())
27c766aaa   Joe Perches   watchdog: Use pr_...
205
206
  		pr_warn("Warning: Watchdog reset may not work on this machine
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
212
213
214
215
216
217
  	return 0;
  }
  
  static void __exit footbridge_watchdog_exit(void)
  {
  	misc_deregister(&watchdog_miscdev);
  }
  
  MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
  MODULE_DESCRIPTION("Footbridge watchdog driver");
  MODULE_LICENSE("GPL");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
  
  module_param(soft_margin, int, 0);
d0e58eed0   Alan Cox   [WATCHDOG 55/57] ...
220
  MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
  
  module_init(footbridge_watchdog_init);
  module_exit(footbridge_watchdog_exit);