1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
--- a/drivers/cbus/retu-wdt.c
+++ b/drivers/cbus/retu-wdt.c
@@ -7,6 +7,8 @@
*
* Written by Amit Kucheria <amit.kucheria@nokia.com>
*
+ * Cleanups by Michael Buesch <mb@bu3sch.de> (C) 2011
+ *
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of this
* archive for more details.
@@ -48,37 +50,31 @@
#define RETU_WDT_DEFAULT_TIMER 32
#define RETU_WDT_MAX_TIMER 63
-static DEFINE_MUTEX(retu_wdt_mutex);
-
-/* Current period of watchdog */
-static unsigned int period_val = RETU_WDT_DEFAULT_TIMER;
-
struct retu_wdt_dev {
struct device *dev;
+ unsigned int period_val; /* Current period of watchdog */
unsigned long users;
- struct miscdevice retu_wdt_miscdev;
+ struct miscdevice miscdev;
struct delayed_work ping_work;
+ struct mutex mutex;
};
-static struct retu_wdt_dev *retu_wdt;
-static int _retu_modify_counter(unsigned int new)
+static inline void _retu_modify_counter(struct retu_wdt_dev *wdev,
+ unsigned int new)
{
- if (retu_wdt)
- retu_write_reg(retu_wdt->dev, RETU_REG_WATCHDOG, (u16)new);
-
- return 0;
+ retu_write_reg(wdev->dev, RETU_REG_WATCHDOG, (u16)new);
}
-static int retu_modify_counter(unsigned int new)
+static int retu_modify_counter(struct retu_wdt_dev *wdev, unsigned int new)
{
if (new < RETU_WDT_MIN_TIMER || new > RETU_WDT_MAX_TIMER)
return -EINVAL;
- mutex_lock(&retu_wdt_mutex);
- period_val = new;
- _retu_modify_counter(period_val);
- mutex_unlock(&retu_wdt_mutex);
+ mutex_lock(&wdev->mutex);
+ wdev->period_val = new;
+ _retu_modify_counter(wdev, wdev->period_val);
+ mutex_unlock(&wdev->mutex);
return 0;
}
@@ -90,14 +86,14 @@ static int retu_modify_counter(unsigned
*/
static void retu_wdt_ping_enable(struct retu_wdt_dev *wdev)
{
- _retu_modify_counter(RETU_WDT_MAX_TIMER);
+ _retu_modify_counter(wdev, RETU_WDT_MAX_TIMER);
schedule_delayed_work(&wdev->ping_work,
round_jiffies_relative(RETU_WDT_DEFAULT_TIMER * HZ));
}
static void retu_wdt_ping_disable(struct retu_wdt_dev *wdev)
{
- _retu_modify_counter(RETU_WDT_MAX_TIMER);
+ _retu_modify_counter(wdev, RETU_WDT_MAX_TIMER);
cancel_delayed_work_sync(&wdev->ping_work);
}
@@ -110,18 +106,21 @@ static void retu_wdt_ping_work(struct wo
static int retu_wdt_open(struct inode *inode, struct file *file)
{
- if (test_and_set_bit(0, &retu_wdt->users))
+ struct miscdevice *mdev = file->private_data;
+ struct retu_wdt_dev *wdev = container_of(mdev, struct retu_wdt_dev, miscdev);
+
+ if (test_and_set_bit(0, &wdev->users))
return -EBUSY;
- file->private_data = (void *)retu_wdt;
- retu_wdt_ping_disable(retu_wdt);
+ retu_wdt_ping_disable(wdev);
return nonseekable_open(inode, file);
}
static int retu_wdt_release(struct inode *inode, struct file *file)
{
- struct retu_wdt_dev *wdev = file->private_data;
+ struct miscdevice *mdev = file->private_data;
+ struct retu_wdt_dev *wdev = container_of(mdev, struct retu_wdt_dev, miscdev);
#ifndef CONFIG_WATCHDOG_NOWAYOUT
retu_wdt_ping_enable(wdev);
@@ -134,8 +133,11 @@ static int retu_wdt_release(struct inode
static ssize_t retu_wdt_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
+ struct miscdevice *mdev = file->private_data;
+ struct retu_wdt_dev *wdev = container_of(mdev, struct retu_wdt_dev, miscdev);
+
if (len)
- retu_modify_counter(RETU_WDT_MAX_TIMER);
+ retu_modify_counter(wdev, RETU_WDT_MAX_TIMER);
return len;
}
@@ -143,6 +145,8 @@ static ssize_t retu_wdt_write(struct fil
static long retu_wdt_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ struct miscdevice *mdev = file->private_data;
+ struct retu_wdt_dev *wdev = container_of(mdev, struct retu_wdt_dev, miscdev);
int new_margin;
static struct watchdog_info ident = {
@@ -167,15 +171,15 @@ static long retu_wdt_ioctl(struct file *
return put_user(omap_prcm_get_reset_sources(),
(int __user *)arg);
case WDIOC_KEEPALIVE:
- retu_modify_counter(RETU_WDT_MAX_TIMER);
+ retu_modify_counter(wdev, RETU_WDT_MAX_TIMER);
break;
case WDIOC_SETTIMEOUT:
if (get_user(new_margin, (int __user *)arg))
return -EFAULT;
- retu_modify_counter(new_margin);
+ retu_modify_counter(wdev, new_margin);
/* Fall through */
case WDIOC_GETTIMEOUT:
- return put_user(period_val, (int __user *)arg);
+ return put_user(wdev->period_val, (int __user *)arg);
}
return 0;
@@ -199,15 +203,17 @@ static int __init retu_wdt_probe(struct
return -ENOMEM;
wdev->dev = &pdev->dev;
+ wdev->period_val = RETU_WDT_DEFAULT_TIMER;
+ mutex_init(&wdev->mutex);
platform_set_drvdata(pdev, wdev);
- retu_wdt = wdev;
- wdev->retu_wdt_miscdev.parent = &pdev->dev;
- wdev->retu_wdt_miscdev.minor = WATCHDOG_MINOR;
- wdev->retu_wdt_miscdev.name = "watchdog";
- wdev->retu_wdt_miscdev.fops = &retu_wdt_fops;
- ret = misc_register(&(wdev->retu_wdt_miscdev));
+ wdev->miscdev.parent = &pdev->dev;
+ wdev->miscdev.minor = WATCHDOG_MINOR;
+ wdev->miscdev.name = "watchdog";
+ wdev->miscdev.fops = &retu_wdt_fops;
+
+ ret = misc_register(&wdev->miscdev);
if (ret)
goto err_free_wdev;
@@ -216,9 +222,9 @@ static int __init retu_wdt_probe(struct
/* Kick the watchdog for kernel booting to finish.
* If nowayout is not set, we start the ping work. */
#ifdef CONFIG_WATCHDOG_NOWAYOUT
- retu_modify_counter(RETU_WDT_MAX_TIMER);
+ retu_modify_counter(wdev, RETU_WDT_MAX_TIMER);
#else
- retu_wdt_ping_enable(retu_wdt);
+ retu_wdt_ping_enable(wdev);
#endif
return 0;
@@ -234,7 +240,7 @@ static int __devexit retu_wdt_remove(str
struct retu_wdt_dev *wdev;
wdev = platform_get_drvdata(pdev);
- misc_deregister(&wdev->retu_wdt_miscdev);
+ misc_deregister(&wdev->miscdev);
cancel_delayed_work_sync(&wdev->ping_work);
kfree(wdev);
|