8
8
#include <linux/clk.h>
9
9
#include <linux/delay.h>
10
10
#include <linux/io.h>
11
- #include <linux/iopoll.h>
12
11
#include <linux/kernel.h>
13
12
#include <linux/module.h>
14
13
#include <linux/of.h>
@@ -54,35 +53,11 @@ struct rzg2l_wdt_priv {
54
53
struct reset_control * rstc ;
55
54
unsigned long osc_clk_rate ;
56
55
unsigned long delay ;
57
- unsigned long minimum_assertion_period ;
58
56
struct clk * pclk ;
59
57
struct clk * osc_clk ;
60
58
enum rz_wdt_type devtype ;
61
59
};
62
60
63
- static int rzg2l_wdt_reset (struct rzg2l_wdt_priv * priv )
64
- {
65
- int err , status ;
66
-
67
- if (priv -> devtype == WDT_RZV2M ) {
68
- /* WDT needs TYPE-B reset control */
69
- err = reset_control_assert (priv -> rstc );
70
- if (err )
71
- return err ;
72
- ndelay (priv -> minimum_assertion_period );
73
- err = reset_control_deassert (priv -> rstc );
74
- if (err )
75
- return err ;
76
- err = read_poll_timeout (reset_control_status , status ,
77
- status != 1 , 0 , 1000 , false,
78
- priv -> rstc );
79
- } else {
80
- err = reset_control_reset (priv -> rstc );
81
- }
82
-
83
- return err ;
84
- }
85
-
86
61
static void rzg2l_wdt_wait_delay (struct rzg2l_wdt_priv * priv )
87
62
{
88
63
/* delay timer when change the setting register */
@@ -123,8 +98,17 @@ static void rzg2l_wdt_init_timeout(struct watchdog_device *wdev)
123
98
static int rzg2l_wdt_start (struct watchdog_device * wdev )
124
99
{
125
100
struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
101
+ int ret ;
126
102
127
- pm_runtime_get_sync (wdev -> parent );
103
+ ret = pm_runtime_resume_and_get (wdev -> parent );
104
+ if (ret )
105
+ return ret ;
106
+
107
+ ret = reset_control_deassert (priv -> rstc );
108
+ if (ret ) {
109
+ pm_runtime_put (wdev -> parent );
110
+ return ret ;
111
+ }
128
112
129
113
/* Initialize time out */
130
114
rzg2l_wdt_init_timeout (wdev );
@@ -141,15 +125,23 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev)
141
125
static int rzg2l_wdt_stop (struct watchdog_device * wdev )
142
126
{
143
127
struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
128
+ int ret ;
144
129
145
- rzg2l_wdt_reset (priv );
146
- pm_runtime_put (wdev -> parent );
130
+ ret = reset_control_assert (priv -> rstc );
131
+ if (ret )
132
+ return ret ;
133
+
134
+ ret = pm_runtime_put (wdev -> parent );
135
+ if (ret < 0 )
136
+ return ret ;
147
137
148
138
return 0 ;
149
139
}
150
140
151
141
static int rzg2l_wdt_set_timeout (struct watchdog_device * wdev , unsigned int timeout )
152
142
{
143
+ int ret = 0 ;
144
+
153
145
wdev -> timeout = timeout ;
154
146
155
147
/*
@@ -158,30 +150,40 @@ static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int time
158
150
* to reset the module) so that it is updated with new timeout values.
159
151
*/
160
152
if (watchdog_active (wdev )) {
161
- rzg2l_wdt_stop (wdev );
162
- rzg2l_wdt_start (wdev );
153
+ ret = rzg2l_wdt_stop (wdev );
154
+ if (ret )
155
+ return ret ;
156
+
157
+ ret = rzg2l_wdt_start (wdev );
163
158
}
164
159
165
- return 0 ;
160
+ return ret ;
166
161
}
167
162
168
163
static int rzg2l_wdt_restart (struct watchdog_device * wdev ,
169
164
unsigned long action , void * data )
170
165
{
171
166
struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
167
+ int ret ;
172
168
173
169
clk_prepare_enable (priv -> pclk );
174
170
clk_prepare_enable (priv -> osc_clk );
175
171
176
172
if (priv -> devtype == WDT_RZG2L ) {
173
+ ret = reset_control_deassert (priv -> rstc );
174
+ if (ret )
175
+ return ret ;
176
+
177
177
/* Generate Reset (WDTRSTB) Signal on parity error */
178
178
rzg2l_wdt_write (priv , 0 , PECR );
179
179
180
180
/* Force parity error */
181
181
rzg2l_wdt_write (priv , PEEN_FORCE , PEEN );
182
182
} else {
183
183
/* RZ/V2M doesn't have parity error registers */
184
- rzg2l_wdt_reset (priv );
184
+ ret = reset_control_reset (priv -> rstc );
185
+ if (ret )
186
+ return ret ;
185
187
186
188
wdev -> timeout = 0 ;
187
189
@@ -224,13 +226,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = {
224
226
.restart = rzg2l_wdt_restart ,
225
227
};
226
228
227
- static void rzg2l_wdt_reset_assert_pm_disable (void * data )
229
+ static void rzg2l_wdt_pm_disable (void * data )
228
230
{
229
231
struct watchdog_device * wdev = data ;
230
- struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
231
232
232
233
pm_runtime_disable (wdev -> parent );
233
- reset_control_assert (priv -> rstc );
234
234
}
235
235
236
236
static int rzg2l_wdt_probe (struct platform_device * pdev )
@@ -273,19 +273,8 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
273
273
return dev_err_probe (& pdev -> dev , PTR_ERR (priv -> rstc ),
274
274
"failed to get cpg reset" );
275
275
276
- ret = reset_control_deassert (priv -> rstc );
277
- if (ret )
278
- return dev_err_probe (dev , ret , "failed to deassert" );
279
-
280
276
priv -> devtype = (uintptr_t )of_device_get_match_data (dev );
281
277
282
- if (priv -> devtype == WDT_RZV2M ) {
283
- priv -> minimum_assertion_period = RZV2M_A_NSEC +
284
- 3 * F2CYCLE_NSEC (pclk_rate ) + 5 *
285
- max (F2CYCLE_NSEC (priv -> osc_clk_rate ),
286
- F2CYCLE_NSEC (pclk_rate ));
287
- }
288
-
289
278
pm_runtime_enable (& pdev -> dev );
290
279
291
280
priv -> wdev .info = & rzg2l_wdt_ident ;
@@ -297,10 +286,9 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
297
286
priv -> wdev .timeout = WDT_DEFAULT_TIMEOUT ;
298
287
299
288
watchdog_set_drvdata (& priv -> wdev , priv );
300
- ret = devm_add_action_or_reset (& pdev -> dev ,
301
- rzg2l_wdt_reset_assert_pm_disable ,
302
- & priv -> wdev );
303
- if (ret < 0 )
289
+ dev_set_drvdata (dev , priv );
290
+ ret = devm_add_action_or_reset (& pdev -> dev , rzg2l_wdt_pm_disable , & priv -> wdev );
291
+ if (ret )
304
292
return ret ;
305
293
306
294
watchdog_set_nowayout (& priv -> wdev , nowayout );
@@ -320,10 +308,35 @@ static const struct of_device_id rzg2l_wdt_ids[] = {
320
308
};
321
309
MODULE_DEVICE_TABLE (of , rzg2l_wdt_ids );
322
310
311
+ static int rzg2l_wdt_suspend_late (struct device * dev )
312
+ {
313
+ struct rzg2l_wdt_priv * priv = dev_get_drvdata (dev );
314
+
315
+ if (!watchdog_active (& priv -> wdev ))
316
+ return 0 ;
317
+
318
+ return rzg2l_wdt_stop (& priv -> wdev );
319
+ }
320
+
321
+ static int rzg2l_wdt_resume_early (struct device * dev )
322
+ {
323
+ struct rzg2l_wdt_priv * priv = dev_get_drvdata (dev );
324
+
325
+ if (!watchdog_active (& priv -> wdev ))
326
+ return 0 ;
327
+
328
+ return rzg2l_wdt_start (& priv -> wdev );
329
+ }
330
+
331
+ static const struct dev_pm_ops rzg2l_wdt_pm_ops = {
332
+ LATE_SYSTEM_SLEEP_PM_OPS (rzg2l_wdt_suspend_late , rzg2l_wdt_resume_early )
333
+ };
334
+
323
335
static struct platform_driver rzg2l_wdt_driver = {
324
336
.driver = {
325
337
.name = "rzg2l_wdt" ,
326
338
.of_match_table = rzg2l_wdt_ids ,
339
+ .pm = & rzg2l_wdt_pm_ops ,
327
340
},
328
341
.probe = rzg2l_wdt_probe ,
329
342
};
0 commit comments