aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Sharp <andy.sharp@onstor.com>2008-02-06 04:38:46 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:13 -0500
commit8f26795a22b12880bb07be688df72b4266f67be8 (patch)
tree880e4826a5de1e6ca8746c7fb00973ab9f2ee5f3
parent8a0bdfd7a05f5bb0486fbe7146a2cf775957e95e (diff)
Platform real time clock driver for Dallas 1511 chip
Add RTC support for DS1511 RTC/WDT chip. Signed-off-by: Andy Sharp <andy.sharp@onstor.com> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/rtc/Kconfig10
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ds1511.c656
3 files changed, 667 insertions, 0 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0cc448c0eddd..4a39b76aeacd 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -312,6 +312,16 @@ config RTC_DRV_DS1302
312 help 312 help
313 If you say yes here you get support for the Dallas DS1302 RTC chips. 313 If you say yes here you get support for the Dallas DS1302 RTC chips.
314 314
315config RTC_DRV_DS1511
316 tristate "Dallas DS1511"
317 depends on RTC_CLASS
318 help
319 If you say yes here you get support for the
320 Dallas DS1511 timekeeping/watchdog chip.
321
322 This driver can also be built as a module. If so, the module
323 will be called rtc-ds1511.
324
315config RTC_DRV_DS1553 325config RTC_DRV_DS1553
316 tristate "Maxim/Dallas DS1553" 326 tristate "Maxim/Dallas DS1553"
317 help 327 help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index b5c3d3996444..36586c28cefc 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
25obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o 25obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
26obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o 26obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
27obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o 27obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
28obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
28obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o 29obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
29obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o 30obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
30obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o 31obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
new file mode 100644
index 000000000000..d74b8086fa31
--- /dev/null
+++ b/drivers/rtc/rtc-ds1511.c
@@ -0,0 +1,656 @@
1/*
2 * An rtc driver for the Dallas DS1511
3 *
4 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
5 * Copyright (C) 2007 Andrew Sharp <andy.sharp@onstor.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Real time clock driver for the Dallas 1511 chip, which also
12 * contains a watchdog timer. There is a tiny amount of code that
13 * platform code could use to mess with the watchdog device a little
14 * bit, but not a full watchdog driver.
15 */
16
17#include <linux/bcd.h>
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/delay.h>
21#include <linux/interrupt.h>
22#include <linux/rtc.h>
23#include <linux/platform_device.h>
24#include <linux/io.h>
25
26#define DRV_VERSION "0.6"
27
28enum ds1511reg {
29 DS1511_SEC = 0x0,
30 DS1511_MIN = 0x1,
31 DS1511_HOUR = 0x2,
32 DS1511_DOW = 0x3,
33 DS1511_DOM = 0x4,
34 DS1511_MONTH = 0x5,
35 DS1511_YEAR = 0x6,
36 DS1511_CENTURY = 0x7,
37 DS1511_AM1_SEC = 0x8,
38 DS1511_AM2_MIN = 0x9,
39 DS1511_AM3_HOUR = 0xa,
40 DS1511_AM4_DATE = 0xb,
41 DS1511_WD_MSEC = 0xc,
42 DS1511_WD_SEC = 0xd,
43 DS1511_CONTROL_A = 0xe,
44 DS1511_CONTROL_B = 0xf,
45 DS1511_RAMADDR_LSB = 0x10,
46 DS1511_RAMDATA = 0x13
47};
48
49#define DS1511_BLF1 0x80
50#define DS1511_BLF2 0x40
51#define DS1511_PRS 0x20
52#define DS1511_PAB 0x10
53#define DS1511_TDF 0x08
54#define DS1511_KSF 0x04
55#define DS1511_WDF 0x02
56#define DS1511_IRQF 0x01
57#define DS1511_TE 0x80
58#define DS1511_CS 0x40
59#define DS1511_BME 0x20
60#define DS1511_TPE 0x10
61#define DS1511_TIE 0x08
62#define DS1511_KIE 0x04
63#define DS1511_WDE 0x02
64#define DS1511_WDS 0x01
65#define DS1511_RAM_MAX 0xff
66
67#define RTC_CMD DS1511_CONTROL_B
68#define RTC_CMD1 DS1511_CONTROL_A
69
70#define RTC_ALARM_SEC DS1511_AM1_SEC
71#define RTC_ALARM_MIN DS1511_AM2_MIN
72#define RTC_ALARM_HOUR DS1511_AM3_HOUR
73#define RTC_ALARM_DATE DS1511_AM4_DATE
74
75#define RTC_SEC DS1511_SEC
76#define RTC_MIN DS1511_MIN
77#define RTC_HOUR DS1511_HOUR
78#define RTC_DOW DS1511_DOW
79#define RTC_DOM DS1511_DOM
80#define RTC_MON DS1511_MONTH
81#define RTC_YEAR DS1511_YEAR
82#define RTC_CENTURY DS1511_CENTURY
83
84#define RTC_TIE DS1511_TIE
85#define RTC_TE DS1511_TE
86
87struct rtc_plat_data {
88 struct rtc_device *rtc;
89 void __iomem *ioaddr; /* virtual base address */
90 unsigned long baseaddr; /* physical base address */
91 int size; /* amount of memory mapped */
92 int irq;
93 unsigned int irqen;
94 int alrm_sec;
95 int alrm_min;
96 int alrm_hour;
97 int alrm_mday;
98};
99
100static DEFINE_SPINLOCK(ds1511_lock);
101
102static __iomem char *ds1511_base;
103static u32 reg_spacing = 1;
104
105 static noinline void
106rtc_write(uint8_t val, uint32_t reg)
107{
108 writeb(val, ds1511_base + (reg * reg_spacing));
109}
110
111 static inline void
112rtc_write_alarm(uint8_t val, enum ds1511reg reg)
113{
114 rtc_write((val | 0x80), reg);
115}
116
117 static noinline uint8_t
118rtc_read(enum ds1511reg reg)
119{
120 return readb(ds1511_base + (reg * reg_spacing));
121}
122
123 static inline void
124rtc_disable_update(void)
125{
126 rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD);
127}
128
129 static void
130rtc_enable_update(void)
131{
132 rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD);
133}
134
135/*
136 * #define DS1511_WDOG_RESET_SUPPORT
137 *
138 * Uncomment this if you want to use these routines in
139 * some platform code.
140 */
141#ifdef DS1511_WDOG_RESET_SUPPORT
142/*
143 * just enough code to set the watchdog timer so that it
144 * will reboot the system
145 */
146 void
147ds1511_wdog_set(unsigned long deciseconds)
148{
149 /*
150 * the wdog timer can take 99.99 seconds
151 */
152 deciseconds %= 10000;
153 /*
154 * set the wdog values in the wdog registers
155 */
156 rtc_write(BIN2BCD(deciseconds % 100), DS1511_WD_MSEC);
157 rtc_write(BIN2BCD(deciseconds / 100), DS1511_WD_SEC);
158 /*
159 * set wdog enable and wdog 'steering' bit to issue a reset
160 */
161 rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD);
162}
163
164 void
165ds1511_wdog_disable(void)
166{
167 /*
168 * clear wdog enable and wdog 'steering' bits
169 */
170 rtc_write(rtc_read(RTC_CMD) & ~(DS1511_WDE | DS1511_WDS), RTC_CMD);
171 /*
172 * clear the wdog counter
173 */
174 rtc_write(0, DS1511_WD_MSEC);
175 rtc_write(0, DS1511_WD_SEC);
176}
177#endif
178
179/*
180 * set the rtc chip's idea of the time.
181 * stupidly, some callers call with year unmolested;
182 * and some call with year = year - 1900. thanks.
183 */
184 int
185ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
186{
187 u8 mon, day, dow, hrs, min, sec, yrs, cen;
188 unsigned int flags;
189
190 /*
191 * won't have to change this for a while
192 */
193 if (rtc_tm->tm_year < 1900) {
194 rtc_tm->tm_year += 1900;
195 }
196
197 if (rtc_tm->tm_year < 1970) {
198 return -EINVAL;
199 }
200 yrs = rtc_tm->tm_year % 100;
201 cen = rtc_tm->tm_year / 100;
202 mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */
203 day = rtc_tm->tm_mday;
204 dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */
205 hrs = rtc_tm->tm_hour;
206 min = rtc_tm->tm_min;
207 sec = rtc_tm->tm_sec;
208
209 if ((mon > 12) || (day == 0)) {
210 return -EINVAL;
211 }
212
213 if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) {
214 return -EINVAL;
215 }
216
217 if ((hrs >= 24) || (min >= 60) || (sec >= 60)) {
218 return -EINVAL;
219 }
220
221 /*
222 * each register is a different number of valid bits
223 */
224 sec = BIN2BCD(sec) & 0x7f;
225 min = BIN2BCD(min) & 0x7f;
226 hrs = BIN2BCD(hrs) & 0x3f;
227 day = BIN2BCD(day) & 0x3f;
228 mon = BIN2BCD(mon) & 0x1f;
229 yrs = BIN2BCD(yrs) & 0xff;
230 cen = BIN2BCD(cen) & 0xff;
231
232 spin_lock_irqsave(&ds1511_lock, flags);
233 rtc_disable_update();
234 rtc_write(cen, RTC_CENTURY);
235 rtc_write(yrs, RTC_YEAR);
236 rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON);
237 rtc_write(day, RTC_DOM);
238 rtc_write(hrs, RTC_HOUR);
239 rtc_write(min, RTC_MIN);
240 rtc_write(sec, RTC_SEC);
241 rtc_write(dow, RTC_DOW);
242 rtc_enable_update();
243 spin_unlock_irqrestore(&ds1511_lock, flags);
244
245 return 0;
246}
247
248 int
249ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
250{
251 unsigned int century;
252 unsigned int flags;
253
254 spin_lock_irqsave(&ds1511_lock, flags);
255 rtc_disable_update();
256
257 rtc_tm->tm_sec = rtc_read(RTC_SEC) & 0x7f;
258 rtc_tm->tm_min = rtc_read(RTC_MIN) & 0x7f;
259 rtc_tm->tm_hour = rtc_read(RTC_HOUR) & 0x3f;
260 rtc_tm->tm_mday = rtc_read(RTC_DOM) & 0x3f;
261 rtc_tm->tm_wday = rtc_read(RTC_DOW) & 0x7;
262 rtc_tm->tm_mon = rtc_read(RTC_MON) & 0x1f;
263 rtc_tm->tm_year = rtc_read(RTC_YEAR) & 0x7f;
264 century = rtc_read(RTC_CENTURY);
265
266 rtc_enable_update();
267 spin_unlock_irqrestore(&ds1511_lock, flags);
268
269 rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec);
270 rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min);
271 rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour);
272 rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday);
273 rtc_tm->tm_wday = BCD2BIN(rtc_tm->tm_wday);
274 rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon);
275 rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year);
276 century = BCD2BIN(century) * 100;
277
278 /*
279 * Account for differences between how the RTC uses the values
280 * and how they are defined in a struct rtc_time;
281 */
282 century += rtc_tm->tm_year;
283 rtc_tm->tm_year = century - 1900;
284
285 rtc_tm->tm_mon--;
286
287 if (rtc_valid_tm(rtc_tm) < 0) {
288 dev_err(dev, "retrieved date/time is not valid.\n");
289 rtc_time_to_tm(0, rtc_tm);
290 }
291 return 0;
292}
293
294/*
295 * write the alarm register settings
296 *
297 * we only have the use to interrupt every second, otherwise
298 * known as the update interrupt, or the interrupt if the whole
299 * date/hours/mins/secs matches. the ds1511 has many more
300 * permutations, but the kernel doesn't.
301 */
302 static void
303ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
304{
305 unsigned long flags;
306
307 spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
308 rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
309 0x80 : BIN2BCD(pdata->alrm_mday) & 0x3f,
310 RTC_ALARM_DATE);
311 rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
312 0x80 : BIN2BCD(pdata->alrm_hour) & 0x3f,
313 RTC_ALARM_HOUR);
314 rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
315 0x80 : BIN2BCD(pdata->alrm_min) & 0x7f,
316 RTC_ALARM_MIN);
317 rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
318 0x80 : BIN2BCD(pdata->alrm_sec) & 0x7f,
319 RTC_ALARM_SEC);
320 rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD);
321 rtc_read(RTC_CMD1); /* clear interrupts */
322 spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
323}
324
325 static int
326ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
327{
328 struct platform_device *pdev = to_platform_device(dev);
329 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
330
331 if (pdata->irq < 0) {
332 return -EINVAL;
333 }
334 pdata->alrm_mday = alrm->time.tm_mday;
335 pdata->alrm_hour = alrm->time.tm_hour;
336 pdata->alrm_min = alrm->time.tm_min;
337 pdata->alrm_sec = alrm->time.tm_sec;
338 if (alrm->enabled) {
339 pdata->irqen |= RTC_AF;
340 }
341 ds1511_rtc_update_alarm(pdata);
342 return 0;
343}
344
345 static int
346ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
347{
348 struct platform_device *pdev = to_platform_device(dev);
349 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
350
351 if (pdata->irq < 0) {
352 return -EINVAL;
353 }
354 alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday;
355 alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour;
356 alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min;
357 alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec;
358 alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0;
359 return 0;
360}
361
362 static irqreturn_t
363ds1511_interrupt(int irq, void *dev_id)
364{
365 struct platform_device *pdev = dev_id;
366 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
367 unsigned long events = RTC_IRQF;
368
369 /*
370 * read and clear interrupt
371 */
372 if (!(rtc_read(RTC_CMD1) & DS1511_IRQF)) {
373 return IRQ_NONE;
374 }
375 if (rtc_read(RTC_ALARM_SEC) & 0x80) {
376 events |= RTC_UF;
377 } else {
378 events |= RTC_AF;
379 }
380 rtc_update_irq(pdata->rtc, 1, events);
381 return IRQ_HANDLED;
382}
383
384 static void
385ds1511_rtc_release(struct device *dev)
386{
387 struct platform_device *pdev = to_platform_device(dev);
388 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
389
390 if (pdata->irq >= 0) {
391 pdata->irqen = 0;
392 ds1511_rtc_update_alarm(pdata);
393 }
394}
395
396 static int
397ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
398{
399 struct platform_device *pdev = to_platform_device(dev);
400 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
401
402 if (pdata->irq < 0) {
403 return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
404 }
405 switch (cmd) {
406 case RTC_AIE_OFF:
407 pdata->irqen &= ~RTC_AF;
408 ds1511_rtc_update_alarm(pdata);
409 break;
410 case RTC_AIE_ON:
411 pdata->irqen |= RTC_AF;
412 ds1511_rtc_update_alarm(pdata);
413 break;
414 case RTC_UIE_OFF:
415 pdata->irqen &= ~RTC_UF;
416 ds1511_rtc_update_alarm(pdata);
417 break;
418 case RTC_UIE_ON:
419 pdata->irqen |= RTC_UF;
420 ds1511_rtc_update_alarm(pdata);
421 break;
422 default:
423 return -ENOIOCTLCMD;
424 }
425 return 0;
426}
427
428static const struct rtc_class_ops ds1511_rtc_ops = {
429 .read_time = ds1511_rtc_read_time,
430 .set_time = ds1511_rtc_set_time,
431 .read_alarm = ds1511_rtc_read_alarm,
432 .set_alarm = ds1511_rtc_set_alarm,
433 .release = ds1511_rtc_release,
434 .ioctl = ds1511_rtc_ioctl,
435};
436
437 static ssize_t
438ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba,
439 char *buf, loff_t pos, size_t size)
440{
441 ssize_t count;
442
443 /*
444 * if count is more than one, turn on "burst" mode
445 * turn it off when you're done
446 */
447 if (size > 1) {
448 rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD);
449 }
450 if (pos > DS1511_RAM_MAX) {
451 pos = DS1511_RAM_MAX;
452 }
453 if (size + pos > DS1511_RAM_MAX + 1) {
454 size = DS1511_RAM_MAX - pos + 1;
455 }
456 rtc_write(pos, DS1511_RAMADDR_LSB);
457 for (count = 0; size > 0; count++, size--) {
458 *buf++ = rtc_read(DS1511_RAMDATA);
459 }
460 if (count > 1) {
461 rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD);
462 }
463 return count;
464}
465
466 static ssize_t
467ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr,
468 char *buf, loff_t pos, size_t size)
469{
470 ssize_t count;
471
472 /*
473 * if count is more than one, turn on "burst" mode
474 * turn it off when you're done
475 */
476 if (size > 1) {
477 rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD);
478 }
479 if (pos > DS1511_RAM_MAX) {
480 pos = DS1511_RAM_MAX;
481 }
482 if (size + pos > DS1511_RAM_MAX + 1) {
483 size = DS1511_RAM_MAX - pos + 1;
484 }
485 rtc_write(pos, DS1511_RAMADDR_LSB);
486 for (count = 0; size > 0; count++, size--) {
487 rtc_write(*buf++, DS1511_RAMDATA);
488 }
489 if (count > 1) {
490 rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD);
491 }
492 return count;
493}
494
495static struct bin_attribute ds1511_nvram_attr = {
496 .attr = {
497 .name = "nvram",
498 .mode = S_IRUGO | S_IWUGO,
499 .owner = THIS_MODULE,
500 },
501 .size = DS1511_RAM_MAX,
502 .read = ds1511_nvram_read,
503 .write = ds1511_nvram_write,
504};
505
506 static int __devinit
507ds1511_rtc_probe(struct platform_device *pdev)
508{
509 struct rtc_device *rtc;
510 struct resource *res;
511 struct rtc_plat_data *pdata = NULL;
512 int ret = 0;
513
514 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
515 if (!res) {
516 return -ENODEV;
517 }
518 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
519 if (!pdata) {
520 return -ENOMEM;
521 }
522 pdata->irq = -1;
523 pdata->size = res->end - res->start + 1;
524 if (!request_mem_region(res->start, pdata->size, pdev->name)) {
525 ret = -EBUSY;
526 goto out;
527 }
528 pdata->baseaddr = res->start;
529 pdata->size = pdata->size;
530 ds1511_base = ioremap(pdata->baseaddr, pdata->size);
531 if (!ds1511_base) {
532 ret = -ENOMEM;
533 goto out;
534 }
535 pdata->ioaddr = ds1511_base;
536 pdata->irq = platform_get_irq(pdev, 0);
537
538 /*
539 * turn on the clock and the crystal, etc.
540 */
541 rtc_write(0, RTC_CMD);
542 rtc_write(0, RTC_CMD1);
543 /*
544 * clear the wdog counter
545 */
546 rtc_write(0, DS1511_WD_MSEC);
547 rtc_write(0, DS1511_WD_SEC);
548 /*
549 * start the clock
550 */
551 rtc_enable_update();
552
553 /*
554 * check for a dying bat-tree
555 */
556 if (rtc_read(RTC_CMD1) & DS1511_BLF1) {
557 dev_warn(&pdev->dev, "voltage-low detected.\n");
558 }
559
560 /*
561 * if the platform has an interrupt in mind for this device,
562 * then by all means, set it
563 */
564 if (pdata->irq >= 0) {
565 rtc_read(RTC_CMD1);
566 if (request_irq(pdata->irq, ds1511_interrupt,
567 IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) {
568
569 dev_warn(&pdev->dev, "interrupt not available.\n");
570 pdata->irq = -1;
571 }
572 }
573
574 rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops,
575 THIS_MODULE);
576 if (IS_ERR(rtc)) {
577 ret = PTR_ERR(rtc);
578 goto out;
579 }
580 pdata->rtc = rtc;
581 platform_set_drvdata(pdev, pdata);
582 ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
583 if (ret) {
584 goto out;
585 }
586 return 0;
587 out:
588 if (pdata->rtc) {
589 rtc_device_unregister(pdata->rtc);
590 }
591 if (pdata->irq >= 0) {
592 free_irq(pdata->irq, pdev);
593 }
594 if (ds1511_base) {
595 iounmap(ds1511_base);
596 ds1511_base = NULL;
597 }
598 if (pdata->baseaddr) {
599 release_mem_region(pdata->baseaddr, pdata->size);
600 }
601
602 kfree(pdata);
603 return ret;
604}
605
606 static int __devexit
607ds1511_rtc_remove(struct platform_device *pdev)
608{
609 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
610
611 sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
612 rtc_device_unregister(pdata->rtc);
613 pdata->rtc = NULL;
614 if (pdata->irq >= 0) {
615 /*
616 * disable the alarm interrupt
617 */
618 rtc_write(rtc_read(RTC_CMD) & ~RTC_TIE, RTC_CMD);
619 rtc_read(RTC_CMD1);
620 free_irq(pdata->irq, pdev);
621 }
622 iounmap(pdata->ioaddr);
623 ds1511_base = NULL;
624 release_mem_region(pdata->baseaddr, pdata->size);
625 kfree(pdata);
626 return 0;
627}
628
629static struct platform_driver ds1511_rtc_driver = {
630 .probe = ds1511_rtc_probe,
631 .remove = __devexit_p(ds1511_rtc_remove),
632 .driver = {
633 .name = "ds1511",
634 .owner = THIS_MODULE,
635 },
636};
637
638 static int __init
639ds1511_rtc_init(void)
640{
641 return platform_driver_register(&ds1511_rtc_driver);
642}
643
644 static void __exit
645ds1511_rtc_exit(void)
646{
647 return platform_driver_unregister(&ds1511_rtc_driver);
648}
649
650module_init(ds1511_rtc_init);
651module_exit(ds1511_rtc_exit);
652
653MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>");
654MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
655MODULE_LICENSE("GPL");
656MODULE_VERSION(DRV_VERSION);