aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/ixp2000_wdt.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-05-19 09:06:42 -0400
committerWim Van Sebroeck <wim@iguana.be>2008-06-13 14:57:01 -0400
commit640b4f685784feafcd99c24582c5eb3ea36c3c60 (patch)
tree46682cb99f63ef7f6ceaddd79dac43d648dba022 /drivers/watchdog/ixp2000_wdt.c
parent00e9c2059aba0a0d67d144229bac82d403c2f42a (diff)
[WATCHDOG 21/57] ixp2000_wdt: clean up and unlocked_ioctl
Review and switch to unlocked_ioctl Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/ixp2000_wdt.c')
-rw-r--r--drivers/watchdog/ixp2000_wdt.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index dc7548dcaf35..943ceffbd683 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -25,42 +25,45 @@
25#include <linux/watchdog.h> 25#include <linux/watchdog.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/bitops.h> 27#include <linux/bitops.h>
28#include <linux/uaccess.h>
28 29
29#include <asm/hardware.h> 30#include <asm/hardware.h>
30#include <asm/uaccess.h>
31 31
32static int nowayout = WATCHDOG_NOWAYOUT; 32static int nowayout = WATCHDOG_NOWAYOUT;
33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ 33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
34static unsigned long wdt_status; 34static unsigned long wdt_status;
35static spinlock_t wdt_lock;
35 36
36#define WDT_IN_USE 0 37#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 38#define WDT_OK_TO_CLOSE 1
38 39
39static unsigned long wdt_tick_rate; 40static unsigned long wdt_tick_rate;
40 41
41static void 42static void wdt_enable(void)
42wdt_enable(void)
43{ 43{
44 spin_lock(&wdt_lock);
44 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); 45 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
45 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); 46 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
46 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 47 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
47 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); 48 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
49 spin_unlock(&wdt_lock);
48} 50}
49 51
50static void 52static void wdt_disable(void)
51wdt_disable(void)
52{ 53{
54 spin_lock(&wdt_lock);
53 ixp2000_reg_write(IXP2000_T4_CTL, 0); 55 ixp2000_reg_write(IXP2000_T4_CTL, 0);
56 spin_unlock(&wdt_lock);
54} 57}
55 58
56static void 59static void wdt_keepalive(void)
57wdt_keepalive(void)
58{ 60{
61 spin_lock(&wdt_lock);
59 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 62 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
63 spin_unlock(&wdt_lock);
60} 64}
61 65
62static int 66static int ixp2000_wdt_open(struct inode *inode, struct file *file)
63ixp2000_wdt_open(struct inode *inode, struct file *file)
64{ 67{
65 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 68 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
66 return -EBUSY; 69 return -EBUSY;
@@ -72,8 +75,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file)
72 return nonseekable_open(inode, file); 75 return nonseekable_open(inode, file);
73} 76}
74 77
75static ssize_t 78static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
76ixp2000_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 79 size_t len, loff_t *ppos)
77{ 80{
78 if (len) { 81 if (len) {
79 if (!nowayout) { 82 if (!nowayout) {
@@ -103,9 +106,8 @@ static struct watchdog_info ident = {
103 .identity = "IXP2000 Watchdog", 106 .identity = "IXP2000 Watchdog",
104}; 107};
105 108
106static int 109static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
107ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 110 unsigned long arg)
108 unsigned long arg)
109{ 111{
110 int ret = -ENOTTY; 112 int ret = -ENOTTY;
111 int time; 113 int time;
@@ -151,16 +153,13 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
151 return ret; 153 return ret;
152} 154}
153 155
154static int 156static int ixp2000_wdt_release(struct inode *inode, struct file *file)
155ixp2000_wdt_release(struct inode *inode, struct file *file)
156{ 157{
157 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 158 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
158 wdt_disable(); 159 wdt_disable();
159 } else { 160 else
160 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 161 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
161 "timer will not stop\n"); 162 "timer will not stop\n");
162 }
163
164 clear_bit(WDT_IN_USE, &wdt_status); 163 clear_bit(WDT_IN_USE, &wdt_status);
165 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 164 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
166 165
@@ -168,18 +167,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
168} 167}
169 168
170 169
171static const struct file_operations ixp2000_wdt_fops = 170static const struct file_operations ixp2000_wdt_fops = {
172{
173 .owner = THIS_MODULE, 171 .owner = THIS_MODULE,
174 .llseek = no_llseek, 172 .llseek = no_llseek,
175 .write = ixp2000_wdt_write, 173 .write = ixp2000_wdt_write,
176 .ioctl = ixp2000_wdt_ioctl, 174 .unlocked_ioctl = ixp2000_wdt_ioctl,
177 .open = ixp2000_wdt_open, 175 .open = ixp2000_wdt_open,
178 .release = ixp2000_wdt_release, 176 .release = ixp2000_wdt_release,
179}; 177};
180 178
181static struct miscdevice ixp2000_wdt_miscdev = 179static struct miscdevice ixp2000_wdt_miscdev = {
182{
183 .minor = WATCHDOG_MINOR, 180 .minor = WATCHDOG_MINOR,
184 .name = "watchdog", 181 .name = "watchdog",
185 .fops = &ixp2000_wdt_fops, 182 .fops = &ixp2000_wdt_fops,
@@ -191,9 +188,8 @@ static int __init ixp2000_wdt_init(void)
191 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); 188 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
192 return -EIO; 189 return -EIO;
193 } 190 }
194
195 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; 191 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
196 192 spin_lock_init(&wdt_lock);
197 return misc_register(&ixp2000_wdt_miscdev); 193 return misc_register(&ixp2000_wdt_miscdev);
198} 194}
199 195