3131#define TMR1CTL_RESTART BIT(9)
3232#define TMR1CTL_PRESCALE_SHIFT 16
3333
34- static void __iomem * mt7621_wdt_base ;
35- static struct reset_control * mt7621_wdt_reset ;
34+ struct mt7621_wdt_data {
35+ void __iomem * base ;
36+ struct reset_control * rst ;
37+ struct watchdog_device wdt ;
38+ };
3639
3740static bool nowayout = WATCHDOG_NOWAYOUT ;
3841module_param (nowayout , bool , 0 );
3942MODULE_PARM_DESC (nowayout ,
4043 "Watchdog cannot be stopped once started (default="
4144 __MODULE_STRING (WATCHDOG_NOWAYOUT ) ")" );
4245
43- static inline void rt_wdt_w32 (unsigned reg , u32 val )
46+ static inline void rt_wdt_w32 (void __iomem * base , unsigned int reg , u32 val )
4447{
45- iowrite32 (val , mt7621_wdt_base + reg );
48+ iowrite32 (val , base + reg );
4649}
4750
48- static inline u32 rt_wdt_r32 (unsigned reg )
51+ static inline u32 rt_wdt_r32 (void __iomem * base , unsigned int reg )
4952{
50- return ioread32 (mt7621_wdt_base + reg );
53+ return ioread32 (base + reg );
5154}
5255
5356static int mt7621_wdt_ping (struct watchdog_device * w )
5457{
55- rt_wdt_w32 (TIMER_REG_TMRSTAT , TMR1CTL_RESTART );
58+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
59+
60+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMRSTAT , TMR1CTL_RESTART );
5661
5762 return 0 ;
5863}
5964
6065static int mt7621_wdt_set_timeout (struct watchdog_device * w , unsigned int t )
6166{
67+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
68+
6269 w -> timeout = t ;
63- rt_wdt_w32 (TIMER_REG_TMR1LOAD , t * 1000 );
70+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1LOAD , t * 1000 );
6471 mt7621_wdt_ping (w );
6572
6673 return 0 ;
6774}
6875
6976static int mt7621_wdt_start (struct watchdog_device * w )
7077{
78+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
7179 u32 t ;
7280
7381 /* set the prescaler to 1ms == 1000us */
74- rt_wdt_w32 (TIMER_REG_TMR1CTL , 1000 << TMR1CTL_PRESCALE_SHIFT );
82+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1CTL , 1000 << TMR1CTL_PRESCALE_SHIFT );
7583
7684 mt7621_wdt_set_timeout (w , w -> timeout );
7785
78- t = rt_wdt_r32 (TIMER_REG_TMR1CTL );
86+ t = rt_wdt_r32 (drvdata -> base , TIMER_REG_TMR1CTL );
7987 t |= TMR1CTL_ENABLE ;
80- rt_wdt_w32 (TIMER_REG_TMR1CTL , t );
88+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1CTL , t );
8189
8290 return 0 ;
8391}
8492
8593static int mt7621_wdt_stop (struct watchdog_device * w )
8694{
95+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
8796 u32 t ;
8897
8998 mt7621_wdt_ping (w );
9099
91- t = rt_wdt_r32 (TIMER_REG_TMR1CTL );
100+ t = rt_wdt_r32 (drvdata -> base , TIMER_REG_TMR1CTL );
92101 t &= ~TMR1CTL_ENABLE ;
93- rt_wdt_w32 (TIMER_REG_TMR1CTL , t );
102+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1CTL , t );
94103
95104 return 0 ;
96105}
@@ -105,7 +114,9 @@ static int mt7621_wdt_bootcause(void)
105114
106115static int mt7621_wdt_is_running (struct watchdog_device * w )
107116{
108- return !!(rt_wdt_r32 (TIMER_REG_TMR1CTL ) & TMR1CTL_ENABLE );
117+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
118+
119+ return !!(rt_wdt_r32 (drvdata -> base , TIMER_REG_TMR1CTL ) & TMR1CTL_ENABLE );
109120}
110121
111122static const struct watchdog_info mt7621_wdt_info = {
@@ -121,30 +132,39 @@ static const struct watchdog_ops mt7621_wdt_ops = {
121132 .set_timeout = mt7621_wdt_set_timeout ,
122133};
123134
124- static struct watchdog_device mt7621_wdt_dev = {
125- .info = & mt7621_wdt_info ,
126- .ops = & mt7621_wdt_ops ,
127- .min_timeout = 1 ,
128- .max_timeout = 0xfffful / 1000 ,
129- };
130-
131135static int mt7621_wdt_probe (struct platform_device * pdev )
132136{
133137 struct device * dev = & pdev -> dev ;
134- mt7621_wdt_base = devm_platform_ioremap_resource (pdev , 0 );
135- if (IS_ERR (mt7621_wdt_base ))
136- return PTR_ERR (mt7621_wdt_base );
138+ struct watchdog_device * mt7621_wdt ;
139+ struct mt7621_wdt_data * drvdata ;
140+ int err ;
141+
142+ drvdata = devm_kzalloc (dev , sizeof (* drvdata ), GFP_KERNEL );
143+ if (!drvdata )
144+ return - ENOMEM ;
137145
138- mt7621_wdt_reset = devm_reset_control_get_exclusive ( dev , NULL );
139- if (! IS_ERR (mt7621_wdt_reset ))
140- reset_control_deassert ( mt7621_wdt_reset );
146+ drvdata -> base = devm_platform_ioremap_resource ( pdev , 0 );
147+ if (IS_ERR (drvdata -> base ))
148+ return PTR_ERR ( drvdata -> base );
141149
142- mt7621_wdt_dev .bootstatus = mt7621_wdt_bootcause ();
150+ drvdata -> rst = devm_reset_control_get_exclusive (dev , NULL );
151+ if (!IS_ERR (drvdata -> rst ))
152+ reset_control_deassert (drvdata -> rst );
143153
144- watchdog_init_timeout (& mt7621_wdt_dev , mt7621_wdt_dev .max_timeout ,
145- dev );
146- watchdog_set_nowayout (& mt7621_wdt_dev , nowayout );
147- if (mt7621_wdt_is_running (& mt7621_wdt_dev )) {
154+ mt7621_wdt = & drvdata -> wdt ;
155+ mt7621_wdt -> info = & mt7621_wdt_info ;
156+ mt7621_wdt -> ops = & mt7621_wdt_ops ;
157+ mt7621_wdt -> min_timeout = 1 ;
158+ mt7621_wdt -> max_timeout = 0xfffful / 1000 ;
159+ mt7621_wdt -> parent = dev ;
160+
161+ mt7621_wdt -> bootstatus = mt7621_wdt_bootcause ();
162+
163+ watchdog_init_timeout (mt7621_wdt , mt7621_wdt -> max_timeout , dev );
164+ watchdog_set_nowayout (mt7621_wdt , nowayout );
165+ watchdog_set_drvdata (mt7621_wdt , drvdata );
166+
167+ if (mt7621_wdt_is_running (mt7621_wdt )) {
148168 /*
149169 * Make sure to apply timeout from watchdog core, taking
150170 * the prescaler of this driver here into account (the
@@ -154,17 +174,25 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
154174 * we first disable the watchdog, set the new prescaler
155175 * and timeout, and then re-enable the watchdog.
156176 */
157- mt7621_wdt_stop (& mt7621_wdt_dev );
158- mt7621_wdt_start (& mt7621_wdt_dev );
159- set_bit (WDOG_HW_RUNNING , & mt7621_wdt_dev . status );
177+ mt7621_wdt_stop (mt7621_wdt );
178+ mt7621_wdt_start (mt7621_wdt );
179+ set_bit (WDOG_HW_RUNNING , & mt7621_wdt -> status );
160180 }
161181
162- return devm_watchdog_register_device (dev , & mt7621_wdt_dev );
182+ err = devm_watchdog_register_device (dev , & drvdata -> wdt );
183+ if (err )
184+ return err ;
185+
186+ platform_set_drvdata (pdev , drvdata );
187+
188+ return 0 ;
163189}
164190
165191static void mt7621_wdt_shutdown (struct platform_device * pdev )
166192{
167- mt7621_wdt_stop (& mt7621_wdt_dev );
193+ struct mt7621_wdt_data * drvdata = platform_get_drvdata (pdev );
194+
195+ mt7621_wdt_stop (& drvdata -> wdt );
168196}
169197
170198static const struct of_device_id mt7621_wdt_match [] = {
0 commit comments