@@ -48,6 +48,7 @@ struct sunxi_wdt_reg {
48
48
u8 wdt_timeout_shift ;
49
49
u8 wdt_reset_mask ;
50
50
u8 wdt_reset_val ;
51
+ u32 wdt_key_val ;
51
52
};
52
53
53
54
struct sunxi_wdt_dev {
@@ -91,12 +92,14 @@ static int sunxi_wdt_restart(struct watchdog_device *wdt_dev,
91
92
val = readl (wdt_base + regs -> wdt_cfg );
92
93
val &= ~(regs -> wdt_reset_mask );
93
94
val |= regs -> wdt_reset_val ;
95
+ val |= regs -> wdt_key_val ;
94
96
writel (val , wdt_base + regs -> wdt_cfg );
95
97
96
98
/* Set lowest timeout and enable watchdog */
97
99
val = readl (wdt_base + regs -> wdt_mode );
98
100
val &= ~(WDT_TIMEOUT_MASK << regs -> wdt_timeout_shift );
99
101
val |= WDT_MODE_EN ;
102
+ val |= regs -> wdt_key_val ;
100
103
writel (val , wdt_base + regs -> wdt_mode );
101
104
102
105
/*
@@ -109,6 +112,7 @@ static int sunxi_wdt_restart(struct watchdog_device *wdt_dev,
109
112
mdelay (5 );
110
113
val = readl (wdt_base + regs -> wdt_mode );
111
114
val |= WDT_MODE_EN ;
115
+ val |= regs -> wdt_key_val ;
112
116
writel (val , wdt_base + regs -> wdt_mode );
113
117
}
114
118
return 0 ;
@@ -141,6 +145,7 @@ static int sunxi_wdt_set_timeout(struct watchdog_device *wdt_dev,
141
145
reg = readl (wdt_base + regs -> wdt_mode );
142
146
reg &= ~(WDT_TIMEOUT_MASK << regs -> wdt_timeout_shift );
143
147
reg |= wdt_timeout_map [timeout ] << regs -> wdt_timeout_shift ;
148
+ reg |= regs -> wdt_key_val ;
144
149
writel (reg , wdt_base + regs -> wdt_mode );
145
150
146
151
sunxi_wdt_ping (wdt_dev );
@@ -154,7 +159,7 @@ static int sunxi_wdt_stop(struct watchdog_device *wdt_dev)
154
159
void __iomem * wdt_base = sunxi_wdt -> wdt_base ;
155
160
const struct sunxi_wdt_reg * regs = sunxi_wdt -> wdt_regs ;
156
161
157
- writel (0 , wdt_base + regs -> wdt_mode );
162
+ writel (regs -> wdt_key_val , wdt_base + regs -> wdt_mode );
158
163
159
164
return 0 ;
160
165
}
@@ -176,11 +181,13 @@ static int sunxi_wdt_start(struct watchdog_device *wdt_dev)
176
181
reg = readl (wdt_base + regs -> wdt_cfg );
177
182
reg &= ~(regs -> wdt_reset_mask );
178
183
reg |= regs -> wdt_reset_val ;
184
+ reg |= regs -> wdt_key_val ;
179
185
writel (reg , wdt_base + regs -> wdt_cfg );
180
186
181
187
/* Enable watchdog */
182
188
reg = readl (wdt_base + regs -> wdt_mode );
183
189
reg |= WDT_MODE_EN ;
190
+ reg |= regs -> wdt_key_val ;
184
191
writel (reg , wdt_base + regs -> wdt_mode );
185
192
186
193
return 0 ;
@@ -220,9 +227,20 @@ static const struct sunxi_wdt_reg sun6i_wdt_reg = {
220
227
.wdt_reset_val = 0x01 ,
221
228
};
222
229
230
+ static const struct sunxi_wdt_reg sun20i_wdt_reg = {
231
+ .wdt_ctrl = 0x10 ,
232
+ .wdt_cfg = 0x14 ,
233
+ .wdt_mode = 0x18 ,
234
+ .wdt_timeout_shift = 4 ,
235
+ .wdt_reset_mask = 0x03 ,
236
+ .wdt_reset_val = 0x01 ,
237
+ .wdt_key_val = 0x16aa0000 ,
238
+ };
239
+
223
240
static const struct of_device_id sunxi_wdt_dt_ids [] = {
224
241
{ .compatible = "allwinner,sun4i-a10-wdt" , .data = & sun4i_wdt_reg },
225
242
{ .compatible = "allwinner,sun6i-a31-wdt" , .data = & sun6i_wdt_reg },
243
+ { .compatible = "allwinner,sun20i-d1-wdt" , .data = & sun20i_wdt_reg },
226
244
{ /* sentinel */ }
227
245
};
228
246
MODULE_DEVICE_TABLE (of , sunxi_wdt_dt_ids );
0 commit comments