31
31
#define TMR1CTL_RESTART BIT(9)
32
32
#define TMR1CTL_PRESCALE_SHIFT 16
33
33
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
+ };
36
39
37
40
static bool nowayout = WATCHDOG_NOWAYOUT ;
38
41
module_param (nowayout , bool , 0 );
39
42
MODULE_PARM_DESC (nowayout ,
40
43
"Watchdog cannot be stopped once started (default="
41
44
__MODULE_STRING (WATCHDOG_NOWAYOUT ) ")" );
42
45
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 )
44
47
{
45
- iowrite32 (val , mt7621_wdt_base + reg );
48
+ iowrite32 (val , base + reg );
46
49
}
47
50
48
- static inline u32 rt_wdt_r32 (unsigned reg )
51
+ static inline u32 rt_wdt_r32 (void __iomem * base , unsigned int reg )
49
52
{
50
- return ioread32 (mt7621_wdt_base + reg );
53
+ return ioread32 (base + reg );
51
54
}
52
55
53
56
static int mt7621_wdt_ping (struct watchdog_device * w )
54
57
{
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 );
56
61
57
62
return 0 ;
58
63
}
59
64
60
65
static int mt7621_wdt_set_timeout (struct watchdog_device * w , unsigned int t )
61
66
{
67
+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
68
+
62
69
w -> timeout = t ;
63
- rt_wdt_w32 (TIMER_REG_TMR1LOAD , t * 1000 );
70
+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1LOAD , t * 1000 );
64
71
mt7621_wdt_ping (w );
65
72
66
73
return 0 ;
67
74
}
68
75
69
76
static int mt7621_wdt_start (struct watchdog_device * w )
70
77
{
78
+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
71
79
u32 t ;
72
80
73
81
/* 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 );
75
83
76
84
mt7621_wdt_set_timeout (w , w -> timeout );
77
85
78
- t = rt_wdt_r32 (TIMER_REG_TMR1CTL );
86
+ t = rt_wdt_r32 (drvdata -> base , TIMER_REG_TMR1CTL );
79
87
t |= TMR1CTL_ENABLE ;
80
- rt_wdt_w32 (TIMER_REG_TMR1CTL , t );
88
+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1CTL , t );
81
89
82
90
return 0 ;
83
91
}
84
92
85
93
static int mt7621_wdt_stop (struct watchdog_device * w )
86
94
{
95
+ struct mt7621_wdt_data * drvdata = watchdog_get_drvdata (w );
87
96
u32 t ;
88
97
89
98
mt7621_wdt_ping (w );
90
99
91
- t = rt_wdt_r32 (TIMER_REG_TMR1CTL );
100
+ t = rt_wdt_r32 (drvdata -> base , TIMER_REG_TMR1CTL );
92
101
t &= ~TMR1CTL_ENABLE ;
93
- rt_wdt_w32 (TIMER_REG_TMR1CTL , t );
102
+ rt_wdt_w32 (drvdata -> base , TIMER_REG_TMR1CTL , t );
94
103
95
104
return 0 ;
96
105
}
@@ -105,7 +114,9 @@ static int mt7621_wdt_bootcause(void)
105
114
106
115
static int mt7621_wdt_is_running (struct watchdog_device * w )
107
116
{
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 );
109
120
}
110
121
111
122
static const struct watchdog_info mt7621_wdt_info = {
@@ -121,30 +132,39 @@ static const struct watchdog_ops mt7621_wdt_ops = {
121
132
.set_timeout = mt7621_wdt_set_timeout ,
122
133
};
123
134
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
-
131
135
static int mt7621_wdt_probe (struct platform_device * pdev )
132
136
{
133
137
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 ;
137
145
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 );
141
149
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 );
143
153
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 )) {
148
168
/*
149
169
* Make sure to apply timeout from watchdog core, taking
150
170
* the prescaler of this driver here into account (the
@@ -154,17 +174,25 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
154
174
* we first disable the watchdog, set the new prescaler
155
175
* and timeout, and then re-enable the watchdog.
156
176
*/
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 );
160
180
}
161
181
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 ;
163
189
}
164
190
165
191
static void mt7621_wdt_shutdown (struct platform_device * pdev )
166
192
{
167
- mt7621_wdt_stop (& mt7621_wdt_dev );
193
+ struct mt7621_wdt_data * drvdata = platform_get_drvdata (pdev );
194
+
195
+ mt7621_wdt_stop (& drvdata -> wdt );
168
196
}
169
197
170
198
static const struct of_device_id mt7621_wdt_match [] = {
0 commit comments