Blame view

drivers/watchdog/mpc8xxx_wdt.c 8.07 KB
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
1
  /*
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
2
   * mpc8xxx_wdt.c - MPC8xx/MPC83xx/MPC86xx watchdog userspace interface
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
3
4
   *
   * Authors: Dave Updegraff <dave@cray.org>
5f3b27569   Wim Van Sebroeck   watchdog: cleanup...
5
6
7
   *	    Kumar Gala <galak@kernel.crashing.org>
   *		Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org>
   *				..and from sc520_wdt
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
8
9
   * Copyright (c) 2008  MontaVista Software, Inc.
   *                     Anton Vorontsov <avorontsov@ru.mvista.com>
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
10
11
12
13
14
15
16
17
18
   *
   * Note: it appears that you can only actually ENABLE or DISABLE the thing
   * once after POR. Once enabled, you cannot disable, and vice versa.
   *
   * This program is free software; you can redistribute  it and/or modify it
   * under  the terms of  the GNU General  Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   */
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
19
20
21
  #include <linux/fs.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
22
  #include <linux/timer.h>
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
23
  #include <linux/miscdevice.h>
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
24
  #include <linux/of_platform.h>
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
25
26
  #include <linux/module.h>
  #include <linux/watchdog.h>
f26ef3dc6   Alan Cox   [WATCHDOG 26/57] ...
27
28
  #include <linux/io.h>
  #include <linux/uaccess.h>
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
29
  #include <sysdev/fsl_soc.h>
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
30

59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
31
  struct mpc8xxx_wdt {
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
32
33
34
35
36
37
38
39
40
41
42
  	__be32 res0;
  	__be32 swcrr; /* System watchdog control register */
  #define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
  #define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
  #define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
  #define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
  	__be32 swcnr; /* System watchdog count register */
  	u8 res1[2];
  	__be16 swsrr; /* System watchdog service register */
  	u8 res2[0xF0];
  };
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
43
  struct mpc8xxx_wdt_type {
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
44
45
46
  	int prescaler;
  	bool hw_enabled;
  };
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
47
  static struct mpc8xxx_wdt __iomem *wd_base;
593fc178f   Anton Vorontsov   [WATCHDOG] mpc8xx...
48
  static int mpc8xxx_wdt_init_late(void);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
49
50
51
  
  static u16 timeout = 0xffff;
  module_param(timeout, ushort, 0);
f26ef3dc6   Alan Cox   [WATCHDOG 26/57] ...
52
  MODULE_PARM_DESC(timeout,
76550d329   Randy Dunlap   watchdog: fix sev...
53
  	"Watchdog timeout in ticks. (0<timeout<65536, default=65535)");
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
54

90ab5ee94   Rusty Russell   module_param: mak...
55
  static bool reset = 1;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
56
  module_param(reset, bool, 0);
