Commit e75e657756554676f13070266bedbd75d404a0f8
1 parent
28401140a2
Exists in
master
and in
7 other branches
[WATCHDOG] at32ap700x_wdt.c - Add spinlock support
Add spinlock support so that forked children can't do different io stuff at the same time. Signed-off-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com> Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be> Cc: Andrew Morton <akpm@linux-foundation.org>
Showing 1 changed file with 9 additions and 0 deletions Side-by-side Diff
drivers/char/watchdog/at32ap700x_wdt.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | #include <linux/watchdog.h> |
19 | 19 | #include <linux/uaccess.h> |
20 | 20 | #include <linux/io.h> |
21 | +#include <linux/spinlock.h> | |
21 | 22 | |
22 | 23 | #define TIMEOUT_MIN 1 |
23 | 24 | #define TIMEOUT_MAX 2 |
... | ... | @@ -53,6 +54,7 @@ |
53 | 54 | |
54 | 55 | struct wdt_at32ap700x { |
55 | 56 | void __iomem *regs; |
57 | + spinlock_t io_lock; | |
56 | 58 | int timeout; |
57 | 59 | int users; |
58 | 60 | struct miscdevice miscdev; |
59 | 61 | |
... | ... | @@ -66,9 +68,11 @@ |
66 | 68 | */ |
67 | 69 | static inline void at32_wdt_stop(void) |
68 | 70 | { |
71 | + spin_lock(&wdt->io_lock); | |
69 | 72 | unsigned long psel = wdt_readl(wdt, CTRL) & WDT_BF(CTRL_PSEL, 0x0f); |
70 | 73 | wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0x55)); |
71 | 74 | wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0xaa)); |
75 | + spin_unlock(&wdt->io_lock); | |
72 | 76 | } |
73 | 77 | |
74 | 78 | /* |
75 | 79 | |
... | ... | @@ -79,12 +83,14 @@ |
79 | 83 | /* 0xf is 2^16 divider = 2 sec, 0xe is 2^15 divider = 1 sec */ |
80 | 84 | unsigned long psel = (wdt->timeout > 1) ? 0xf : 0xe; |
81 | 85 | |
86 | + spin_lock(&wdt->io_lock); | |
82 | 87 | wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN) |
83 | 88 | | WDT_BF(CTRL_PSEL, psel) |
84 | 89 | | WDT_BF(CTRL_KEY, 0x55)); |
85 | 90 | wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN) |
86 | 91 | | WDT_BF(CTRL_PSEL, psel) |
87 | 92 | | WDT_BF(CTRL_KEY, 0xaa)); |
93 | + spin_unlock(&wdt->io_lock); | |
88 | 94 | } |
89 | 95 | |
90 | 96 | /* |
91 | 97 | |
... | ... | @@ -92,7 +98,9 @@ |
92 | 98 | */ |
93 | 99 | static inline void at32_wdt_pat(void) |
94 | 100 | { |
101 | + spin_lock(&wdt->io_lock); | |
95 | 102 | wdt_writel(wdt, CLR, 0x42); |
103 | + spin_unlock(&wdt->io_lock); | |
96 | 104 | } |
97 | 105 | |
98 | 106 | /* |
... | ... | @@ -272,6 +280,7 @@ |
272 | 280 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); |
273 | 281 | goto err_free; |
274 | 282 | } |
283 | + spin_lock_init(&wdt->io_lock); | |
275 | 284 | wdt->users = 0; |
276 | 285 | wdt->miscdev.minor = WATCHDOG_MINOR; |
277 | 286 | wdt->miscdev.name = "watchdog"; |