7ac56387fe9e035b352165848fd2bac1c0ab269b
[openwrt.git] / target / linux / brcm47xx / patches-3.6 / 540-watchdog-bcm47xx_wdt.c-convert-to-watchdog-core-api.patch
1 --- a/drivers/watchdog/Kconfig
2 +++ b/drivers/watchdog/Kconfig
3 @@ -959,6 +959,7 @@ config ATH79_WDT
4  config BCM47XX_WDT
5         tristate "Broadcom BCM47xx Watchdog Timer"
6         depends on BCM47XX
7 +       select WATCHDOG_CORE
8         help
9           Hardware driver for the Broadcom BCM47xx Watchdog Timer.
10  
11 --- a/drivers/watchdog/bcm47xx_wdt.c
12 +++ b/drivers/watchdog/bcm47xx_wdt.c
13 @@ -14,15 +14,12 @@
14  
15  #include <linux/bitops.h>
16  #include <linux/errno.h>
17 -#include <linux/fs.h>
18  #include <linux/init.h>
19  #include <linux/kernel.h>
20 -#include <linux/miscdevice.h>
21  #include <linux/module.h>
22  #include <linux/moduleparam.h>
23  #include <linux/reboot.h>
24  #include <linux/types.h>
25 -#include <linux/uaccess.h>
26  #include <linux/watchdog.h>
27  #include <linux/timer.h>
28  #include <linux/jiffies.h>
29 @@ -48,8 +45,6 @@ MODULE_PARM_DESC(nowayout,
30                                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
31  #endif
32  
33 -static unsigned long bcm47xx_wdt_busy;
34 -static char expect_release;
35  static struct timer_list wdt_timer;
36  static atomic_t ticks;
37  
38 @@ -97,29 +92,31 @@ static void bcm47xx_timer_tick(unsigned
39         }
40  }
41  
42 -static inline void bcm47xx_wdt_pet(void)
43 +static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd)
44  {
45         atomic_set(&ticks, wdt_time);
46 +
47 +       return 0;
48  }
49  
50 -static void bcm47xx_wdt_start(void)
51 +static int bcm47xx_wdt_start(struct watchdog_device *wdd)
52  {
53         bcm47xx_wdt_pet();
54         bcm47xx_timer_tick(0);
55 +
56 +       return 0;
57  }
58  
59 -static void bcm47xx_wdt_pause(void)
60 +static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
61  {
62         del_timer_sync(&wdt_timer);
63         bcm47xx_wdt_hw_stop();
64 -}
65  
66 -static void bcm47xx_wdt_stop(void)
67 -{
68 -       bcm47xx_wdt_pause();
69 +       return 0;
70  }
71  
72 -static int bcm47xx_wdt_settimeout(int new_time)
73 +static int bcm47xx_wdt_set_timeout(struct watchdog_device *wdd,
74 +                                  unsigned int new_time)
75  {
76         if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
77                 return -EINVAL;
78 @@ -128,51 +125,6 @@ static int bcm47xx_wdt_settimeout(int ne
79         return 0;
80  }
81  
82 -static int bcm47xx_wdt_open(struct inode *inode, struct file *file)
83 -{
84 -       if (test_and_set_bit(0, &bcm47xx_wdt_busy))
85 -               return -EBUSY;
86 -
87 -       bcm47xx_wdt_start();
88 -       return nonseekable_open(inode, file);
89 -}
90 -
91 -static int bcm47xx_wdt_release(struct inode *inode, struct file *file)
92 -{
93 -       if (expect_release == 42) {
94 -               bcm47xx_wdt_stop();
95 -       } else {
96 -               pr_crit("Unexpected close, not stopping watchdog!\n");
97 -               bcm47xx_wdt_start();
98 -       }
99 -
100 -       clear_bit(0, &bcm47xx_wdt_busy);
101 -       expect_release = 0;
102 -       return 0;
103 -}
104 -
105 -static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data,
106 -                               size_t len, loff_t *ppos)
107 -{
108 -       if (len) {
109 -               if (!nowayout) {
110 -                       size_t i;
111 -
112 -                       expect_release = 0;
113 -
114 -                       for (i = 0; i != len; i++) {
115 -                               char c;
116 -                               if (get_user(c, data + i))
117 -                                       return -EFAULT;
118 -                               if (c == 'V')
119 -                                       expect_release = 42;
120 -                       }
121 -               }
122 -               bcm47xx_wdt_pet();
123 -       }
124 -       return len;
125 -}
126 -
127  static const struct watchdog_info bcm47xx_wdt_info = {
128         .identity       = DRV_NAME,
129         .options        = WDIOF_SETTIMEOUT |
130 @@ -180,80 +132,25 @@ static const struct watchdog_info bcm47x
131                                 WDIOF_MAGICCLOSE,
132  };
133  
134 -static long bcm47xx_wdt_ioctl(struct file *file,
135 -                                       unsigned int cmd, unsigned long arg)
136 -{
137 -       void __user *argp = (void __user *)arg;
138 -       int __user *p = argp;
139 -       int new_value, retval = -EINVAL;
140 -
141 -       switch (cmd) {
142 -       case WDIOC_GETSUPPORT:
143 -               return copy_to_user(argp, &bcm47xx_wdt_info,
144 -                               sizeof(bcm47xx_wdt_info)) ? -EFAULT : 0;
145 -
146 -       case WDIOC_GETSTATUS:
147 -       case WDIOC_GETBOOTSTATUS:
148 -               return put_user(0, p);
149 -
150 -       case WDIOC_SETOPTIONS:
151 -               if (get_user(new_value, p))
152 -                       return -EFAULT;
153 -
154 -               if (new_value & WDIOS_DISABLECARD) {
155 -                       bcm47xx_wdt_stop();
156 -                       retval = 0;
157 -               }
158 -
159 -               if (new_value & WDIOS_ENABLECARD) {
160 -                       bcm47xx_wdt_start();
161 -                       retval = 0;
162 -               }
163 -
164 -               return retval;
165 -
166 -       case WDIOC_KEEPALIVE:
167 -               bcm47xx_wdt_pet();
168 -               return 0;
169 -
170 -       case WDIOC_SETTIMEOUT:
171 -               if (get_user(new_value, p))
172 -                       return -EFAULT;
173 -
174 -               if (bcm47xx_wdt_settimeout(new_value))
175 -                       return -EINVAL;
176 -
177 -               bcm47xx_wdt_pet();
178 -
179 -       case WDIOC_GETTIMEOUT:
180 -               return put_user(wdt_time, p);
181 -
182 -       default:
183 -               return -ENOTTY;
184 -       }
185 -}
186 -
187  static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
188 -       unsigned long code, void *unused)
189 +                                 unsigned long code, void *unused)
190  {
191         if (code == SYS_DOWN || code == SYS_HALT)
192                 bcm47xx_wdt_stop();
193         return NOTIFY_DONE;
194  }
195  
196 -static const struct file_operations bcm47xx_wdt_fops = {
197 +static struct watchdog_ops bcm47xx_wdt_ops = {
198         .owner          = THIS_MODULE,
199 -       .llseek         = no_llseek,
200 -       .unlocked_ioctl = bcm47xx_wdt_ioctl,
201 -       .open           = bcm47xx_wdt_open,
202 -       .release        = bcm47xx_wdt_release,
203 -       .write          = bcm47xx_wdt_write,
204 +       .start          = bcm47xx_wdt_start,
205 +       .stop           = bcm47xx_wdt_stop,
206 +       .ping           = bcm47xx_wdt_keepalive,
207 +       .set_timeout    = bcm47xx_wdt_set_timeout,
208  };
209  
210 -static struct miscdevice bcm47xx_wdt_miscdev = {
211 -       .minor          = WATCHDOG_MINOR,
212 -       .name           = "watchdog",
213 -       .fops           = &bcm47xx_wdt_fops,
214 +static struct watchdog_device bcm47xx_wdt_wdd = {
215 +       .info           = &bcm47xx_wdt_info,
216 +       .ops            = &bcm47xx_wdt_ops,
217  };
218  
219  static struct notifier_block bcm47xx_wdt_notifier = {
220 @@ -274,12 +171,13 @@ static int __init bcm47xx_wdt_init(void)
221                 pr_info("wdt_time value must be 0 < wdt_time < %d, using %d\n",
222                         (WDT_MAX_TIME + 1), wdt_time);
223         }
224 +       watchdog_set_nowayout(&bcm47xx_wdt_wdd, nowayout);
225  
226         ret = register_reboot_notifier(&bcm47xx_wdt_notifier);
227         if (ret)
228                 return ret;
229  
230 -       ret = misc_register(&bcm47xx_wdt_miscdev);
231 +       ret = watchdog_register_device(&bcm47xx_wdt_wdd);
232         if (ret) {
233                 unregister_reboot_notifier(&bcm47xx_wdt_notifier);
234                 return ret;
235 @@ -292,10 +190,8 @@ static int __init bcm47xx_wdt_init(void)
236  
237  static void __exit bcm47xx_wdt_exit(void)
238  {
239 -       if (!nowayout)
240 -               bcm47xx_wdt_stop();
241 -
242 -       misc_deregister(&bcm47xx_wdt_miscdev);
243 +       watchdog_stop(&bcm47xx_wdt_wdd);
244 +       watchdog_unregister_device(&bcm47xx_wdt_wdd);
245  
246         unregister_reboot_notifier(&bcm47xx_wdt_notifier);
247  }
248 @@ -306,4 +202,3 @@ module_exit(bcm47xx_wdt_exit);
249  MODULE_AUTHOR("Aleksandar Radovanovic");
250  MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx");
251  MODULE_LICENSE("GPL");
252 -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);