f26ef3dc6   Alan Cox   [WATCHDOG 26/57] ...
57
58
  MODULE_PARM_DESC(reset,
  	"Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
59

500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
60
61
62
63
  static int nowayout = WATCHDOG_NOWAYOUT;
  module_param(nowayout, int, 0);
  MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
  		 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
64
65
66
67
68
69
70
71
  /*
   * We always prescale, but if someone really doesn't want to they can set this
   * to 0
   */
  static int prescale = 1;
  static unsigned int timeout_sec;
  
  static unsigned long wdt_is_open;
c7dfd0cca   Alexey Dobriyan   [WATCHDOG] spin_l...
72
  static DEFINE_SPINLOCK(wdt_spinlock);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
73

59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
74
  static void mpc8xxx_wdt_keepalive(void)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
75
76
77
78
79
80
81
  {
  	/* Ping the WDT */
  	spin_lock(&wdt_spinlock);
  	out_be16(&wd_base->swsrr, 0x556c);
  	out_be16(&wd_base->swsrr, 0xaa39);
  	spin_unlock(&wdt_spinlock);
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
82
83
  static void mpc8xxx_wdt_timer_ping(unsigned long arg);
  static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0);
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
84

59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
85
  static void mpc8xxx_wdt_timer_ping(unsigned long arg)
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
86
  {
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
87
  	mpc8xxx_wdt_keepalive();
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
88
89
90
  	/* We're pinging it twice faster than needed, just to be sure. */
  	mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2);
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
91
  static void mpc8xxx_wdt_pr_warn(const char *msg)
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
92
  {
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
93
94
  	pr_crit("mpc8xxx_wdt: %s, expect the %s soon!
  ", msg,
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
95
96
  		reset ? "reset" : "machine check exception");
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
97
  static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf,
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
98
99
100
  				 size_t count, loff_t *ppos)
  {
  	if (count)
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
101
  		mpc8xxx_wdt_keepalive();
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
102
103
  	return count;
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
104
  static int mpc8xxx_wdt_open(struct inode *inode, struct file *file)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
105
106
107
108
109
110
  {
  	u32 tmp = SWCRR_SWEN;
  	if (test_and_set_bit(0, &wdt_is_open))
  		return -EBUSY;
  
  	/* Once we start the watchdog we can't stop it */
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
111
112
  	if (nowayout)
  		__module_get(THIS_MODULE);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
113
114
115
116
117
118
119
120
121
122
  
  	/* Good, fire up the show */
  	if (prescale)
  		tmp |= SWCRR_SWPR;
  	if (reset)
  		tmp |= SWCRR_SWRI;
  
  	tmp |= timeout << 16;
  
  	out_be32(&wd_base->swcrr, tmp);
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
123
  	del_timer_sync(&wdt_timer);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
124
125
  	return nonseekable_open(inode, file);
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
126
  static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
127
  {
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
128
  	if (!nowayout)
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
129
  		mpc8xxx_wdt_timer_ping(0);
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
130
  	else
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
131
  		mpc8xxx_wdt_pr_warn("watchdog closed");
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
132
133
134
  	clear_bit(0, &wdt_is_open);
  	return 0;
  }
cb55d282a   Anton Vorontsov   [WATCHDOG] mpc8xx...
135
  static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
f26ef3dc6   Alan Cox   [WATCHDOG 26/57] ...
136
  							unsigned long arg)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
137
138
139
  {
  	void __user *argp = (void __user *)arg;
  	int __user *p = argp;
42747d712   Wim Van Sebroeck   [WATCHDOG] watchd...
140
  	static const struct watchdog_info ident = {
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
141
142
  		.options = WDIOF_KEEPALIVEPING,
  		.firmware_version = 1,
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
143
  		.identity = "MPC8xxx",
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
144
145
146
147
148
  	};
  
  	switch (cmd) {
  	case WDIOC_GETSUPPORT:
  		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
5c4eb61b3   Wim Van Sebroeck   [WATCHDOG] WDIOC_...
149
150
151
  	case WDIOC_GETSTATUS:
  	case WDIOC_GETBOOTSTATUS:
  		return put_user(0, p);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
152
  	case WDIOC_KEEPALIVE:
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
153
  		mpc8xxx_wdt_keepalive();
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
154
155
156
157
  		return 0;
  	case WDIOC_GETTIMEOUT:
  		return put_user(timeout_sec, p);
  	default:
795b89d20   Samuel Tardieu   [WATCHDOG] use EN...
158
  		return -ENOTTY;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
159
160
  	}
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
161
  static const struct file_operations mpc8xxx_wdt_fops = {
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
162
163
  	.owner		= THIS_MODULE,
  	.llseek		= no_llseek,
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
164
165
166
167
  	.write		= mpc8xxx_wdt_write,
  	.unlocked_ioctl	= mpc8xxx_wdt_ioctl,
  	.open		= mpc8xxx_wdt_open,
  	.release	= mpc8xxx_wdt_release,
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
168
  };
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
169
  static struct miscdevice mpc8xxx_wdt_miscdev = {
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
170
171
  	.minor	= WATCHDOG_MINOR,
  	.name	= "watchdog",
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
172
  	.fops	= &mpc8xxx_wdt_fops,
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
173
  };
b1608d69c   Grant Likely   drivercore: rever...
174
  static const struct of_device_id mpc8xxx_wdt_match[];
1c48a5c93   Grant Likely   dt: Eliminate of_...
175
  static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
176
  {
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
177
  	int ret;
b1608d69c   Grant Likely   drivercore: rever...
178
  	const struct of_device_id *match;
de2b606c2   Michael Guntsche   watchdog: Fix bui...
179
  	struct device_node *np = ofdev->dev.of_node;
1c48a5c93   Grant Likely   dt: Eliminate of_...
180
  	struct mpc8xxx_wdt_type *wdt_type;
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
181
  	u32 freq = fsl_get_sys_freq();
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
182
  	bool enabled;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
183

b1608d69c   Grant Likely   drivercore: rever...
184
185
  	match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev);
  	if (!match)
1c48a5c93   Grant Likely   dt: Eliminate of_...
186
  		return -EINVAL;
b1608d69c   Grant Likely   drivercore: rever...
187
  	wdt_type = match->data;
1c48a5c93   Grant Likely   dt: Eliminate of_...
188

ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
189
190
  	if (!freq || freq == -1)
  		return -EINVAL;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
191

500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
192
  	wd_base = of_iomap(np, 0);
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
193
194
  	if (!wd_base)
  		return -ENOMEM;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
195

500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
196
197
  	enabled = in_be32(&wd_base->swcrr) & SWCRR_SWEN;
  	if (!enabled && wdt_type->hw_enabled) {
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
198
199
  		pr_info("mpc8xxx_wdt: could not be enabled in software
  ");
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
200
201
202
  		ret = -ENOSYS;
  		goto err_unmap;
  	}
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
203
204
  	/* Calculate the timeout in seconds */
  	if (prescale)
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
205
  		timeout_sec = (timeout * wdt_type->prescaler) / freq;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
206
  	else
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
207
  		timeout_sec = timeout / freq;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
208

593fc178f   Anton Vorontsov   [WATCHDOG] mpc8xx...
209
210
211
212
213
  #ifdef MODULE
  	ret = mpc8xxx_wdt_init_late();
  	if (ret)
  		goto err_unmap;
  #endif
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
214
  	pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d "
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
215
216
217
  		"(%d seconds)
  ", reset ? "reset" : "interrupt", timeout,
  		timeout_sec);
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
218
219
220
  
  	/*
  	 * If the watchdog was previously enabled or we're running on
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
221
  	 * MPC8xxx, we should ping the wdt from the kernel until the
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
222
223
224
  	 * userspace handles it.
  	 */
  	if (enabled)
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
225
  		mpc8xxx_wdt_timer_ping(0);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
226
  	return 0;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
227
228
  err_unmap:
  	iounmap(wd_base);
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
229
  	wd_base = NULL;
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
230
231
  	return ret;
  }
2dc115813   Grant Likely   of/device: Replac...
232
  static int __devexit mpc8xxx_wdt_remove(struct platform_device *ofdev)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
233
  {
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
234
  	mpc8xxx_wdt_pr_warn("watchdog removed");
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
235
  	del_timer_sync(&wdt_timer);
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
236
  	misc_deregister(&mpc8xxx_wdt_miscdev);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
237
238
239
240
  	iounmap(wd_base);
  
  	return 0;
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
241
  static const struct of_device_id mpc8xxx_wdt_match[] = {
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
242
243
  	{
  		.compatible = "mpc83xx_wdt",
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
244
  		.data = &(struct mpc8xxx_wdt_type) {
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
245
246
247
248
249
  			.prescaler = 0x10000,
  		},
  	},
  	{
  		.compatible = "fsl,mpc8610-wdt",
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
250
  		.data = &(struct mpc8xxx_wdt_type) {
500c919e3   Anton Vorontsov   [WATCHDOG] mpc83x...
251
252
253
  			.prescaler = 0x10000,
  			.hw_enabled = true,
  		},
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
254
  	},
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
255
256
257
258
259
260
  	{
  		.compatible = "fsl,mpc823-wdt",
  		.data = &(struct mpc8xxx_wdt_type) {
  			.prescaler = 0x800,
  		},
  	},
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
261
262
  	{},
  };
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
263
  MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match);
ef8ab12ec   Anton Vorontsov   [WATCHDOG] mpc83x...
264

1c48a5c93   Grant Likely   dt: Eliminate of_...
265
  static struct platform_driver mpc8xxx_wdt_driver = {
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
266
267
  	.probe		= mpc8xxx_wdt_probe,
  	.remove		= __devexit_p(mpc8xxx_wdt_remove),
4018294b5   Grant Likely   of: Remove duplic...
268
269
270
271
  	.driver = {
  		.name = "mpc8xxx_wdt",
  		.owner = THIS_MODULE,
  		.of_match_table = mpc8xxx_wdt_match,
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
272
273
  	},
  };
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
274
275
276
277
278
  /*
   * We do wdt initialization in two steps: arch_initcall probes the wdt
   * very early to start pinging the watchdog (misc devices are not yet
   * available), and later module_init() just registers the misc device.
   */
593fc178f   Anton Vorontsov   [WATCHDOG] mpc8xx...
279
  static int mpc8xxx_wdt_init_late(void)
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  {
  	int ret;
  
  	if (!wd_base)
  		return -ENODEV;
  
  	ret = misc_register(&mpc8xxx_wdt_miscdev);
  	if (ret) {
  		pr_err("cannot register miscdev on minor=%d (err=%d)
  ",
  			WATCHDOG_MINOR, ret);
  		return ret;
  	}
  	return 0;
  }
593fc178f   Anton Vorontsov   [WATCHDOG] mpc8xx...
295
  #ifndef MODULE
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
296
  module_init(mpc8xxx_wdt_init_late);
593fc178f   Anton Vorontsov   [WATCHDOG] mpc8xx...
297
  #endif
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
298

59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
299
  static int __init mpc8xxx_wdt_init(void)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
300
  {
1c48a5c93   Grant Likely   dt: Eliminate of_...
301
  	return platform_driver_register(&mpc8xxx_wdt_driver);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
302
  }
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
303
  arch_initcall(mpc8xxx_wdt_init);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
304

59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
305
  static void __exit mpc8xxx_wdt_exit(void)
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
306
  {
1c48a5c93   Grant Likely   dt: Eliminate of_...
307
  	platform_driver_unregister(&mpc8xxx_wdt_driver);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
308
  }
59ca1b0d1   Anton Vorontsov   [WATCHDOG] mpc8xx...
309
  module_exit(mpc8xxx_wdt_exit);
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
310
311
  
  MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
0d7b10140   Anton Vorontsov   [WATCHDOG] mpc8xx...
312
313
  MODULE_DESCRIPTION("Driver for watchdog timer in MPC8xx/MPC83xx/MPC86xx "
  		   "uProcessors");
fabbfb9e8   Kumar Gala   [PATCH] powerpc: ...
314
315
  MODULE_LICENSE("GPL");
  MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);