88#include <linux/clk.h>
99#include <linux/delay.h>
1010#include <linux/io.h>
11- #include <linux/iopoll.h>
1211#include <linux/kernel.h>
1312#include <linux/module.h>
1413#include <linux/of.h>
@@ -54,35 +53,11 @@ struct rzg2l_wdt_priv {
5453 struct reset_control * rstc ;
5554 unsigned long osc_clk_rate ;
5655 unsigned long delay ;
57- unsigned long minimum_assertion_period ;
5856 struct clk * pclk ;
5957 struct clk * osc_clk ;
6058 enum rz_wdt_type devtype ;
6159};
6260
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-
8661static void rzg2l_wdt_wait_delay (struct rzg2l_wdt_priv * priv )
8762{
8863 /* delay timer when change the setting register */
@@ -123,8 +98,17 @@ static void rzg2l_wdt_init_timeout(struct watchdog_device *wdev)
12398static int rzg2l_wdt_start (struct watchdog_device * wdev )
12499{
125100 struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
101+ int ret ;
126102
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+ }
128112
129113 /* Initialize time out */
130114 rzg2l_wdt_init_timeout (wdev );
@@ -141,15 +125,23 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev)
141125static int rzg2l_wdt_stop (struct watchdog_device * wdev )
142126{
143127 struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
128+ int ret ;
144129
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 ;
147137
148138 return 0 ;
149139}
150140
151141static int rzg2l_wdt_set_timeout (struct watchdog_device * wdev , unsigned int timeout )
152142{
143+ int ret = 0 ;
144+
153145 wdev -> timeout = timeout ;
154146
155147 /*
@@ -158,30 +150,40 @@ static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int time
158150 * to reset the module) so that it is updated with new timeout values.
159151 */
160152 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 );
163158 }
164159
165- return 0 ;
160+ return ret ;
166161}
167162
168163static int rzg2l_wdt_restart (struct watchdog_device * wdev ,
169164 unsigned long action , void * data )
170165{
171166 struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
167+ int ret ;
172168
173169 clk_prepare_enable (priv -> pclk );
174170 clk_prepare_enable (priv -> osc_clk );
175171
176172 if (priv -> devtype == WDT_RZG2L ) {
173+ ret = reset_control_deassert (priv -> rstc );
174+ if (ret )
175+ return ret ;
176+
177177 /* Generate Reset (WDTRSTB) Signal on parity error */
178178 rzg2l_wdt_write (priv , 0 , PECR );
179179
180180 /* Force parity error */
181181 rzg2l_wdt_write (priv , PEEN_FORCE , PEEN );
182182 } else {
183183 /* 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 ;
185187
186188 wdev -> timeout = 0 ;
187189
@@ -224,13 +226,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = {
224226 .restart = rzg2l_wdt_restart ,
225227};
226228
227- static void rzg2l_wdt_reset_assert_pm_disable (void * data )
229+ static void rzg2l_wdt_pm_disable (void * data )
228230{
229231 struct watchdog_device * wdev = data ;
230- struct rzg2l_wdt_priv * priv = watchdog_get_drvdata (wdev );
231232
232233 pm_runtime_disable (wdev -> parent );
233- reset_control_assert (priv -> rstc );
234234}
235235
236236static int rzg2l_wdt_probe (struct platform_device * pdev )
@@ -273,19 +273,8 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
273273 return dev_err_probe (& pdev -> dev , PTR_ERR (priv -> rstc ),
274274 "failed to get cpg reset" );
275275
276- ret = reset_control_deassert (priv -> rstc );
277- if (ret )
278- return dev_err_probe (dev , ret , "failed to deassert" );
279-
280276 priv -> devtype = (uintptr_t )of_device_get_match_data (dev );
281277
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-
289278 pm_runtime_enable (& pdev -> dev );
290279
291280 priv -> wdev .info = & rzg2l_wdt_ident ;
@@ -297,10 +286,9 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
297286 priv -> wdev .timeout = WDT_DEFAULT_TIMEOUT ;
298287
299288 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 )
304292 return ret ;
305293
306294 watchdog_set_nowayout (& priv -> wdev , nowayout );
@@ -320,10 +308,35 @@ static const struct of_device_id rzg2l_wdt_ids[] = {
320308};
321309MODULE_DEVICE_TABLE (of , rzg2l_wdt_ids );
322310
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+
323335static struct platform_driver rzg2l_wdt_driver = {
324336 .driver = {
325337 .name = "rzg2l_wdt" ,
326338 .of_match_table = rzg2l_wdt_ids ,
339+ .pm = & rzg2l_wdt_pm_ops ,
327340 },
328341 .probe = rzg2l_wdt_probe ,
329342};
0 commit comments