Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtc-davinci.c
Go to the documentation of this file.
1 /*
2  * DaVinci Power Management and Real Time Clock Driver for TI platforms
3  *
4  * Copyright (C) 2009 Texas Instruments, Inc
5  *
6  * Author: Miguel Aguilar <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 #include <linux/kernel.h>
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/ioport.h>
26 #include <linux/delay.h>
27 #include <linux/spinlock.h>
28 #include <linux/rtc.h>
29 #include <linux/bcd.h>
30 #include <linux/platform_device.h>
31 #include <linux/io.h>
32 #include <linux/slab.h>
33 
34 /*
35  * The DaVinci RTC is a simple RTC with the following
36  * Sec: 0 - 59 : BCD count
37  * Min: 0 - 59 : BCD count
38  * Hour: 0 - 23 : BCD count
39  * Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years )
40  */
41 
42 /* PRTC interface registers */
43 #define DAVINCI_PRTCIF_PID 0x00
44 #define PRTCIF_CTLR 0x04
45 #define PRTCIF_LDATA 0x08
46 #define PRTCIF_UDATA 0x0C
47 #define PRTCIF_INTEN 0x10
48 #define PRTCIF_INTFLG 0x14
49 
50 /* PRTCIF_CTLR bit fields */
51 #define PRTCIF_CTLR_BUSY BIT(31)
52 #define PRTCIF_CTLR_SIZE BIT(25)
53 #define PRTCIF_CTLR_DIR BIT(24)
54 #define PRTCIF_CTLR_BENU_MSB BIT(23)
55 #define PRTCIF_CTLR_BENU_3RD_BYTE BIT(22)
56 #define PRTCIF_CTLR_BENU_2ND_BYTE BIT(21)
57 #define PRTCIF_CTLR_BENU_LSB BIT(20)
58 #define PRTCIF_CTLR_BENU_MASK (0x00F00000)
59 #define PRTCIF_CTLR_BENL_MSB BIT(19)
60 #define PRTCIF_CTLR_BENL_3RD_BYTE BIT(18)
61 #define PRTCIF_CTLR_BENL_2ND_BYTE BIT(17)
62 #define PRTCIF_CTLR_BENL_LSB BIT(16)
63 #define PRTCIF_CTLR_BENL_MASK (0x000F0000)
64 
65 /* PRTCIF_INTEN bit fields */
66 #define PRTCIF_INTEN_RTCSS BIT(1)
67 #define PRTCIF_INTEN_RTCIF BIT(0)
68 #define PRTCIF_INTEN_MASK (PRTCIF_INTEN_RTCSS \
69  | PRTCIF_INTEN_RTCIF)
70 
71 /* PRTCIF_INTFLG bit fields */
72 #define PRTCIF_INTFLG_RTCSS BIT(1)
73 #define PRTCIF_INTFLG_RTCIF BIT(0)
74 #define PRTCIF_INTFLG_MASK (PRTCIF_INTFLG_RTCSS \
75  | PRTCIF_INTFLG_RTCIF)
76 
77 /* PRTC subsystem registers */
78 #define PRTCSS_RTC_INTC_EXTENA1 (0x0C)
79 #define PRTCSS_RTC_CTRL (0x10)
80 #define PRTCSS_RTC_WDT (0x11)
81 #define PRTCSS_RTC_TMR0 (0x12)
82 #define PRTCSS_RTC_TMR1 (0x13)
83 #define PRTCSS_RTC_CCTRL (0x14)
84 #define PRTCSS_RTC_SEC (0x15)
85 #define PRTCSS_RTC_MIN (0x16)
86 #define PRTCSS_RTC_HOUR (0x17)
87 #define PRTCSS_RTC_DAY0 (0x18)
88 #define PRTCSS_RTC_DAY1 (0x19)
89 #define PRTCSS_RTC_AMIN (0x1A)
90 #define PRTCSS_RTC_AHOUR (0x1B)
91 #define PRTCSS_RTC_ADAY0 (0x1C)
92 #define PRTCSS_RTC_ADAY1 (0x1D)
93 #define PRTCSS_RTC_CLKC_CNT (0x20)
94 
95 /* PRTCSS_RTC_INTC_EXTENA1 */
96 #define PRTCSS_RTC_INTC_EXTENA1_MASK (0x07)
97 
98 /* PRTCSS_RTC_CTRL bit fields */
99 #define PRTCSS_RTC_CTRL_WDTBUS BIT(7)
100 #define PRTCSS_RTC_CTRL_WEN BIT(6)
101 #define PRTCSS_RTC_CTRL_WDRT BIT(5)
102 #define PRTCSS_RTC_CTRL_WDTFLG BIT(4)
103 #define PRTCSS_RTC_CTRL_TE BIT(3)
104 #define PRTCSS_RTC_CTRL_TIEN BIT(2)
105 #define PRTCSS_RTC_CTRL_TMRFLG BIT(1)
106 #define PRTCSS_RTC_CTRL_TMMD BIT(0)
107 
108 /* PRTCSS_RTC_CCTRL bit fields */
109 #define PRTCSS_RTC_CCTRL_CALBUSY BIT(7)
110 #define PRTCSS_RTC_CCTRL_DAEN BIT(5)
111 #define PRTCSS_RTC_CCTRL_HAEN BIT(4)
112 #define PRTCSS_RTC_CCTRL_MAEN BIT(3)
113 #define PRTCSS_RTC_CCTRL_ALMFLG BIT(2)
114 #define PRTCSS_RTC_CCTRL_AIEN BIT(1)
115 #define PRTCSS_RTC_CCTRL_CAEN BIT(0)
116 
117 static DEFINE_SPINLOCK(davinci_rtc_lock);
118 
119 struct davinci_rtc {
120  struct rtc_device *rtc;
121  void __iomem *base;
123  size_t base_size;
124  int irq;
125 };
126 
127 static inline void rtcif_write(struct davinci_rtc *davinci_rtc,
128  u32 val, u32 addr)
129 {
130  writel(val, davinci_rtc->base + addr);
131 }
132 
133 static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr)
134 {
135  return readl(davinci_rtc->base + addr);
136 }
137 
138 static inline void rtcif_wait(struct davinci_rtc *davinci_rtc)
139 {
140  while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY)
141  cpu_relax();
142 }
143 
144 static inline void rtcss_write(struct davinci_rtc *davinci_rtc,
145  unsigned long val, u8 addr)
146 {
147  rtcif_wait(davinci_rtc);
148 
149  rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR);
150  rtcif_write(davinci_rtc, val, PRTCIF_LDATA);
151 
152  rtcif_wait(davinci_rtc);
153 }
154 
155 static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr)
156 {
157  rtcif_wait(davinci_rtc);
158 
159  rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr,
160  PRTCIF_CTLR);
161 
162  rtcif_wait(davinci_rtc);
163 
164  return rtcif_read(davinci_rtc, PRTCIF_LDATA);
165 }
166 
167 static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc)
168 {
169  while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
171  cpu_relax();
172 }
173 
174 static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev)
175 {
176  struct davinci_rtc *davinci_rtc = class_dev;
177  unsigned long events = 0;
178  u32 irq_flg;
179  u8 alm_irq, tmr_irq;
180  u8 rtc_ctrl, rtc_cctrl;
181  int ret = IRQ_NONE;
182 
183  irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) &
185 
186  alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
188 
189  tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) &
191 
192  if (irq_flg) {
193  if (alm_irq) {
194  events |= RTC_IRQF | RTC_AF;
195  rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
196  rtc_cctrl |= PRTCSS_RTC_CCTRL_ALMFLG;
197  rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
198  } else if (tmr_irq) {
199  events |= RTC_IRQF | RTC_PF;
200  rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
201  rtc_ctrl |= PRTCSS_RTC_CTRL_TMRFLG;
202  rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
203  }
204 
205  rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS,
206  PRTCIF_INTFLG);
207  rtc_update_irq(davinci_rtc->rtc, 1, events);
208 
209  ret = IRQ_HANDLED;
210  }
211 
212  return ret;
213 }
214 
215 static int
216 davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
217 {
218  struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
219  u8 rtc_ctrl;
220  unsigned long flags;
221  int ret = 0;
222 
223  spin_lock_irqsave(&davinci_rtc_lock, flags);
224 
225  rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
226 
227  switch (cmd) {
228  case RTC_WIE_ON:
230  break;
231  case RTC_WIE_OFF:
232  rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
233  break;
234  default:
235  ret = -ENOIOCTLCMD;
236  }
237 
238  rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
239 
240  spin_unlock_irqrestore(&davinci_rtc_lock, flags);
241 
242  return ret;
243 }
244 
245 static int convertfromdays(u16 days, struct rtc_time *tm)
246 {
247  int tmp_days, year, mon;
248 
249  for (year = 2000;; year++) {
250  tmp_days = rtc_year_days(1, 12, year);
251  if (days >= tmp_days)
252  days -= tmp_days;
253  else {
254  for (mon = 0;; mon++) {
255  tmp_days = rtc_month_days(mon, year);
256  if (days >= tmp_days) {
257  days -= tmp_days;
258  } else {
259  tm->tm_year = year - 1900;
260  tm->tm_mon = mon;
261  tm->tm_mday = days + 1;
262  break;
263  }
264  }
265  break;
266  }
267  }
268  return 0;
269 }
270 
271 static int convert2days(u16 *days, struct rtc_time *tm)
272 {
273  int i;
274  *days = 0;
275 
276  /* epoch == 1900 */
277  if (tm->tm_year < 100 || tm->tm_year > 199)
278  return -EINVAL;
279 
280  for (i = 2000; i < 1900 + tm->tm_year; i++)
281  *days += rtc_year_days(1, 12, i);
282 
283  *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year);
284 
285  return 0;
286 }
287 
288 static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm)
289 {
290  struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
291  u16 days = 0;
292  u8 day0, day1;
293  unsigned long flags;
294 
295  spin_lock_irqsave(&davinci_rtc_lock, flags);
296 
297  davinci_rtcss_calendar_wait(davinci_rtc);
298  tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC));
299 
300  davinci_rtcss_calendar_wait(davinci_rtc);
301  tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN));
302 
303  davinci_rtcss_calendar_wait(davinci_rtc);
304  tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR));
305 
306  davinci_rtcss_calendar_wait(davinci_rtc);
307  day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0);
308 
309  davinci_rtcss_calendar_wait(davinci_rtc);
310  day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1);
311 
312  spin_unlock_irqrestore(&davinci_rtc_lock, flags);
313 
314  days |= day1;
315  days <<= 8;
316  days |= day0;
317 
318  if (convertfromdays(days, tm) < 0)
319  return -EINVAL;
320 
321  return 0;
322 }
323 
324 static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm)
325 {
326  struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
327  u16 days;
328  u8 rtc_cctrl;
329  unsigned long flags;
330 
331  if (convert2days(&days, tm) < 0)
332  return -EINVAL;
333 
334  spin_lock_irqsave(&davinci_rtc_lock, flags);
335 
336  davinci_rtcss_calendar_wait(davinci_rtc);
337  rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC);
338 
339  davinci_rtcss_calendar_wait(davinci_rtc);
340  rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN);
341 
342  davinci_rtcss_calendar_wait(davinci_rtc);
343  rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR);
344 
345  davinci_rtcss_calendar_wait(davinci_rtc);
346  rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0);
347 
348  davinci_rtcss_calendar_wait(davinci_rtc);
349  rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1);
350 
351  rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
352  rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN;
353  rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
354 
355  spin_unlock_irqrestore(&davinci_rtc_lock, flags);
356 
357  return 0;
358 }
359 
360 static int davinci_rtc_alarm_irq_enable(struct device *dev,
361  unsigned int enabled)
362 {
363  struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
364  unsigned long flags;
365  u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
366 
367  spin_lock_irqsave(&davinci_rtc_lock, flags);
368 
369  if (enabled)
370  rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN |
375  else
376  rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN;
377 
378  davinci_rtcss_calendar_wait(davinci_rtc);
379  rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
380 
381  spin_unlock_irqrestore(&davinci_rtc_lock, flags);
382 
383  return 0;
384 }
385 
386 static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
387 {
388  struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
389  u16 days = 0;
390  u8 day0, day1;
391  unsigned long flags;
392 
393  spin_lock_irqsave(&davinci_rtc_lock, flags);
394 
395  davinci_rtcss_calendar_wait(davinci_rtc);
396  alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN));
397 
398  davinci_rtcss_calendar_wait(davinci_rtc);
399  alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR));
400 
401  davinci_rtcss_calendar_wait(davinci_rtc);
402  day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0);
403 
404  davinci_rtcss_calendar_wait(davinci_rtc);
405  day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1);
406 
407  spin_unlock_irqrestore(&davinci_rtc_lock, flags);
408  days |= day1;
409  days <<= 8;
410  days |= day0;
411 
412  if (convertfromdays(days, &alm->time) < 0)
413  return -EINVAL;
414 
415  alm->pending = !!(rtcss_read(davinci_rtc,
418  alm->enabled = alm->pending && device_may_wakeup(dev);
419 
420  return 0;
421 }
422 
423 static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
424 {
425  struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
426  unsigned long flags;
427  u16 days;
428 
429  if (alm->time.tm_mday <= 0 && alm->time.tm_mon < 0
430  && alm->time.tm_year < 0) {
431  struct rtc_time tm;
432  unsigned long now, then;
433 
434  davinci_rtc_read_time(dev, &tm);
435  rtc_tm_to_time(&tm, &now);
436 
437  alm->time.tm_mday = tm.tm_mday;
438  alm->time.tm_mon = tm.tm_mon;
439  alm->time.tm_year = tm.tm_year;
440  rtc_tm_to_time(&alm->time, &then);
441 
442  if (then < now) {
443  rtc_time_to_tm(now + 24 * 60 * 60, &tm);
444  alm->time.tm_mday = tm.tm_mday;
445  alm->time.tm_mon = tm.tm_mon;
446  alm->time.tm_year = tm.tm_year;
447  }
448  }
449 
450  if (convert2days(&days, &alm->time) < 0)
451  return -EINVAL;
452 
453  spin_lock_irqsave(&davinci_rtc_lock, flags);
454 
455  davinci_rtcss_calendar_wait(davinci_rtc);
456  rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN);
457 
458  davinci_rtcss_calendar_wait(davinci_rtc);
459  rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR);
460 
461  davinci_rtcss_calendar_wait(davinci_rtc);
462  rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0);
463 
464  davinci_rtcss_calendar_wait(davinci_rtc);
465  rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1);
466 
467  spin_unlock_irqrestore(&davinci_rtc_lock, flags);
468 
469  return 0;
470 }
471 
472 static struct rtc_class_ops davinci_rtc_ops = {
473  .ioctl = davinci_rtc_ioctl,
474  .read_time = davinci_rtc_read_time,
475  .set_time = davinci_rtc_set_time,
476  .alarm_irq_enable = davinci_rtc_alarm_irq_enable,
477  .read_alarm = davinci_rtc_read_alarm,
478  .set_alarm = davinci_rtc_set_alarm,
479 };
480 
481 static int __init davinci_rtc_probe(struct platform_device *pdev)
482 {
483  struct device *dev = &pdev->dev;
484  struct davinci_rtc *davinci_rtc;
485  struct resource *res, *mem;
486  int ret = 0;
487 
488  davinci_rtc = kzalloc(sizeof(struct davinci_rtc), GFP_KERNEL);
489  if (!davinci_rtc) {
490  dev_dbg(dev, "could not allocate memory for private data\n");
491  return -ENOMEM;
492  }
493 
494  davinci_rtc->irq = platform_get_irq(pdev, 0);
495  if (davinci_rtc->irq < 0) {
496  dev_err(dev, "no RTC irq\n");
497  ret = davinci_rtc->irq;
498  goto fail1;
499  }
500 
501  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
502  if (!res) {
503  dev_err(dev, "no mem resource\n");
504  ret = -EINVAL;
505  goto fail1;
506  }
507 
508  davinci_rtc->pbase = res->start;
509  davinci_rtc->base_size = resource_size(res);
510 
511  mem = request_mem_region(davinci_rtc->pbase, davinci_rtc->base_size,
512  pdev->name);
513  if (!mem) {
514  dev_err(dev, "RTC registers at %08x are not free\n",
515  davinci_rtc->pbase);
516  ret = -EBUSY;
517  goto fail1;
518  }
519 
520  davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size);
521  if (!davinci_rtc->base) {
522  dev_err(dev, "unable to ioremap MEM resource\n");
523  ret = -ENOMEM;
524  goto fail2;
525  }
526 
527  platform_set_drvdata(pdev, davinci_rtc);
528 
529  davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
530  &davinci_rtc_ops, THIS_MODULE);
531  if (IS_ERR(davinci_rtc->rtc)) {
532  dev_err(dev, "unable to register RTC device, err %ld\n",
533  PTR_ERR(davinci_rtc->rtc));
534  goto fail3;
535  }
536 
537  rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
538  rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
539  rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1);
540 
541  rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL);
542  rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
543 
544  ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
545  0, "davinci_rtc", davinci_rtc);
546  if (ret < 0) {
547  dev_err(dev, "unable to register davinci RTC interrupt\n");
548  goto fail4;
549  }
550 
551  /* Enable interrupts */
552  rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN);
553  rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK,
555 
556  rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL);
557 
558  device_init_wakeup(&pdev->dev, 0);
559 
560  return 0;
561 
562 fail4:
563  rtc_device_unregister(davinci_rtc->rtc);
564 fail3:
565  platform_set_drvdata(pdev, NULL);
566  iounmap(davinci_rtc->base);
567 fail2:
568  release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size);
569 fail1:
570  kfree(davinci_rtc);
571 
572  return ret;
573 }
574 
575 static int __devexit davinci_rtc_remove(struct platform_device *pdev)
576 {
577  struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
578 
579  device_init_wakeup(&pdev->dev, 0);
580 
581  rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
582 
583  free_irq(davinci_rtc->irq, davinci_rtc);
584 
585  rtc_device_unregister(davinci_rtc->rtc);
586 
587  iounmap(davinci_rtc->base);
588  release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size);
589 
590  platform_set_drvdata(pdev, NULL);
591 
592  kfree(davinci_rtc);
593 
594  return 0;
595 }
596 
597 static struct platform_driver davinci_rtc_driver = {
598  .probe = davinci_rtc_probe,
599  .remove = __devexit_p(davinci_rtc_remove),
600  .driver = {
601  .name = "rtc_davinci",
602  .owner = THIS_MODULE,
603  },
604 };
605 
606 static int __init rtc_init(void)
607 {
608  return platform_driver_probe(&davinci_rtc_driver, davinci_rtc_probe);
609 }
610 module_init(rtc_init);
611 
612 static void __exit rtc_exit(void)
613 {
614  platform_driver_unregister(&davinci_rtc_driver);
615 }
616 module_exit(rtc_exit);
617 
618 MODULE_AUTHOR("Miguel Aguilar <[email protected]>");
619 MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
620 MODULE_LICENSE("GPL");