Blame view

drivers/rtc/rtc-vr41xx.c 9.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
2
   *  Driver for NEC VR4100 series Real Time Clock unit.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
   *
ada8e9514   Yoichi Yuasa   Update Yoichi Yua...
4
   *  Copyright (C) 2003-2008  Yoichi Yuasa <yuasa@linux-mips.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   *
   *  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.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
bd0765098   Yoichi Yuasa   [MIPS] separate p...
20
  #include <linux/err.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
  #include <linux/fs.h>
  #include <linux/init.h>
  #include <linux/ioport.h>
bd0765098   Yoichi Yuasa   [MIPS] separate p...
24
  #include <linux/interrupt.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  #include <linux/module.h>
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
26
  #include <linux/platform_device.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
  #include <linux/rtc.h>
  #include <linux/spinlock.h>
  #include <linux/types.h>
5d2a50371   Jonathan Cameron   rtc: move power o...
30
  #include <linux/log2.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
  
  #include <asm/div64.h>
  #include <asm/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  #include <asm/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

ada8e9514   Yoichi Yuasa   Update Yoichi Yua...
36
  MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
4cad4431f   Yoichi Yuasa   rtc-vr41xx: add i...
38
  MODULE_LICENSE("GPL v2");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  /* RTC 1 registers */
  #define ETIMELREG		0x00
  #define ETIMEMREG		0x02
  #define ETIMEHREG		0x04
  /* RFU */
  #define ECMPLREG		0x08
  #define ECMPMREG		0x0a
  #define ECMPHREG		0x0c
  /* RFU */
  #define RTCL1LREG		0x10
  #define RTCL1HREG		0x12
  #define RTCL1CNTLREG		0x14
  #define RTCL1CNTHREG		0x16
  #define RTCL2LREG		0x18
  #define RTCL2HREG		0x1a
  #define RTCL2CNTLREG		0x1c
  #define RTCL2CNTHREG		0x1e
  
  /* RTC 2 registers */
  #define TCLKLREG		0x00
  #define TCLKHREG		0x02
  #define TCLKCNTLREG		0x04
  #define TCLKCNTHREG		0x06
  /* RFU */
  #define RTCINTREG		0x1e
   #define TCLOCK_INT		0x08
   #define RTCLONG2_INT		0x04
   #define RTCLONG1_INT		0x02
   #define ELAPSEDTIME_INT	0x01
  
  #define RTC_FREQUENCY		32768
  #define MAX_PERIODIC_RATE	6553
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
76
77
78
79
80
81
82
  
  static void __iomem *rtc1_base;
  static void __iomem *rtc2_base;
  
  #define rtc1_read(offset)		readw(rtc1_base + (offset))
  #define rtc1_write(offset, value)	writew((value), rtc1_base + (offset))
  
  #define rtc2_read(offset)		readw(rtc2_base + (offset))
  #define rtc2_write(offset, value)	writew((value), rtc2_base + (offset))
  
  static unsigned long epoch = 1970;	/* Jan 1 1970 00:00:00 */
