diff options
Diffstat (limited to 'drivers/watchdog/booke_wdt.c')
-rw-r--r-- | drivers/watchdog/booke_wdt.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index d11ffb091b0..7e7ec9c35b6 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -85,6 +85,22 @@ static unsigned int sec_to_period(unsigned int secs) | |||
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | static void __booke_wdt_set(void *data) | ||
89 | { | ||
90 | u32 val; | ||
91 | |||
92 | val = mfspr(SPRN_TCR); | ||
93 | val &= ~WDTP_MASK; | ||
94 | val |= WDTP(booke_wdt_period); | ||
95 | |||
96 | mtspr(SPRN_TCR, val); | ||
97 | } | ||
98 | |||
99 | static void booke_wdt_set(void) | ||
100 | { | ||
101 | on_each_cpu(__booke_wdt_set, NULL, 0); | ||
102 | } | ||
103 | |||
88 | static void __booke_wdt_ping(void *data) | 104 | static void __booke_wdt_ping(void *data) |
89 | { | 105 | { |
90 | mtspr(SPRN_TSR, TSR_ENW|TSR_WIS); | 106 | mtspr(SPRN_TSR, TSR_ENW|TSR_WIS); |
@@ -181,8 +197,7 @@ static long booke_wdt_ioctl(struct file *file, | |||
181 | #else | 197 | #else |
182 | booke_wdt_period = tmp; | 198 | booke_wdt_period = tmp; |
183 | #endif | 199 | #endif |
184 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP_MASK) | | 200 | booke_wdt_set(); |
185 | WDTP(booke_wdt_period)); | ||
186 | return 0; | 201 | return 0; |
187 | case WDIOC_GETTIMEOUT: | 202 | case WDIOC_GETTIMEOUT: |
188 | return put_user(booke_wdt_period, p); | 203 | return put_user(booke_wdt_period, p); |
@@ -193,8 +208,15 @@ static long booke_wdt_ioctl(struct file *file, | |||
193 | return 0; | 208 | return 0; |
194 | } | 209 | } |
195 | 210 | ||
211 | /* wdt_is_active stores wether or not the /dev/watchdog device is opened */ | ||
212 | static unsigned long wdt_is_active; | ||
213 | |||
196 | static int booke_wdt_open(struct inode *inode, struct file *file) | 214 | static int booke_wdt_open(struct inode *inode, struct file *file) |
197 | { | 215 | { |
216 | /* /dev/watchdog can only be opened once */ | ||
217 | if (test_and_set_bit(0, &wdt_is_active)) | ||
218 | return -EBUSY; | ||
219 | |||
198 | spin_lock(&booke_wdt_lock); | 220 | spin_lock(&booke_wdt_lock); |
199 | if (booke_wdt_enabled == 0) { | 221 | if (booke_wdt_enabled == 0) { |
200 | booke_wdt_enabled = 1; | 222 | booke_wdt_enabled = 1; |
@@ -210,8 +232,17 @@ static int booke_wdt_open(struct inode *inode, struct file *file) | |||
210 | 232 | ||
211 | static int booke_wdt_release(struct inode *inode, struct file *file) | 233 | static int booke_wdt_release(struct inode *inode, struct file *file) |
212 | { | 234 | { |
235 | #ifndef CONFIG_WATCHDOG_NOWAYOUT | ||
236 | /* Normally, the watchdog is disabled when /dev/watchdog is closed, but | ||
237 | * if CONFIG_WATCHDOG_NOWAYOUT is defined, then it means that the | ||
238 | * watchdog should remain enabled. So we disable it only if | ||
239 | * CONFIG_WATCHDOG_NOWAYOUT is not defined. | ||
240 | */ | ||
213 | on_each_cpu(__booke_wdt_disable, NULL, 0); | 241 | on_each_cpu(__booke_wdt_disable, NULL, 0); |
214 | booke_wdt_enabled = 0; | 242 | booke_wdt_enabled = 0; |
243 | #endif | ||
244 | |||
245 | clear_bit(0, &wdt_is_active); | ||
215 | 246 | ||
216 | return 0; | 247 | return 0; |
217 | } | 248 | } |