diff options
author | Leela Krishna Amudala <l.krishna@samsung.com> | 2013-08-27 06:06:03 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2013-09-10 15:14:36 -0400 |
commit | af4ea6312cebd756221b813b0b69bca9b201a6af (patch) | |
tree | 5144cde649e913736cbdb9e52d4fd9309d5cc176 | |
parent | 26b0332e30c7f93e780aaa054bd84e3437f84354 (diff) |
watchdog: s3c2410_wdt: remove the global variables
This patch removes the global variables in the driver file and
group them into a structure.
Signed-off-by: Leela Krishna Amudala <l.krishna@samsung.com>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r-- | drivers/watchdog/s3c2410_wdt.c | 222 |
1 files changed, 128 insertions, 94 deletions
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 6a22cf5d35bd..43d280718709 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -84,13 +84,17 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, " | |||
84 | "0 to reboot (default 0)"); | 84 | "0 to reboot (default 0)"); |
85 | MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)"); | 85 | MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)"); |
86 | 86 | ||
87 | static struct device *wdt_dev; /* platform device attached to */ | 87 | struct s3c2410_wdt { |
88 | static struct resource *wdt_mem; | 88 | struct device *dev; |
89 | static struct resource *wdt_irq; | 89 | struct clk *clock; |
90 | static struct clk *wdt_clock; | 90 | void __iomem *reg_base; |
91 | static void __iomem *wdt_base; | 91 | unsigned int count; |
92 | static unsigned int wdt_count; | 92 | spinlock_t lock; |
93 | static DEFINE_SPINLOCK(wdt_lock); | 93 | unsigned long wtcon_save; |
94 | unsigned long wtdat_save; | ||
95 | struct watchdog_device wdt_device; | ||
96 | struct notifier_block freq_transition; | ||
97 | }; | ||
94 | 98 | ||
95 | /* watchdog control routines */ | 99 | /* watchdog control routines */ |
96 | 100 | ||
@@ -102,29 +106,38 @@ do { \ | |||
102 | 106 | ||
103 | /* functions */ | 107 | /* functions */ |
104 | 108 | ||
109 | static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb) | ||
110 | { | ||
111 | return container_of(nb, struct s3c2410_wdt, freq_transition); | ||
112 | } | ||
113 | |||
105 | static int s3c2410wdt_keepalive(struct watchdog_device *wdd) | 114 | static int s3c2410wdt_keepalive(struct watchdog_device *wdd) |
106 | { | 115 | { |
107 | spin_lock(&wdt_lock); | 116 | struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); |
108 | writel(wdt_count, wdt_base + S3C2410_WTCNT); | 117 | |
109 | spin_unlock(&wdt_lock); | 118 | spin_lock(&wdt->lock); |
119 | writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); | ||
120 | spin_unlock(&wdt->lock); | ||
110 | 121 | ||
111 | return 0; | 122 | return 0; |
112 | } | 123 | } |
113 | 124 | ||
114 | static void __s3c2410wdt_stop(void) | 125 | static void __s3c2410wdt_stop(struct s3c2410_wdt *wdt) |
115 | { | 126 | { |
116 | unsigned long wtcon; | 127 | unsigned long wtcon; |
117 | 128 | ||
118 | wtcon = readl(wdt_base + S3C2410_WTCON); | 129 | wtcon = readl(wdt->reg_base + S3C2410_WTCON); |
119 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); | 130 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); |
120 | writel(wtcon, wdt_base + S3C2410_WTCON); | 131 | writel(wtcon, wdt->reg_base + S3C2410_WTCON); |
121 | } | 132 | } |
122 | 133 | ||
123 | static int s3c2410wdt_stop(struct watchdog_device *wdd) | 134 | static int s3c2410wdt_stop(struct watchdog_device *wdd) |
124 | { | 135 | { |
125 | spin_lock(&wdt_lock); | 136 | struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); |
126 | __s3c2410wdt_stop(); | 137 | |
127 | spin_unlock(&wdt_lock); | 138 | spin_lock(&wdt->lock); |
139 | __s3c2410wdt_stop(wdt); | ||
140 | spin_unlock(&wdt->lock); | ||
128 | 141 | ||
129 | return 0; | 142 | return 0; |
130 | } | 143 | } |
@@ -132,12 +145,13 @@ static int s3c2410wdt_stop(struct watchdog_device *wdd) | |||
132 | static int s3c2410wdt_start(struct watchdog_device *wdd) | 145 | static int s3c2410wdt_start(struct watchdog_device *wdd) |
133 | { | 146 | { |
134 | unsigned long wtcon; | 147 | unsigned long wtcon; |
148 | struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); | ||
135 | 149 | ||
136 | spin_lock(&wdt_lock); | 150 | spin_lock(&wdt->lock); |
137 | 151 | ||
138 | __s3c2410wdt_stop(); | 152 | __s3c2410wdt_stop(wdt); |
139 | 153 | ||
140 | wtcon = readl(wdt_base + S3C2410_WTCON); | 154 | wtcon = readl(wdt->reg_base + S3C2410_WTCON); |
141 | wtcon |= S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128; | 155 | wtcon |= S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128; |
142 | 156 | ||
143 | if (soft_noboot) { | 157 | if (soft_noboot) { |
@@ -148,25 +162,26 @@ static int s3c2410wdt_start(struct watchdog_device *wdd) | |||
148 | wtcon |= S3C2410_WTCON_RSTEN; | 162 | wtcon |= S3C2410_WTCON_RSTEN; |
149 | } | 163 | } |
150 | 164 | ||
151 | DBG("%s: wdt_count=0x%08x, wtcon=%08lx\n", | 165 | DBG("%s: count=0x%08x, wtcon=%08lx\n", |
152 | __func__, wdt_count, wtcon); | 166 | __func__, wdt->count, wtcon); |
153 | 167 | ||
154 | writel(wdt_count, wdt_base + S3C2410_WTDAT); | 168 | writel(wdt->count, wdt->reg_base + S3C2410_WTDAT); |
155 | writel(wdt_count, wdt_base + S3C2410_WTCNT); | 169 | writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); |
156 | writel(wtcon, wdt_base + S3C2410_WTCON); | 170 | writel(wtcon, wdt->reg_base + S3C2410_WTCON); |
157 | spin_unlock(&wdt_lock); | 171 | spin_unlock(&wdt->lock); |
158 | 172 | ||
159 | return 0; | 173 | return 0; |
160 | } | 174 | } |
161 | 175 | ||
162 | static inline int s3c2410wdt_is_running(void) | 176 | static inline int s3c2410wdt_is_running(struct s3c2410_wdt *wdt) |
163 | { | 177 | { |
164 | return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE; | 178 | return readl(wdt->reg_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE; |
165 | } | 179 | } |
166 | 180 | ||
167 | static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeout) | 181 | static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeout) |
168 | { | 182 | { |
169 | unsigned long freq = clk_get_rate(wdt_clock); | 183 | struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); |
184 | unsigned long freq = clk_get_rate(wdt->clock); | ||
170 | unsigned int count; | 185 | unsigned int count; |
171 | unsigned int divisor = 1; | 186 | unsigned int divisor = 1; |
172 | unsigned long wtcon; | 187 | unsigned long wtcon; |
@@ -192,7 +207,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou | |||
192 | } | 207 | } |
193 | 208 | ||
194 | if ((count / divisor) >= 0x10000) { | 209 | if ((count / divisor) >= 0x10000) { |
195 | dev_err(wdt_dev, "timeout %d too big\n", timeout); | 210 | dev_err(wdt->dev, "timeout %d too big\n", timeout); |
196 | return -EINVAL; | 211 | return -EINVAL; |
197 | } | 212 | } |
198 | } | 213 | } |
@@ -201,15 +216,15 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou | |||
201 | __func__, timeout, divisor, count, count/divisor); | 216 | __func__, timeout, divisor, count, count/divisor); |
202 | 217 | ||
203 | count /= divisor; | 218 | count /= divisor; |
204 | wdt_count = count; | 219 | wdt->count = count; |
205 | 220 | ||
206 | /* update the pre-scaler */ | 221 | /* update the pre-scaler */ |
207 | wtcon = readl(wdt_base + S3C2410_WTCON); | 222 | wtcon = readl(wdt->reg_base + S3C2410_WTCON); |
208 | wtcon &= ~S3C2410_WTCON_PRESCALE_MASK; | 223 | wtcon &= ~S3C2410_WTCON_PRESCALE_MASK; |
209 | wtcon |= S3C2410_WTCON_PRESCALE(divisor-1); | 224 | wtcon |= S3C2410_WTCON_PRESCALE(divisor-1); |
210 | 225 | ||
211 | writel(count, wdt_base + S3C2410_WTDAT); | 226 | writel(count, wdt->reg_base + S3C2410_WTDAT); |
212 | writel(wtcon, wdt_base + S3C2410_WTCON); | 227 | writel(wtcon, wdt->reg_base + S3C2410_WTCON); |
213 | 228 | ||
214 | wdd->timeout = (count * divisor) / freq; | 229 | wdd->timeout = (count * divisor) / freq; |
215 | 230 | ||
@@ -242,21 +257,23 @@ static struct watchdog_device s3c2410_wdd = { | |||
242 | 257 | ||
243 | static irqreturn_t s3c2410wdt_irq(int irqno, void *param) | 258 | static irqreturn_t s3c2410wdt_irq(int irqno, void *param) |
244 | { | 259 | { |
245 | dev_info(wdt_dev, "watchdog timer expired (irq)\n"); | 260 | struct s3c2410_wdt *wdt = platform_get_drvdata(param); |
246 | 261 | ||
247 | s3c2410wdt_keepalive(&s3c2410_wdd); | 262 | dev_info(wdt->dev, "watchdog timer expired (irq)\n"); |
263 | |||
264 | s3c2410wdt_keepalive(&wdt->wdt_device); | ||
248 | return IRQ_HANDLED; | 265 | return IRQ_HANDLED; |
249 | } | 266 | } |
250 | 267 | ||
251 | |||
252 | #ifdef CONFIG_CPU_FREQ | 268 | #ifdef CONFIG_CPU_FREQ |
253 | 269 | ||
254 | static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, | 270 | static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, |
255 | unsigned long val, void *data) | 271 | unsigned long val, void *data) |
256 | { | 272 | { |
257 | int ret; | 273 | int ret; |
274 | struct s3c2410_wdt *wdt = freq_to_wdt(nb); | ||
258 | 275 | ||
259 | if (!s3c2410wdt_is_running()) | 276 | if (!s3c2410wdt_is_running(wdt)) |
260 | goto done; | 277 | goto done; |
261 | 278 | ||
262 | if (val == CPUFREQ_PRECHANGE) { | 279 | if (val == CPUFREQ_PRECHANGE) { |
@@ -265,14 +282,15 @@ static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, | |||
265 | * the watchdog is running. | 282 | * the watchdog is running. |
266 | */ | 283 | */ |
267 | 284 | ||
268 | s3c2410wdt_keepalive(&s3c2410_wdd); | 285 | s3c2410wdt_keepalive(&wdt->wdt_device); |
269 | } else if (val == CPUFREQ_POSTCHANGE) { | 286 | } else if (val == CPUFREQ_POSTCHANGE) { |
270 | s3c2410wdt_stop(&s3c2410_wdd); | 287 | s3c2410wdt_stop(&wdt->wdt_device); |
271 | 288 | ||
272 | ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout); | 289 | ret = s3c2410wdt_set_heartbeat(&wdt->wdt_device, |
290 | wdt->wdt_device.timeout); | ||
273 | 291 | ||
274 | if (ret >= 0) | 292 | if (ret >= 0) |
275 | s3c2410wdt_start(&s3c2410_wdd); | 293 | s3c2410wdt_start(&wdt->wdt_device); |
276 | else | 294 | else |
277 | goto err; | 295 | goto err; |
278 | } | 296 | } |
@@ -281,34 +299,35 @@ done: | |||
281 | return 0; | 299 | return 0; |
282 | 300 | ||
283 | err: | 301 | err: |
284 | dev_err(wdt_dev, "cannot set new value for timeout %d\n", | 302 | dev_err(wdt->dev, "cannot set new value for timeout %d\n", |
285 | s3c2410_wdd.timeout); | 303 | wdt->wdt_device.timeout); |
286 | return ret; | 304 | return ret; |
287 | } | 305 | } |
288 | 306 | ||
289 | static struct notifier_block s3c2410wdt_cpufreq_transition_nb = { | 307 | static inline int s3c2410wdt_cpufreq_register(struct s3c2410_wdt *wdt) |
290 | .notifier_call = s3c2410wdt_cpufreq_transition, | ||
291 | }; | ||
292 | |||
293 | static inline int s3c2410wdt_cpufreq_register(void) | ||
294 | { | 308 | { |
295 | return cpufreq_register_notifier(&s3c2410wdt_cpufreq_transition_nb, | 309 | wdt->freq_transition.notifier_call = s3c2410wdt_cpufreq_transition; |
310 | |||
311 | return cpufreq_register_notifier(&wdt->freq_transition, | ||
296 | CPUFREQ_TRANSITION_NOTIFIER); | 312 | CPUFREQ_TRANSITION_NOTIFIER); |
297 | } | 313 | } |
298 | 314 | ||
299 | static inline void s3c2410wdt_cpufreq_deregister(void) | 315 | static inline void s3c2410wdt_cpufreq_deregister(struct s3c2410_wdt *wdt) |
300 | { | 316 | { |
301 | cpufreq_unregister_notifier(&s3c2410wdt_cpufreq_transition_nb, | 317 | wdt->freq_transition.notifier_call = s3c2410wdt_cpufreq_transition; |
318 | |||
319 | cpufreq_unregister_notifier(&wdt->freq_transition, | ||
302 | CPUFREQ_TRANSITION_NOTIFIER); | 320 | CPUFREQ_TRANSITION_NOTIFIER); |
303 | } | 321 | } |
304 | 322 | ||
305 | #else | 323 | #else |
306 | static inline int s3c2410wdt_cpufreq_register(void) | 324 | |
325 | static inline int s3c2410wdt_cpufreq_register(struct s3c2410_wdt *wdt) | ||
307 | { | 326 | { |
308 | return 0; | 327 | return 0; |
309 | } | 328 | } |
310 | 329 | ||
311 | static inline void s3c2410wdt_cpufreq_deregister(void) | 330 | static inline void s3c2410wdt_cpufreq_deregister(struct s3c2410_wdt *wdt) |
312 | { | 331 | { |
313 | } | 332 | } |
314 | #endif | 333 | #endif |
@@ -316,6 +335,9 @@ static inline void s3c2410wdt_cpufreq_deregister(void) | |||
316 | static int s3c2410wdt_probe(struct platform_device *pdev) | 335 | static int s3c2410wdt_probe(struct platform_device *pdev) |
317 | { | 336 | { |
318 | struct device *dev; | 337 | struct device *dev; |
338 | struct s3c2410_wdt *wdt; | ||
339 | struct resource *wdt_mem; | ||
340 | struct resource *wdt_irq; | ||
319 | unsigned int wtcon; | 341 | unsigned int wtcon; |
320 | int started = 0; | 342 | int started = 0; |
321 | int ret; | 343 | int ret; |
@@ -323,8 +345,14 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
323 | DBG("%s: probe=%p\n", __func__, pdev); | 345 | DBG("%s: probe=%p\n", __func__, pdev); |
324 | 346 | ||
325 | dev = &pdev->dev; | 347 | dev = &pdev->dev; |
326 | wdt_dev = &pdev->dev; | ||
327 | 348 | ||
349 | wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); | ||
350 | if (!wdt) | ||
351 | return -ENOMEM; | ||
352 | |||
353 | wdt->dev = &pdev->dev; | ||
354 | spin_lock_init(&wdt->lock); | ||
355 | wdt->wdt_device = s3c2410_wdd; | ||
328 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 356 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
329 | if (wdt_mem == NULL) { | 357 | if (wdt_mem == NULL) { |
330 | dev_err(dev, "no memory resource specified\n"); | 358 | dev_err(dev, "no memory resource specified\n"); |
@@ -339,35 +367,39 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
339 | } | 367 | } |
340 | 368 | ||
341 | /* get the memory region for the watchdog timer */ | 369 | /* get the memory region for the watchdog timer */ |
342 | wdt_base = devm_ioremap_resource(dev, wdt_mem); | 370 | wdt->reg_base = devm_ioremap_resource(dev, wdt_mem); |
343 | if (IS_ERR(wdt_base)) { | 371 | if (IS_ERR(wdt->reg_base)) { |
344 | ret = PTR_ERR(wdt_base); | 372 | ret = PTR_ERR(wdt->reg_base); |
345 | goto err; | 373 | goto err; |
346 | } | 374 | } |
347 | 375 | ||
348 | DBG("probe: mapped wdt_base=%p\n", wdt_base); | 376 | DBG("probe: mapped reg_base=%p\n", wdt->reg_base); |
349 | 377 | ||
350 | wdt_clock = devm_clk_get(dev, "watchdog"); | 378 | wdt->clock = devm_clk_get(dev, "watchdog"); |
351 | if (IS_ERR(wdt_clock)) { | 379 | if (IS_ERR(wdt->clock)) { |
352 | dev_err(dev, "failed to find watchdog clock source\n"); | 380 | dev_err(dev, "failed to find watchdog clock source\n"); |
353 | ret = PTR_ERR(wdt_clock); | 381 | ret = PTR_ERR(wdt->clock); |
354 | goto err; | 382 | goto err; |
355 | } | 383 | } |
356 | 384 | ||
357 | clk_prepare_enable(wdt_clock); | 385 | clk_prepare_enable(wdt->clock); |
358 | 386 | ||
359 | ret = s3c2410wdt_cpufreq_register(); | 387 | ret = s3c2410wdt_cpufreq_register(wdt); |
360 | if (ret < 0) { | 388 | if (ret < 0) { |
361 | dev_err(dev, "failed to register cpufreq\n"); | 389 | dev_err(dev, "failed to register cpufreq\n"); |
362 | goto err_clk; | 390 | goto err_clk; |
363 | } | 391 | } |
364 | 392 | ||
393 | watchdog_set_drvdata(&wdt->wdt_device, wdt); | ||
394 | |||
365 | /* see if we can actually set the requested timer margin, and if | 395 | /* see if we can actually set the requested timer margin, and if |
366 | * not, try the default value */ | 396 | * not, try the default value */ |
367 | 397 | ||
368 | watchdog_init_timeout(&s3c2410_wdd, tmr_margin, &pdev->dev); | 398 | watchdog_init_timeout(&wdt->wdt_device, tmr_margin, &pdev->dev); |
369 | if (s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout)) { | 399 | ret = s3c2410wdt_set_heartbeat(&wdt->wdt_device, |
370 | started = s3c2410wdt_set_heartbeat(&s3c2410_wdd, | 400 | wdt->wdt_device.timeout); |
401 | if (ret) { | ||
402 | started = s3c2410wdt_set_heartbeat(&wdt->wdt_device, | ||
371 | CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); | 403 | CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); |
372 | 404 | ||
373 | if (started == 0) | 405 | if (started == 0) |
@@ -386,9 +418,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
386 | goto err_cpufreq; | 418 | goto err_cpufreq; |
387 | } | 419 | } |
388 | 420 | ||
389 | watchdog_set_nowayout(&s3c2410_wdd, nowayout); | 421 | watchdog_set_nowayout(&wdt->wdt_device, nowayout); |
390 | 422 | ||
391 | ret = watchdog_register_device(&s3c2410_wdd); | 423 | ret = watchdog_register_device(&wdt->wdt_device); |
392 | if (ret) { | 424 | if (ret) { |
393 | dev_err(dev, "cannot register watchdog (%d)\n", ret); | 425 | dev_err(dev, "cannot register watchdog (%d)\n", ret); |
394 | goto err_cpufreq; | 426 | goto err_cpufreq; |
@@ -396,18 +428,20 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
396 | 428 | ||
397 | if (tmr_atboot && started == 0) { | 429 | if (tmr_atboot && started == 0) { |
398 | dev_info(dev, "starting watchdog timer\n"); | 430 | dev_info(dev, "starting watchdog timer\n"); |
399 | s3c2410wdt_start(&s3c2410_wdd); | 431 | s3c2410wdt_start(&wdt->wdt_device); |
400 | } else if (!tmr_atboot) { | 432 | } else if (!tmr_atboot) { |
401 | /* if we're not enabling the watchdog, then ensure it is | 433 | /* if we're not enabling the watchdog, then ensure it is |
402 | * disabled if it has been left running from the bootloader | 434 | * disabled if it has been left running from the bootloader |
403 | * or other source */ | 435 | * or other source */ |
404 | 436 | ||
405 | s3c2410wdt_stop(&s3c2410_wdd); | 437 | s3c2410wdt_stop(&wdt->wdt_device); |
406 | } | 438 | } |
407 | 439 | ||
440 | platform_set_drvdata(pdev, wdt); | ||
441 | |||
408 | /* print out a statement of readiness */ | 442 | /* print out a statement of readiness */ |
409 | 443 | ||
410 | wtcon = readl(wdt_base + S3C2410_WTCON); | 444 | wtcon = readl(wdt->reg_base + S3C2410_WTCON); |
411 | 445 | ||
412 | dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", | 446 | dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", |
413 | (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", | 447 | (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", |
@@ -417,64 +451,64 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
417 | return 0; | 451 | return 0; |
418 | 452 | ||
419 | err_cpufreq: | 453 | err_cpufreq: |
420 | s3c2410wdt_cpufreq_deregister(); | 454 | s3c2410wdt_cpufreq_deregister(wdt); |
421 | 455 | ||
422 | err_clk: | 456 | err_clk: |
423 | clk_disable_unprepare(wdt_clock); | 457 | clk_disable_unprepare(wdt->clock); |
424 | wdt_clock = NULL; | 458 | wdt->clock = NULL; |
425 | 459 | ||
426 | err: | 460 | err: |
427 | wdt_irq = NULL; | ||
428 | wdt_mem = NULL; | ||
429 | return ret; | 461 | return ret; |
430 | } | 462 | } |
431 | 463 | ||
432 | static int s3c2410wdt_remove(struct platform_device *dev) | 464 | static int s3c2410wdt_remove(struct platform_device *dev) |
433 | { | 465 | { |
434 | watchdog_unregister_device(&s3c2410_wdd); | 466 | struct s3c2410_wdt *wdt = platform_get_drvdata(dev); |
467 | |||
468 | watchdog_unregister_device(&wdt->wdt_device); | ||
435 | 469 | ||
436 | s3c2410wdt_cpufreq_deregister(); | 470 | s3c2410wdt_cpufreq_deregister(wdt); |
437 | 471 | ||
438 | clk_disable_unprepare(wdt_clock); | 472 | clk_disable_unprepare(wdt->clock); |
439 | wdt_clock = NULL; | 473 | wdt->clock = NULL; |
440 | 474 | ||
441 | wdt_irq = NULL; | ||
442 | wdt_mem = NULL; | ||
443 | return 0; | 475 | return 0; |
444 | } | 476 | } |
445 | 477 | ||
446 | static void s3c2410wdt_shutdown(struct platform_device *dev) | 478 | static void s3c2410wdt_shutdown(struct platform_device *dev) |
447 | { | 479 | { |
448 | s3c2410wdt_stop(&s3c2410_wdd); | 480 | struct s3c2410_wdt *wdt = platform_get_drvdata(dev); |
481 | |||
482 | s3c2410wdt_stop(&wdt->wdt_device); | ||
449 | } | 483 | } |
450 | 484 | ||
451 | #ifdef CONFIG_PM_SLEEP | 485 | #ifdef CONFIG_PM_SLEEP |
452 | 486 | ||
453 | static unsigned long wtcon_save; | ||
454 | static unsigned long wtdat_save; | ||
455 | |||
456 | static int s3c2410wdt_suspend(struct device *dev) | 487 | static int s3c2410wdt_suspend(struct device *dev) |
457 | { | 488 | { |
489 | struct s3c2410_wdt *wdt = dev_get_drvdata(dev); | ||
490 | |||
458 | /* Save watchdog state, and turn it off. */ | 491 | /* Save watchdog state, and turn it off. */ |
459 | wtcon_save = readl(wdt_base + S3C2410_WTCON); | 492 | wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON); |
460 | wtdat_save = readl(wdt_base + S3C2410_WTDAT); | 493 | wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT); |
461 | 494 | ||
462 | /* Note that WTCNT doesn't need to be saved. */ | 495 | /* Note that WTCNT doesn't need to be saved. */ |
463 | s3c2410wdt_stop(&s3c2410_wdd); | 496 | s3c2410wdt_stop(&wdt->wdt_device); |
464 | 497 | ||
465 | return 0; | 498 | return 0; |
466 | } | 499 | } |
467 | 500 | ||
468 | static int s3c2410wdt_resume(struct device *dev) | 501 | static int s3c2410wdt_resume(struct device *dev) |
469 | { | 502 | { |
470 | /* Restore watchdog state. */ | 503 | struct s3c2410_wdt *wdt = dev_get_drvdata(dev); |
471 | 504 | ||
472 | writel(wtdat_save, wdt_base + S3C2410_WTDAT); | 505 | /* Restore watchdog state. */ |
473 | writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */ | 506 | writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTDAT); |
474 | writel(wtcon_save, wdt_base + S3C2410_WTCON); | 507 | writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ |
508 | writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); | ||
475 | 509 | ||
476 | dev_info(dev, "watchdog %sabled\n", | 510 | dev_info(dev, "watchdog %sabled\n", |
477 | (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); | 511 | (wdt->wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); |
478 | 512 | ||
479 | return 0; | 513 | return 0; |
480 | } | 514 | } |