34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
83
  static DEFINE_SPINLOCK(rtc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  static char rtc_name[] = "RTC";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  static unsigned long periodic_count;
9b5ef64a3   Yoichi Yuasa   rtc: update vr41x...
86
  static unsigned int alarm_enabled;
2fac6674d   Anton Vorontsov   rtc: bunch of dri...
87
88
  static int aie_irq;
  static int pie_irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
91
  static inline unsigned long read_elapsed_second(void)
  {
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
92

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  	unsigned long first_low, first_mid, first_high;
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
94

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  	unsigned long second_low, second_mid, second_high;
  
  	do {
  		first_low = rtc1_read(ETIMELREG);
  		first_mid = rtc1_read(ETIMEMREG);
  		first_high = rtc1_read(ETIMEHREG);
  		second_low = rtc1_read(ETIMELREG);
  		second_mid = rtc1_read(ETIMEMREG);
  		second_high = rtc1_read(ETIMEHREG);
  	} while (first_low != second_low || first_mid != second_mid ||
  	         first_high != second_high);
  
  	return (first_high << 17) | (first_mid << 1) | (first_low >> 15);
  }
  
  static inline void write_elapsed_second(unsigned long sec)
  {
  	spin_lock_irq(&rtc_lock);
  
  	rtc1_write(ETIMELREG, (uint16_t)(sec << 15));
  	rtc1_write(ETIMEMREG, (uint16_t)(sec >> 1));
  	rtc1_write(ETIMEHREG, (uint16_t)(sec >> 17));
  
  	spin_unlock_irq(&rtc_lock);
  }
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
120
  static void vr41xx_rtc_release(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
  
  	spin_lock_irq(&rtc_lock);
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
124
125
126
127
128
  	rtc1_write(ECMPLREG, 0);
  	rtc1_write(ECMPMREG, 0);
  	rtc1_write(ECMPHREG, 0);
  	rtc1_write(RTCL1LREG, 0);
  	rtc1_write(RTCL1HREG, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
  
  	spin_unlock_irq(&rtc_lock);
bd0765098   Yoichi Yuasa   [MIPS] separate p...
131
132
  	disable_irq(aie_irq);
  	disable_irq(pie_irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  }
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
134
  static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
138
139
  {
  	unsigned long epoch_sec, elapsed_sec;
  
  	epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
  	elapsed_sec = read_elapsed_second();
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
140
141
142
  	rtc_time_to_tm(epoch_sec + elapsed_sec, time);
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  }
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
144
  static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
149
150
151
152
  {
  	unsigned long epoch_sec, current_sec;
  
  	epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
  	current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
  	                     time->tm_hour, time->tm_min, time->tm_sec);
  
  	write_elapsed_second(current_sec - epoch_sec);
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
153
154
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  }
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
156
  static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  {
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
158
159
  	unsigned long low, mid, high;
  	struct rtc_time *time = &wkalrm->time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
161
  	spin_lock_irq(&rtc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
163
164
165
  	low = rtc1_read(ECMPLREG);
  	mid = rtc1_read(ECMPMREG);
  	high = rtc1_read(ECMPHREG);
9b5ef64a3   Yoichi Yuasa   rtc: update vr41x...
166
  	wkalrm->enabled = alarm_enabled;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
168
  	spin_unlock_irq(&rtc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
170
  	rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
172
173
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
175
176
177
178
  static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
  {
  	unsigned long alarm_sec;
  	struct rtc_time *time = &wkalrm->time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
180
181
  	alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
  	                   time->tm_hour, time->tm_min, time->tm_sec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
183
  	spin_lock_irq(&rtc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184

9b5ef64a3   Yoichi Yuasa   rtc: update vr41x...
185
  	if (alarm_enabled)
bd0765098   Yoichi Yuasa   [MIPS] separate p...
186
  		disable_irq(aie_irq);
9b5ef64a3   Yoichi Yuasa   rtc: update vr41x...
187

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
188
189
190
  	rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
  	rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
  	rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191

9b5ef64a3   Yoichi Yuasa   rtc: update vr41x...
192
  	if (wkalrm->enabled)
bd0765098   Yoichi Yuasa   [MIPS] separate p...
193
  		enable_irq(aie_irq);
9b5ef64a3   Yoichi Yuasa   rtc: update vr41x...
194
195
  
  	alarm_enabled = wkalrm->enabled;
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
196
  	spin_unlock_irq(&rtc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
199
  
  	return 0;
  }
4cad4431f   Yoichi Yuasa   rtc-vr41xx: add i...
200
201
  static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  	switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
  	case RTC_EPOCH_READ:
  		return put_user(epoch, (unsigned long __user *)arg);
  	case RTC_EPOCH_SET:
  		/* Doesn't support before 1900 */
  		if (arg < 1900)
  			return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
210
211
  		epoch = arg;
  		break;
  	default:
b3969e583   Alessandro Zummo   [PATCH] rtc subsy...
212
  		return -ENOIOCTLCMD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
214
215
216
  	}
  
  	return 0;
  }
16380c153   John Stultz   RTC: Convert rtc ...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  {
  	spin_lock_irq(&rtc_lock);
  	if (enabled) {
  		if (!alarm_enabled) {
  			enable_irq(aie_irq);
  			alarm_enabled = 1;
  		}
  	} else {
  		if (alarm_enabled) {
  			disable_irq(aie_irq);
  			alarm_enabled = 0;
  		}
  	}
  	spin_unlock_irq(&rtc_lock);
  	return 0;
  }
7d12e780e   David Howells   IRQ: Maintain reg...
234
  static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
  {
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
236
237
  	struct platform_device *pdev = (struct platform_device *)dev_id;
  	struct rtc_device *rtc = platform_get_drvdata(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
239
  	rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240

ab6a2d70d   David Brownell   rtc: rtc interfac...
241
  	rtc_update_irq(rtc, 1, RTC_AF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
  
  	return IRQ_HANDLED;
  }
7d12e780e   David Howells   IRQ: Maintain reg...
245
  static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
  {
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
247
248
  	struct platform_device *pdev = (struct platform_device *)dev_id;
  	struct rtc_device *rtc = platform_get_drvdata(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  	unsigned long count = periodic_count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
252
253
  	rtc2_write(RTCINTREG, RTCLONG1_INT);
  
  	rtc1_write(RTCL1LREG, count);
  	rtc1_write(RTCL1HREG, count >> 16);
ab6a2d70d   David Brownell   rtc: rtc interfac...
254
  	rtc_update_irq(rtc, 1, RTC_PF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
256
257
  
  	return IRQ_HANDLED;
  }
ff8371ac9   David Brownell   [PATCH] constify ...
258
  static const struct rtc_class_ops vr41xx_rtc_ops = {
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
259
260
261
262
263
264
  	.release	= vr41xx_rtc_release,
  	.ioctl		= vr41xx_rtc_ioctl,
  	.read_time	= vr41xx_rtc_read_time,
  	.set_time	= vr41xx_rtc_set_time,
  	.read_alarm	= vr41xx_rtc_read_alarm,
  	.set_alarm	= vr41xx_rtc_set_alarm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  };
d39b6cfe6   Dmitry Torokhov   [PATCH] vr41xx: c...
266
  static int __devinit rtc_probe(struct platform_device *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  {
bd0765098   Yoichi Yuasa   [MIPS] separate p...
268
  	struct resource *res;
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
269
  	struct rtc_device *rtc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  	int retval;
bd0765098   Yoichi Yuasa   [MIPS] separate p...
271
  	if (pdev->num_resources != 4)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  		return -EBUSY;
bd0765098   Yoichi Yuasa   [MIPS] separate p...
273
274
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	if (!res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  		return -EBUSY;
a91912f8e   Yoichi Yuasa   rtc-vr41xx: use r...
276
  	rtc1_base = ioremap(res->start, resource_size(res));
bd0765098   Yoichi Yuasa   [MIPS] separate p...
277
  	if (!rtc1_base)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  		return -EBUSY;
bd0765098   Yoichi Yuasa   [MIPS] separate p...
279
280
281
282
283
284
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  	if (!res) {
  		retval = -EBUSY;
  		goto err_rtc1_iounmap;
  	}
a91912f8e   Yoichi Yuasa   rtc-vr41xx: use r...
285
  	rtc2_base = ioremap(res->start, resource_size(res));
bd0765098   Yoichi Yuasa   [MIPS] separate p...
286
287
288
  	if (!rtc2_base) {
  		retval = -EBUSY;
  		goto err_rtc1_iounmap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  	}
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
290
291
  	rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE);
  	if (IS_ERR(rtc)) {
bd0765098   Yoichi Yuasa   [MIPS] separate p...
292
293
  		retval = PTR_ERR(rtc);
  		goto err_iounmap_all;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
  	}
4cad4431f   Yoichi Yuasa   rtc-vr41xx: add i...
295
  	rtc->max_user_freq = MAX_PERIODIC_RATE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
299
300
301
302
  	spin_lock_irq(&rtc_lock);
  
  	rtc1_write(ECMPLREG, 0);
  	rtc1_write(ECMPMREG, 0);
  	rtc1_write(ECMPHREG, 0);
  	rtc1_write(RTCL1LREG, 0);
  	rtc1_write(RTCL1HREG, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	spin_unlock_irq(&rtc_lock);
bd0765098   Yoichi Yuasa   [MIPS] separate p...
304
  	aie_irq = platform_get_irq(pdev, 0);
2fac6674d   Anton Vorontsov   rtc: bunch of dri...
305
  	if (aie_irq <= 0) {
bd0765098   Yoichi Yuasa   [MIPS] separate p...
306
307
  		retval = -EBUSY;
  		goto err_device_unregister;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  	}
bd0765098   Yoichi Yuasa   [MIPS] separate p...
309
310
311
312
313
314
  	retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED,
  	                     "elapsed_time", pdev);
  	if (retval < 0)
  		goto err_device_unregister;
  
  	pie_irq = platform_get_irq(pdev, 1);
2fac6674d   Anton Vorontsov   rtc: bunch of dri...
315
  	if (pie_irq <= 0)
bd0765098   Yoichi Yuasa   [MIPS] separate p...
316
317
318
319
320
321
  		goto err_free_irq;
  
  	retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
  		             "rtclong1", pdev);
  	if (retval < 0)
  		goto err_free_irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
323
  	platform_set_drvdata(pdev, rtc);
bd0765098   Yoichi Yuasa   [MIPS] separate p...
324
325
  	disable_irq(aie_irq);
  	disable_irq(pie_irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
329
330
  	printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series
  ");
  
  	return 0;
bd0765098   Yoichi Yuasa   [MIPS] separate p...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
  
  err_free_irq:
  	free_irq(aie_irq, pdev);
  
  err_device_unregister:
  	rtc_device_unregister(rtc);
  
  err_iounmap_all:
  	iounmap(rtc2_base);
  	rtc2_base = NULL;
  
  err_rtc1_iounmap:
  	iounmap(rtc1_base);
  	rtc1_base = NULL;
  
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  }
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
348
  static int __devexit rtc_remove(struct platform_device *pdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
  {
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
350
  	struct rtc_device *rtc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351

8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
352
  	rtc = platform_get_drvdata(pdev);
bd0765098   Yoichi Yuasa   [MIPS] separate p...
353
  	if (rtc)
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
354
355
356
  		rtc_device_unregister(rtc);
  
  	platform_set_drvdata(pdev, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357

bd0765098   Yoichi Yuasa   [MIPS] separate p...
358
359
360
  	free_irq(aie_irq, pdev);
  	free_irq(pie_irq, pdev);
  	if (rtc1_base)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  		iounmap(rtc1_base);
bd0765098   Yoichi Yuasa   [MIPS] separate p...
362
  	if (rtc2_base)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
364
365
366
  		iounmap(rtc2_base);
  
  	return 0;
  }
ad28a07bc   Kay Sievers   rtc: fix platform...
367
368
  /* work with hotplug and coldplug */
  MODULE_ALIAS("platform:RTC");
8417eb7a1   Yoichi Yuasa   [PATCH] RTC subsy...
369
  static struct platform_driver rtc_platform_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
  	.probe		= rtc_probe,
d39b6cfe6   Dmitry Torokhov   [PATCH] vr41xx: c...
371
  	.remove		= __devexit_p(rtc_remove),
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
372
373
  	.driver		= {
  		.name	= rtc_name,
d39b6cfe6   Dmitry Torokhov   [PATCH] vr41xx: c...
374
  		.owner	= THIS_MODULE,
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
375
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  };
0c4eae665   Axel Lin   rtc: convert driv...
377
  module_platform_driver(rtc_platform_driver);