diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-05-25 02:38:26 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-05-25 02:38:26 -0400 |
commit | b1e50ebcf24668e57f058deb48b0704b5391ed0f (patch) | |
tree | 17e1b69b249d0738317b732186340c9dd053f1a1 /drivers/rtc | |
parent | 0c2a2ae32793e3500a15a449612485f5d17dd431 (diff) | |
parent | 7e125f7b9cbfce4101191b8076d606c517a73066 (diff) |
Merge remote branch 'origin' into secretlab/next-spi
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 89 | ||||
-rw-r--r-- | drivers/rtc/rtc-davinci.c | 673 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1305.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1511.c | 10 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1553.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1742.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-m41t80.c | 16 | ||||
-rw-r--r-- | drivers/rtc/rtc-m48t59.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-rx8581.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-stk17ta8.c | 8 | ||||
-rw-r--r-- | drivers/rtc/rtc-tx4939.c | 4 |
14 files changed, 771 insertions, 70 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6a1303759432..50ac047cd136 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -620,6 +620,16 @@ config RTC_DRV_NUC900 | |||
620 | 620 | ||
621 | comment "on-CPU RTC drivers" | 621 | comment "on-CPU RTC drivers" |
622 | 622 | ||
623 | config RTC_DRV_DAVINCI | ||
624 | tristate "TI DaVinci RTC" | ||
625 | depends on ARCH_DAVINCI_DM365 | ||
626 | help | ||
627 | If you say yes here you get support for the RTC on the | ||
628 | DaVinci platforms (DM365). | ||
629 | |||
630 | This driver can also be built as a module. If so, the module | ||
631 | will be called rtc-davinci. | ||
632 | |||
623 | config RTC_DRV_OMAP | 633 | config RTC_DRV_OMAP |
624 | tristate "TI OMAP1" | 634 | tristate "TI OMAP1" |
625 | depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX | 635 | depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 44ef194a9573..245311a1348f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o | |||
27 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o | 27 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o |
28 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 28 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
29 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o | 29 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o |
30 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o | ||
30 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o | 31 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o |
31 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 32 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
32 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o | 33 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e9aa814ddd23..96e8e70fbf1e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -238,31 +238,32 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
238 | rtc_control = CMOS_READ(RTC_CONTROL); | 238 | rtc_control = CMOS_READ(RTC_CONTROL); |
239 | spin_unlock_irq(&rtc_lock); | 239 | spin_unlock_irq(&rtc_lock); |
240 | 240 | ||
241 | /* REVISIT this assumes PC style usage: always BCD */ | 241 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
242 | 242 | if (((unsigned)t->time.tm_sec) < 0x60) | |
243 | if (((unsigned)t->time.tm_sec) < 0x60) | 243 | t->time.tm_sec = bcd2bin(t->time.tm_sec); |
244 | t->time.tm_sec = bcd2bin(t->time.tm_sec); | ||
245 | else | ||
246 | t->time.tm_sec = -1; | ||
247 | if (((unsigned)t->time.tm_min) < 0x60) | ||
248 | t->time.tm_min = bcd2bin(t->time.tm_min); | ||
249 | else | ||
250 | t->time.tm_min = -1; | ||
251 | if (((unsigned)t->time.tm_hour) < 0x24) | ||
252 | t->time.tm_hour = bcd2bin(t->time.tm_hour); | ||
253 | else | ||
254 | t->time.tm_hour = -1; | ||
255 | |||
256 | if (cmos->day_alrm) { | ||
257 | if (((unsigned)t->time.tm_mday) <= 0x31) | ||
258 | t->time.tm_mday = bcd2bin(t->time.tm_mday); | ||
259 | else | 244 | else |
260 | t->time.tm_mday = -1; | 245 | t->time.tm_sec = -1; |
261 | if (cmos->mon_alrm) { | 246 | if (((unsigned)t->time.tm_min) < 0x60) |
262 | if (((unsigned)t->time.tm_mon) <= 0x12) | 247 | t->time.tm_min = bcd2bin(t->time.tm_min); |
263 | t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; | 248 | else |
249 | t->time.tm_min = -1; | ||
250 | if (((unsigned)t->time.tm_hour) < 0x24) | ||
251 | t->time.tm_hour = bcd2bin(t->time.tm_hour); | ||
252 | else | ||
253 | t->time.tm_hour = -1; | ||
254 | |||
255 | if (cmos->day_alrm) { | ||
256 | if (((unsigned)t->time.tm_mday) <= 0x31) | ||
257 | t->time.tm_mday = bcd2bin(t->time.tm_mday); | ||
264 | else | 258 | else |
265 | t->time.tm_mon = -1; | 259 | t->time.tm_mday = -1; |
260 | |||
261 | if (cmos->mon_alrm) { | ||
262 | if (((unsigned)t->time.tm_mon) <= 0x12) | ||
263 | t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; | ||
264 | else | ||
265 | t->time.tm_mon = -1; | ||
266 | } | ||
266 | } | 267 | } |
267 | } | 268 | } |
268 | t->time.tm_year = -1; | 269 | t->time.tm_year = -1; |
@@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) | |||
322 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 323 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
323 | { | 324 | { |
324 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 325 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
325 | unsigned char mon, mday, hrs, min, sec; | 326 | unsigned char mon, mday, hrs, min, sec, rtc_control; |
326 | 327 | ||
327 | if (!is_valid_irq(cmos->irq)) | 328 | if (!is_valid_irq(cmos->irq)) |
328 | return -EIO; | 329 | return -EIO; |
329 | 330 | ||
330 | /* REVISIT this assumes PC style usage: always BCD */ | ||
331 | |||
332 | /* Writing 0xff means "don't care" or "match all". */ | ||
333 | |||
334 | mon = t->time.tm_mon + 1; | 331 | mon = t->time.tm_mon + 1; |
335 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; | ||
336 | |||
337 | mday = t->time.tm_mday; | 332 | mday = t->time.tm_mday; |
338 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; | ||
339 | |||
340 | hrs = t->time.tm_hour; | 333 | hrs = t->time.tm_hour; |
341 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; | ||
342 | |||
343 | min = t->time.tm_min; | 334 | min = t->time.tm_min; |
344 | min = (min < 60) ? bin2bcd(min) : 0xff; | ||
345 | |||
346 | sec = t->time.tm_sec; | 335 | sec = t->time.tm_sec; |
347 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; | 336 | |
337 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
338 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
339 | /* Writing 0xff means "don't care" or "match all". */ | ||
340 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; | ||
341 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; | ||
342 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; | ||
343 | min = (min < 60) ? bin2bcd(min) : 0xff; | ||
344 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; | ||
345 | } | ||
348 | 346 | ||
349 | spin_lock_irq(&rtc_lock); | 347 | spin_lock_irq(&rtc_lock); |
350 | 348 | ||
@@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) | |||
478 | "update_IRQ\t: %s\n" | 476 | "update_IRQ\t: %s\n" |
479 | "HPET_emulated\t: %s\n" | 477 | "HPET_emulated\t: %s\n" |
480 | // "square_wave\t: %s\n" | 478 | // "square_wave\t: %s\n" |
481 | // "BCD\t\t: %s\n" | 479 | "BCD\t\t: %s\n" |
482 | "DST_enable\t: %s\n" | 480 | "DST_enable\t: %s\n" |
483 | "periodic_freq\t: %d\n" | 481 | "periodic_freq\t: %d\n" |
484 | "batt_status\t: %s\n", | 482 | "batt_status\t: %s\n", |
@@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) | |||
486 | (rtc_control & RTC_UIE) ? "yes" : "no", | 484 | (rtc_control & RTC_UIE) ? "yes" : "no", |
487 | is_hpet_enabled() ? "yes" : "no", | 485 | is_hpet_enabled() ? "yes" : "no", |
488 | // (rtc_control & RTC_SQWE) ? "yes" : "no", | 486 | // (rtc_control & RTC_SQWE) ? "yes" : "no", |
489 | // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", | 487 | (rtc_control & RTC_DM_BINARY) ? "no" : "yes", |
490 | (rtc_control & RTC_DST_EN) ? "yes" : "no", | 488 | (rtc_control & RTC_DST_EN) ? "yes" : "no", |
491 | cmos->rtc->irq_freq, | 489 | cmos->rtc->irq_freq, |
492 | (valid & RTC_VRT) ? "okay" : "dead"); | 490 | (valid & RTC_VRT) ? "okay" : "dead"); |
@@ -519,7 +517,8 @@ static const struct rtc_class_ops cmos_rtc_ops = { | |||
519 | #define NVRAM_OFFSET (RTC_REG_D + 1) | 517 | #define NVRAM_OFFSET (RTC_REG_D + 1) |
520 | 518 | ||
521 | static ssize_t | 519 | static ssize_t |
522 | cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | 520 | cmos_nvram_read(struct file *filp, struct kobject *kobj, |
521 | struct bin_attribute *attr, | ||
523 | char *buf, loff_t off, size_t count) | 522 | char *buf, loff_t off, size_t count) |
524 | { | 523 | { |
525 | int retval; | 524 | int retval; |
@@ -547,7 +546,8 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
547 | } | 546 | } |
548 | 547 | ||
549 | static ssize_t | 548 | static ssize_t |
550 | cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | 549 | cmos_nvram_write(struct file *filp, struct kobject *kobj, |
550 | struct bin_attribute *attr, | ||
551 | char *buf, loff_t off, size_t count) | 551 | char *buf, loff_t off, size_t count) |
552 | { | 552 | { |
553 | struct cmos_rtc *cmos; | 553 | struct cmos_rtc *cmos; |
@@ -749,12 +749,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
749 | 749 | ||
750 | spin_unlock_irq(&rtc_lock); | 750 | spin_unlock_irq(&rtc_lock); |
751 | 751 | ||
752 | /* FIXME teach the alarm code how to handle binary mode; | 752 | /* FIXME: |
753 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. | 753 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. |
754 | */ | 754 | */ |
755 | if (is_valid_irq(rtc_irq) && | 755 | if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { |
756 | (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { | 756 | dev_warn(dev, "only 24-hr supported\n"); |
757 | dev_dbg(dev, "only 24-hr BCD mode supported\n"); | ||
758 | retval = -ENXIO; | 757 | retval = -ENXIO; |
759 | goto cleanup1; | 758 | goto cleanup1; |
760 | } | 759 | } |
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c new file mode 100644 index 000000000000..92a8f6cacda9 --- /dev/null +++ b/drivers/rtc/rtc-davinci.c | |||
@@ -0,0 +1,673 @@ | |||
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 <miguel.aguilar@ridgerun.com> | ||
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 | |||
33 | /* | ||
34 | * The DaVinci RTC is a simple RTC with the following | ||
35 | * Sec: 0 - 59 : BCD count | ||
36 | * Min: 0 - 59 : BCD count | ||
37 | * Hour: 0 - 23 : BCD count | ||
38 | * Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years ) | ||
39 | */ | ||
40 | |||
41 | /* PRTC interface registers */ | ||
42 | #define DAVINCI_PRTCIF_PID 0x00 | ||
43 | #define PRTCIF_CTLR 0x04 | ||
44 | #define PRTCIF_LDATA 0x08 | ||
45 | #define PRTCIF_UDATA 0x0C | ||
46 | #define PRTCIF_INTEN 0x10 | ||
47 | #define PRTCIF_INTFLG 0x14 | ||
48 | |||
49 | /* PRTCIF_CTLR bit fields */ | ||
50 | #define PRTCIF_CTLR_BUSY BIT(31) | ||
51 | #define PRTCIF_CTLR_SIZE BIT(25) | ||
52 | #define PRTCIF_CTLR_DIR BIT(24) | ||
53 | #define PRTCIF_CTLR_BENU_MSB BIT(23) | ||
54 | #define PRTCIF_CTLR_BENU_3RD_BYTE BIT(22) | ||
55 | #define PRTCIF_CTLR_BENU_2ND_BYTE BIT(21) | ||
56 | #define PRTCIF_CTLR_BENU_LSB BIT(20) | ||
57 | #define PRTCIF_CTLR_BENU_MASK (0x00F00000) | ||
58 | #define PRTCIF_CTLR_BENL_MSB BIT(19) | ||
59 | #define PRTCIF_CTLR_BENL_3RD_BYTE BIT(18) | ||
60 | #define PRTCIF_CTLR_BENL_2ND_BYTE BIT(17) | ||
61 | #define PRTCIF_CTLR_BENL_LSB BIT(16) | ||
62 | #define PRTCIF_CTLR_BENL_MASK (0x000F0000) | ||
63 | |||
64 | /* PRTCIF_INTEN bit fields */ | ||
65 | #define PRTCIF_INTEN_RTCSS BIT(1) | ||
66 | #define PRTCIF_INTEN_RTCIF BIT(0) | ||
67 | #define PRTCIF_INTEN_MASK (PRTCIF_INTEN_RTCSS \ | ||
68 | | PRTCIF_INTEN_RTCIF) | ||
69 | |||
70 | /* PRTCIF_INTFLG bit fields */ | ||
71 | #define PRTCIF_INTFLG_RTCSS BIT(1) | ||
72 | #define PRTCIF_INTFLG_RTCIF BIT(0) | ||
73 | #define PRTCIF_INTFLG_MASK (PRTCIF_INTFLG_RTCSS \ | ||
74 | | PRTCIF_INTFLG_RTCIF) | ||
75 | |||
76 | /* PRTC subsystem registers */ | ||
77 | #define PRTCSS_RTC_INTC_EXTENA1 (0x0C) | ||
78 | #define PRTCSS_RTC_CTRL (0x10) | ||
79 | #define PRTCSS_RTC_WDT (0x11) | ||
80 | #define PRTCSS_RTC_TMR0 (0x12) | ||
81 | #define PRTCSS_RTC_TMR1 (0x13) | ||
82 | #define PRTCSS_RTC_CCTRL (0x14) | ||
83 | #define PRTCSS_RTC_SEC (0x15) | ||
84 | #define PRTCSS_RTC_MIN (0x16) | ||
85 | #define PRTCSS_RTC_HOUR (0x17) | ||
86 | #define PRTCSS_RTC_DAY0 (0x18) | ||
87 | #define PRTCSS_RTC_DAY1 (0x19) | ||
88 | #define PRTCSS_RTC_AMIN (0x1A) | ||
89 | #define PRTCSS_RTC_AHOUR (0x1B) | ||
90 | #define PRTCSS_RTC_ADAY0 (0x1C) | ||
91 | #define PRTCSS_RTC_ADAY1 (0x1D) | ||
92 | #define PRTCSS_RTC_CLKC_CNT (0x20) | ||
93 | |||
94 | /* PRTCSS_RTC_INTC_EXTENA1 */ | ||
95 | #define PRTCSS_RTC_INTC_EXTENA1_MASK (0x07) | ||
96 | |||
97 | /* PRTCSS_RTC_CTRL bit fields */ | ||
98 | #define PRTCSS_RTC_CTRL_WDTBUS BIT(7) | ||
99 | #define PRTCSS_RTC_CTRL_WEN BIT(6) | ||
100 | #define PRTCSS_RTC_CTRL_WDRT BIT(5) | ||
101 | #define PRTCSS_RTC_CTRL_WDTFLG BIT(4) | ||
102 | #define PRTCSS_RTC_CTRL_TE BIT(3) | ||
103 | #define PRTCSS_RTC_CTRL_TIEN BIT(2) | ||
104 | #define PRTCSS_RTC_CTRL_TMRFLG BIT(1) | ||
105 | #define PRTCSS_RTC_CTRL_TMMD BIT(0) | ||
106 | |||
107 | /* PRTCSS_RTC_CCTRL bit fields */ | ||
108 | #define PRTCSS_RTC_CCTRL_CALBUSY BIT(7) | ||
109 | #define PRTCSS_RTC_CCTRL_DAEN BIT(5) | ||
110 | #define PRTCSS_RTC_CCTRL_HAEN BIT(4) | ||
111 | #define PRTCSS_RTC_CCTRL_MAEN BIT(3) | ||
112 | #define PRTCSS_RTC_CCTRL_ALMFLG BIT(2) | ||
113 | #define PRTCSS_RTC_CCTRL_AIEN BIT(1) | ||
114 | #define PRTCSS_RTC_CCTRL_CAEN BIT(0) | ||
115 | |||
116 | static DEFINE_SPINLOCK(davinci_rtc_lock); | ||
117 | |||
118 | struct davinci_rtc { | ||
119 | struct rtc_device *rtc; | ||
120 | void __iomem *base; | ||
121 | resource_size_t pbase; | ||
122 | size_t base_size; | ||
123 | int irq; | ||
124 | }; | ||
125 | |||
126 | static inline void rtcif_write(struct davinci_rtc *davinci_rtc, | ||
127 | u32 val, u32 addr) | ||
128 | { | ||
129 | writel(val, davinci_rtc->base + addr); | ||
130 | } | ||
131 | |||
132 | static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr) | ||
133 | { | ||
134 | return readl(davinci_rtc->base + addr); | ||
135 | } | ||
136 | |||
137 | static inline void rtcif_wait(struct davinci_rtc *davinci_rtc) | ||
138 | { | ||
139 | while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY) | ||
140 | cpu_relax(); | ||
141 | } | ||
142 | |||
143 | static inline void rtcss_write(struct davinci_rtc *davinci_rtc, | ||
144 | unsigned long val, u8 addr) | ||
145 | { | ||
146 | rtcif_wait(davinci_rtc); | ||
147 | |||
148 | rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR); | ||
149 | rtcif_write(davinci_rtc, val, PRTCIF_LDATA); | ||
150 | |||
151 | rtcif_wait(davinci_rtc); | ||
152 | } | ||
153 | |||
154 | static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr) | ||
155 | { | ||
156 | rtcif_wait(davinci_rtc); | ||
157 | |||
158 | rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr, | ||
159 | PRTCIF_CTLR); | ||
160 | |||
161 | rtcif_wait(davinci_rtc); | ||
162 | |||
163 | return rtcif_read(davinci_rtc, PRTCIF_LDATA); | ||
164 | } | ||
165 | |||
166 | static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc) | ||
167 | { | ||
168 | while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) & | ||
169 | PRTCSS_RTC_CCTRL_CALBUSY) | ||
170 | cpu_relax(); | ||
171 | } | ||
172 | |||
173 | static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev) | ||
174 | { | ||
175 | struct davinci_rtc *davinci_rtc = class_dev; | ||
176 | unsigned long events = 0; | ||
177 | u32 irq_flg; | ||
178 | u8 alm_irq, tmr_irq; | ||
179 | u8 rtc_ctrl, rtc_cctrl; | ||
180 | int ret = IRQ_NONE; | ||
181 | |||
182 | irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) & | ||
183 | PRTCIF_INTFLG_RTCSS; | ||
184 | |||
185 | alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) & | ||
186 | PRTCSS_RTC_CCTRL_ALMFLG; | ||
187 | |||
188 | tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) & | ||
189 | PRTCSS_RTC_CTRL_TMRFLG; | ||
190 | |||
191 | if (irq_flg) { | ||
192 | if (alm_irq) { | ||
193 | events |= RTC_IRQF | RTC_AF; | ||
194 | rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL); | ||
195 | rtc_cctrl |= PRTCSS_RTC_CCTRL_ALMFLG; | ||
196 | rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL); | ||
197 | } else if (tmr_irq) { | ||
198 | events |= RTC_IRQF | RTC_PF; | ||
199 | rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); | ||
200 | rtc_ctrl |= PRTCSS_RTC_CTRL_TMRFLG; | ||
201 | rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); | ||
202 | } | ||
203 | |||
204 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, | ||
205 | PRTCIF_INTFLG); | ||
206 | rtc_update_irq(davinci_rtc->rtc, 1, events); | ||
207 | |||
208 | ret = IRQ_HANDLED; | ||
209 | } | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | static int | ||
215 | davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
216 | { | ||
217 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
218 | u8 rtc_ctrl; | ||
219 | unsigned long flags; | ||
220 | int ret = 0; | ||
221 | |||
222 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
223 | |||
224 | rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); | ||
225 | |||
226 | switch (cmd) { | ||
227 | case RTC_WIE_ON: | ||
228 | rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG; | ||
229 | break; | ||
230 | case RTC_WIE_OFF: | ||
231 | rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN; | ||
232 | break; | ||
233 | case RTC_UIE_OFF: | ||
234 | case RTC_UIE_ON: | ||
235 | ret = -ENOTTY; | ||
236 | break; | ||
237 | default: | ||
238 | ret = -ENOIOCTLCMD; | ||
239 | } | ||
240 | |||
241 | rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); | ||
242 | |||
243 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
244 | |||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | static int convertfromdays(u16 days, struct rtc_time *tm) | ||
249 | { | ||
250 | int tmp_days, year, mon; | ||
251 | |||
252 | for (year = 2000;; year++) { | ||
253 | tmp_days = rtc_year_days(1, 12, year); | ||
254 | if (days >= tmp_days) | ||
255 | days -= tmp_days; | ||
256 | else { | ||
257 | for (mon = 0;; mon++) { | ||
258 | tmp_days = rtc_month_days(mon, year); | ||
259 | if (days >= tmp_days) { | ||
260 | days -= tmp_days; | ||
261 | } else { | ||
262 | tm->tm_year = year - 1900; | ||
263 | tm->tm_mon = mon; | ||
264 | tm->tm_mday = days + 1; | ||
265 | break; | ||
266 | } | ||
267 | } | ||
268 | break; | ||
269 | } | ||
270 | } | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int convert2days(u16 *days, struct rtc_time *tm) | ||
275 | { | ||
276 | int i; | ||
277 | *days = 0; | ||
278 | |||
279 | /* epoch == 1900 */ | ||
280 | if (tm->tm_year < 100 || tm->tm_year > 199) | ||
281 | return -EINVAL; | ||
282 | |||
283 | for (i = 2000; i < 1900 + tm->tm_year; i++) | ||
284 | *days += rtc_year_days(1, 12, i); | ||
285 | |||
286 | *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
292 | { | ||
293 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
294 | u16 days = 0; | ||
295 | u8 day0, day1; | ||
296 | unsigned long flags; | ||
297 | |||
298 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
299 | |||
300 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
301 | tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC)); | ||
302 | |||
303 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
304 | tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN)); | ||
305 | |||
306 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
307 | tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR)); | ||
308 | |||
309 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
310 | day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0); | ||
311 | |||
312 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
313 | day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1); | ||
314 | |||
315 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
316 | |||
317 | days |= day1; | ||
318 | days <<= 8; | ||
319 | days |= day0; | ||
320 | |||
321 | if (convertfromdays(days, tm) < 0) | ||
322 | return -EINVAL; | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
328 | { | ||
329 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
330 | u16 days; | ||
331 | u8 rtc_cctrl; | ||
332 | unsigned long flags; | ||
333 | |||
334 | if (convert2days(&days, tm) < 0) | ||
335 | return -EINVAL; | ||
336 | |||
337 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
338 | |||
339 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
340 | rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC); | ||
341 | |||
342 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
343 | rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN); | ||
344 | |||
345 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
346 | rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR); | ||
347 | |||
348 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
349 | rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0); | ||
350 | |||
351 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
352 | rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1); | ||
353 | |||
354 | rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL); | ||
355 | rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN; | ||
356 | rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL); | ||
357 | |||
358 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static int davinci_rtc_alarm_irq_enable(struct device *dev, | ||
364 | unsigned int enabled) | ||
365 | { | ||
366 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
367 | unsigned long flags; | ||
368 | u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL); | ||
369 | |||
370 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
371 | |||
372 | if (enabled) | ||
373 | rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN | | ||
374 | PRTCSS_RTC_CCTRL_HAEN | | ||
375 | PRTCSS_RTC_CCTRL_MAEN | | ||
376 | PRTCSS_RTC_CCTRL_ALMFLG | | ||
377 | PRTCSS_RTC_CCTRL_AIEN; | ||
378 | else | ||
379 | rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN; | ||
380 | |||
381 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
382 | rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL); | ||
383 | |||
384 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
390 | { | ||
391 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
392 | u16 days = 0; | ||
393 | u8 day0, day1; | ||
394 | unsigned long flags; | ||
395 | |||
396 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
397 | |||
398 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
399 | alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN)); | ||
400 | |||
401 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
402 | alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR)); | ||
403 | |||
404 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
405 | day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0); | ||
406 | |||
407 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
408 | day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1); | ||
409 | |||
410 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
411 | days |= day1; | ||
412 | days <<= 8; | ||
413 | days |= day0; | ||
414 | |||
415 | if (convertfromdays(days, &alm->time) < 0) | ||
416 | return -EINVAL; | ||
417 | |||
418 | alm->pending = !!(rtcss_read(davinci_rtc, | ||
419 | PRTCSS_RTC_CCTRL) & | ||
420 | PRTCSS_RTC_CCTRL_AIEN); | ||
421 | alm->enabled = alm->pending && device_may_wakeup(dev); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
427 | { | ||
428 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
429 | unsigned long flags; | ||
430 | u16 days; | ||
431 | |||
432 | if (alm->time.tm_mday <= 0 && alm->time.tm_mon < 0 | ||
433 | && alm->time.tm_year < 0) { | ||
434 | struct rtc_time tm; | ||
435 | unsigned long now, then; | ||
436 | |||
437 | davinci_rtc_read_time(dev, &tm); | ||
438 | rtc_tm_to_time(&tm, &now); | ||
439 | |||
440 | alm->time.tm_mday = tm.tm_mday; | ||
441 | alm->time.tm_mon = tm.tm_mon; | ||
442 | alm->time.tm_year = tm.tm_year; | ||
443 | rtc_tm_to_time(&alm->time, &then); | ||
444 | |||
445 | if (then < now) { | ||
446 | rtc_time_to_tm(now + 24 * 60 * 60, &tm); | ||
447 | alm->time.tm_mday = tm.tm_mday; | ||
448 | alm->time.tm_mon = tm.tm_mon; | ||
449 | alm->time.tm_year = tm.tm_year; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | if (convert2days(&days, &alm->time) < 0) | ||
454 | return -EINVAL; | ||
455 | |||
456 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
457 | |||
458 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
459 | rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN); | ||
460 | |||
461 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
462 | rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR); | ||
463 | |||
464 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
465 | rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0); | ||
466 | |||
467 | davinci_rtcss_calendar_wait(davinci_rtc); | ||
468 | rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1); | ||
469 | |||
470 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static int davinci_rtc_irq_set_state(struct device *dev, int enabled) | ||
476 | { | ||
477 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
478 | unsigned long flags; | ||
479 | u8 rtc_ctrl; | ||
480 | |||
481 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
482 | |||
483 | rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); | ||
484 | |||
485 | if (enabled) { | ||
486 | while (rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) | ||
487 | & PRTCSS_RTC_CTRL_WDTBUS) | ||
488 | cpu_relax(); | ||
489 | |||
490 | rtc_ctrl |= PRTCSS_RTC_CTRL_TE; | ||
491 | rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); | ||
492 | |||
493 | rtcss_write(davinci_rtc, 0x0, PRTCSS_RTC_CLKC_CNT); | ||
494 | |||
495 | rtc_ctrl |= PRTCSS_RTC_CTRL_TIEN | | ||
496 | PRTCSS_RTC_CTRL_TMMD | | ||
497 | PRTCSS_RTC_CTRL_TMRFLG; | ||
498 | } else | ||
499 | rtc_ctrl &= ~PRTCSS_RTC_CTRL_TIEN; | ||
500 | |||
501 | rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); | ||
502 | |||
503 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int davinci_rtc_irq_set_freq(struct device *dev, int freq) | ||
509 | { | ||
510 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
511 | unsigned long flags; | ||
512 | u16 tmr_counter = (0x8000 >> (ffs(freq) - 1)); | ||
513 | |||
514 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
515 | |||
516 | rtcss_write(davinci_rtc, tmr_counter & 0xFF, PRTCSS_RTC_TMR0); | ||
517 | rtcss_write(davinci_rtc, (tmr_counter & 0xFF00) >> 8, PRTCSS_RTC_TMR1); | ||
518 | |||
519 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
520 | |||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | static struct rtc_class_ops davinci_rtc_ops = { | ||
525 | .ioctl = davinci_rtc_ioctl, | ||
526 | .read_time = davinci_rtc_read_time, | ||
527 | .set_time = davinci_rtc_set_time, | ||
528 | .alarm_irq_enable = davinci_rtc_alarm_irq_enable, | ||
529 | .read_alarm = davinci_rtc_read_alarm, | ||
530 | .set_alarm = davinci_rtc_set_alarm, | ||
531 | .irq_set_state = davinci_rtc_irq_set_state, | ||
532 | .irq_set_freq = davinci_rtc_irq_set_freq, | ||
533 | }; | ||
534 | |||
535 | static int __init davinci_rtc_probe(struct platform_device *pdev) | ||
536 | { | ||
537 | struct device *dev = &pdev->dev; | ||
538 | struct davinci_rtc *davinci_rtc; | ||
539 | struct resource *res, *mem; | ||
540 | int ret = 0; | ||
541 | |||
542 | davinci_rtc = kzalloc(sizeof(struct davinci_rtc), GFP_KERNEL); | ||
543 | if (!davinci_rtc) { | ||
544 | dev_dbg(dev, "could not allocate memory for private data\n"); | ||
545 | return -ENOMEM; | ||
546 | } | ||
547 | |||
548 | davinci_rtc->irq = platform_get_irq(pdev, 0); | ||
549 | if (davinci_rtc->irq < 0) { | ||
550 | dev_err(dev, "no RTC irq\n"); | ||
551 | ret = davinci_rtc->irq; | ||
552 | goto fail1; | ||
553 | } | ||
554 | |||
555 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
556 | if (!res) { | ||
557 | dev_err(dev, "no mem resource\n"); | ||
558 | ret = -EINVAL; | ||
559 | goto fail1; | ||
560 | } | ||
561 | |||
562 | davinci_rtc->pbase = res->start; | ||
563 | davinci_rtc->base_size = resource_size(res); | ||
564 | |||
565 | mem = request_mem_region(davinci_rtc->pbase, davinci_rtc->base_size, | ||
566 | pdev->name); | ||
567 | if (!mem) { | ||
568 | dev_err(dev, "RTC registers at %08x are not free\n", | ||
569 | davinci_rtc->pbase); | ||
570 | ret = -EBUSY; | ||
571 | goto fail1; | ||
572 | } | ||
573 | |||
574 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); | ||
575 | if (!davinci_rtc->base) { | ||
576 | dev_err(dev, "unable to ioremap MEM resource\n"); | ||
577 | ret = -ENOMEM; | ||
578 | goto fail2; | ||
579 | } | ||
580 | |||
581 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
582 | &davinci_rtc_ops, THIS_MODULE); | ||
583 | if (IS_ERR(davinci_rtc->rtc)) { | ||
584 | dev_err(dev, "unable to register RTC device, err %ld\n", | ||
585 | PTR_ERR(davinci_rtc->rtc)); | ||
586 | goto fail3; | ||
587 | } | ||
588 | |||
589 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); | ||
590 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); | ||
591 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1); | ||
592 | |||
593 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL); | ||
594 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); | ||
595 | |||
596 | ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt, | ||
597 | IRQF_DISABLED, "davinci_rtc", davinci_rtc); | ||
598 | if (ret < 0) { | ||
599 | dev_err(dev, "unable to register davinci RTC interrupt\n"); | ||
600 | goto fail4; | ||
601 | } | ||
602 | |||
603 | /* Enable interrupts */ | ||
604 | rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN); | ||
605 | rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK, | ||
606 | PRTCSS_RTC_INTC_EXTENA1); | ||
607 | |||
608 | rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL); | ||
609 | |||
610 | platform_set_drvdata(pdev, davinci_rtc); | ||
611 | |||
612 | device_init_wakeup(&pdev->dev, 0); | ||
613 | |||
614 | return 0; | ||
615 | |||
616 | fail4: | ||
617 | rtc_device_unregister(davinci_rtc->rtc); | ||
618 | fail3: | ||
619 | iounmap(davinci_rtc->base); | ||
620 | fail2: | ||
621 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | ||
622 | fail1: | ||
623 | kfree(davinci_rtc); | ||
624 | |||
625 | return ret; | ||
626 | } | ||
627 | |||
628 | static int __devexit davinci_rtc_remove(struct platform_device *pdev) | ||
629 | { | ||
630 | struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev); | ||
631 | |||
632 | device_init_wakeup(&pdev->dev, 0); | ||
633 | |||
634 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); | ||
635 | |||
636 | free_irq(davinci_rtc->irq, davinci_rtc); | ||
637 | |||
638 | rtc_device_unregister(davinci_rtc->rtc); | ||
639 | |||
640 | iounmap(davinci_rtc->base); | ||
641 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | ||
642 | |||
643 | platform_set_drvdata(pdev, NULL); | ||
644 | |||
645 | kfree(davinci_rtc); | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static struct platform_driver davinci_rtc_driver = { | ||
651 | .probe = davinci_rtc_probe, | ||
652 | .remove = __devexit_p(davinci_rtc_remove), | ||
653 | .driver = { | ||
654 | .name = "rtc_davinci", | ||
655 | .owner = THIS_MODULE, | ||
656 | }, | ||
657 | }; | ||
658 | |||
659 | static int __init rtc_init(void) | ||
660 | { | ||
661 | return platform_driver_probe(&davinci_rtc_driver, davinci_rtc_probe); | ||
662 | } | ||
663 | module_init(rtc_init); | ||
664 | |||
665 | static void __exit rtc_exit(void) | ||
666 | { | ||
667 | platform_driver_unregister(&davinci_rtc_driver); | ||
668 | } | ||
669 | module_exit(rtc_exit); | ||
670 | |||
671 | MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>"); | ||
672 | MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver"); | ||
673 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 7836c9cec557..48da85e97ca4 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -542,7 +542,8 @@ static void msg_init(struct spi_message *m, struct spi_transfer *x, | |||
542 | } | 542 | } |
543 | 543 | ||
544 | static ssize_t | 544 | static ssize_t |
545 | ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | 545 | ds1305_nvram_read(struct file *filp, struct kobject *kobj, |
546 | struct bin_attribute *attr, | ||
546 | char *buf, loff_t off, size_t count) | 547 | char *buf, loff_t off, size_t count) |
547 | { | 548 | { |
548 | struct spi_device *spi; | 549 | struct spi_device *spi; |
@@ -572,7 +573,8 @@ ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
572 | } | 573 | } |
573 | 574 | ||
574 | static ssize_t | 575 | static ssize_t |
575 | ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | 576 | ds1305_nvram_write(struct file *filp, struct kobject *kobj, |
577 | struct bin_attribute *attr, | ||
576 | char *buf, loff_t off, size_t count) | 578 | char *buf, loff_t off, size_t count) |
577 | { | 579 | { |
578 | struct spi_device *spi; | 580 | struct spi_device *spi; |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index c4ec5c158aa1..de033b7ac21f 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -556,7 +556,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { | |||
556 | #define NVRAM_SIZE 56 | 556 | #define NVRAM_SIZE 56 |
557 | 557 | ||
558 | static ssize_t | 558 | static ssize_t |
559 | ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | 559 | ds1307_nvram_read(struct file *filp, struct kobject *kobj, |
560 | struct bin_attribute *attr, | ||
560 | char *buf, loff_t off, size_t count) | 561 | char *buf, loff_t off, size_t count) |
561 | { | 562 | { |
562 | struct i2c_client *client; | 563 | struct i2c_client *client; |
@@ -580,7 +581,8 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
580 | } | 581 | } |
581 | 582 | ||
582 | static ssize_t | 583 | static ssize_t |
583 | ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | 584 | ds1307_nvram_write(struct file *filp, struct kobject *kobj, |
585 | struct bin_attribute *attr, | ||
584 | char *buf, loff_t off, size_t count) | 586 | char *buf, loff_t off, size_t count) |
585 | { | 587 | { |
586 | struct i2c_client *client; | 588 | struct i2c_client *client; |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 06b8566c4532..37268e97de49 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -423,8 +423,9 @@ static const struct rtc_class_ops ds1511_rtc_ops = { | |||
423 | }; | 423 | }; |
424 | 424 | ||
425 | static ssize_t | 425 | static ssize_t |
426 | ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, | 426 | ds1511_nvram_read(struct file *filp, struct kobject *kobj, |
427 | char *buf, loff_t pos, size_t size) | 427 | struct bin_attribute *ba, |
428 | char *buf, loff_t pos, size_t size) | ||
428 | { | 429 | { |
429 | ssize_t count; | 430 | ssize_t count; |
430 | 431 | ||
@@ -452,8 +453,9 @@ ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, | |||
452 | } | 453 | } |
453 | 454 | ||
454 | static ssize_t | 455 | static ssize_t |
455 | ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, | 456 | ds1511_nvram_write(struct file *filp, struct kobject *kobj, |
456 | char *buf, loff_t pos, size_t size) | 457 | struct bin_attribute *bin_attr, |
458 | char *buf, loff_t pos, size_t size) | ||
457 | { | 459 | { |
458 | ssize_t count; | 460 | ssize_t count; |
459 | 461 | ||
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 244f9994bcbb..ff432e2ca275 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -252,7 +252,7 @@ static const struct rtc_class_ops ds1553_rtc_ops = { | |||
252 | .update_irq_enable = ds1553_rtc_update_irq_enable, | 252 | .update_irq_enable = ds1553_rtc_update_irq_enable, |
253 | }; | 253 | }; |
254 | 254 | ||
255 | static ssize_t ds1553_nvram_read(struct kobject *kobj, | 255 | static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, |
256 | struct bin_attribute *bin_attr, | 256 | struct bin_attribute *bin_attr, |
257 | char *buf, loff_t pos, size_t size) | 257 | char *buf, loff_t pos, size_t size) |
258 | { | 258 | { |
@@ -267,7 +267,7 @@ static ssize_t ds1553_nvram_read(struct kobject *kobj, | |||
267 | return count; | 267 | return count; |
268 | } | 268 | } |
269 | 269 | ||
270 | static ssize_t ds1553_nvram_write(struct kobject *kobj, | 270 | static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj, |
271 | struct bin_attribute *bin_attr, | 271 | struct bin_attribute *bin_attr, |
272 | char *buf, loff_t pos, size_t size) | 272 | char *buf, loff_t pos, size_t size) |
273 | { | 273 | { |
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 2b4b0bc42d6f..042630c90dd3 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -128,7 +128,7 @@ static const struct rtc_class_ops ds1742_rtc_ops = { | |||
128 | .set_time = ds1742_rtc_set_time, | 128 | .set_time = ds1742_rtc_set_time, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static ssize_t ds1742_nvram_read(struct kobject *kobj, | 131 | static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, |
132 | struct bin_attribute *bin_attr, | 132 | struct bin_attribute *bin_attr, |
133 | char *buf, loff_t pos, size_t size) | 133 | char *buf, loff_t pos, size_t size) |
134 | { | 134 | { |
@@ -143,7 +143,7 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, | |||
143 | return count; | 143 | return count; |
144 | } | 144 | } |
145 | 145 | ||
146 | static ssize_t ds1742_nvram_write(struct kobject *kobj, | 146 | static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, |
147 | struct bin_attribute *bin_attr, | 147 | struct bin_attribute *bin_attr, |
148 | char *buf, loff_t pos, size_t size) | 148 | char *buf, loff_t pos, size_t size) |
149 | { | 149 | { |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 60fe266f0f49..038095d99976 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -623,7 +623,7 @@ static ssize_t wdt_read(struct file *file, char __user *buf, | |||
623 | * according to their available features. We only actually usefully support | 623 | * according to their available features. We only actually usefully support |
624 | * querying capabilities and current status. | 624 | * querying capabilities and current status. |
625 | */ | 625 | */ |
626 | static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 626 | static int wdt_ioctl(struct file *file, unsigned int cmd, |
627 | unsigned long arg) | 627 | unsigned long arg) |
628 | { | 628 | { |
629 | int new_margin, rv; | 629 | int new_margin, rv; |
@@ -676,6 +676,18 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
676 | return -ENOTTY; | 676 | return -ENOTTY; |
677 | } | 677 | } |
678 | 678 | ||
679 | static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, | ||
680 | unsigned long arg) | ||
681 | { | ||
682 | int ret; | ||
683 | |||
684 | lock_kernel(); | ||
685 | ret = wdt_ioctl(file, cmd, arg); | ||
686 | unlock_kernel(); | ||
687 | |||
688 | return ret; | ||
689 | } | ||
690 | |||
679 | /** | 691 | /** |
680 | * wdt_open: | 692 | * wdt_open: |
681 | * @inode: inode of device | 693 | * @inode: inode of device |
@@ -736,7 +748,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
736 | static const struct file_operations wdt_fops = { | 748 | static const struct file_operations wdt_fops = { |
737 | .owner = THIS_MODULE, | 749 | .owner = THIS_MODULE, |
738 | .read = wdt_read, | 750 | .read = wdt_read, |
739 | .ioctl = wdt_ioctl, | 751 | .unlocked_ioctl = wdt_unlocked_ioctl, |
740 | .write = wdt_write, | 752 | .write = wdt_write, |
741 | .open = wdt_open, | 753 | .open = wdt_open, |
742 | .release = wdt_release, | 754 | .release = wdt_release, |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 365ff3ac2348..be8359fdb65a 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -343,7 +343,7 @@ static const struct rtc_class_ops m48t02_rtc_ops = { | |||
343 | .set_time = m48t59_rtc_set_time, | 343 | .set_time = m48t59_rtc_set_time, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | static ssize_t m48t59_nvram_read(struct kobject *kobj, | 346 | static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, |
347 | struct bin_attribute *bin_attr, | 347 | struct bin_attribute *bin_attr, |
348 | char *buf, loff_t pos, size_t size) | 348 | char *buf, loff_t pos, size_t size) |
349 | { | 349 | { |
@@ -363,7 +363,7 @@ static ssize_t m48t59_nvram_read(struct kobject *kobj, | |||
363 | return cnt; | 363 | return cnt; |
364 | } | 364 | } |
365 | 365 | ||
366 | static ssize_t m48t59_nvram_write(struct kobject *kobj, | 366 | static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, |
367 | struct bin_attribute *bin_attr, | 367 | struct bin_attribute *bin_attr, |
368 | char *buf, loff_t pos, size_t size) | 368 | char *buf, loff_t pos, size_t size) |
369 | { | 369 | { |
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index c9522f3bc21c..9718aaaa8215 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * An I2C driver for the Epson RX8581 RTC | 2 | * An I2C driver for the Epson RX8581 RTC |
3 | * | 3 | * |
4 | * Author: Martyn Welch <martyn.welch@gefanuc.com> | 4 | * Author: Martyn Welch <martyn.welch@ge.com> |
5 | * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. | 5 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -272,7 +272,7 @@ static void __exit rx8581_exit(void) | |||
272 | i2c_del_driver(&rx8581_driver); | 272 | i2c_del_driver(&rx8581_driver); |
273 | } | 273 | } |
274 | 274 | ||
275 | MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); | 275 | MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>"); |
276 | MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); | 276 | MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); |
277 | MODULE_LICENSE("GPL"); | 277 | MODULE_LICENSE("GPL"); |
278 | MODULE_VERSION(DRV_VERSION); | 278 | MODULE_VERSION(DRV_VERSION); |
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 875ba099e7a5..3b943673cd3e 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * A RTC driver for the Simtek STK17TA8 | 2 | * A RTC driver for the Simtek STK17TA8 |
3 | * | 3 | * |
4 | * By Thomas Hommel <thomas.hommel@gefanuc.com> | 4 | * By Thomas Hommel <thomas.hommel@ge.com> |
5 | * | 5 | * |
6 | * Based on the DS1553 driver from | 6 | * Based on the DS1553 driver from |
7 | * Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 7 | * Atsushi Nemoto <anemo@mba.ocn.ne.jp> |
@@ -244,7 +244,7 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = { | |||
244 | .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable, | 244 | .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable, |
245 | }; | 245 | }; |
246 | 246 | ||
247 | static ssize_t stk17ta8_nvram_read(struct kobject *kobj, | 247 | static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj, |
248 | struct bin_attribute *attr, char *buf, | 248 | struct bin_attribute *attr, char *buf, |
249 | loff_t pos, size_t size) | 249 | loff_t pos, size_t size) |
250 | { | 250 | { |
@@ -259,7 +259,7 @@ static ssize_t stk17ta8_nvram_read(struct kobject *kobj, | |||
259 | return count; | 259 | return count; |
260 | } | 260 | } |
261 | 261 | ||
262 | static ssize_t stk17ta8_nvram_write(struct kobject *kobj, | 262 | static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj, |
263 | struct bin_attribute *attr, char *buf, | 263 | struct bin_attribute *attr, char *buf, |
264 | loff_t pos, size_t size) | 264 | loff_t pos, size_t size) |
265 | { | 265 | { |
@@ -382,7 +382,7 @@ static __exit void stk17ta8_exit(void) | |||
382 | module_init(stk17ta8_init); | 382 | module_init(stk17ta8_init); |
383 | module_exit(stk17ta8_exit); | 383 | module_exit(stk17ta8_exit); |
384 | 384 | ||
385 | MODULE_AUTHOR("Thomas Hommel <thomas.hommel@gefanuc.com>"); | 385 | MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>"); |
386 | MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver"); | 386 | MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver"); |
387 | MODULE_LICENSE("GPL"); | 387 | MODULE_LICENSE("GPL"); |
388 | MODULE_VERSION(DRV_VERSION); | 388 | MODULE_VERSION(DRV_VERSION); |
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 20bfc64a15c8..ec6313d15359 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c | |||
@@ -188,7 +188,7 @@ static const struct rtc_class_ops tx4939_rtc_ops = { | |||
188 | .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, | 188 | .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, |
189 | }; | 189 | }; |
190 | 190 | ||
191 | static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, | 191 | static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, |
192 | struct bin_attribute *bin_attr, | 192 | struct bin_attribute *bin_attr, |
193 | char *buf, loff_t pos, size_t size) | 193 | char *buf, loff_t pos, size_t size) |
194 | { | 194 | { |
@@ -207,7 +207,7 @@ static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, | |||
207 | return count; | 207 | return count; |
208 | } | 208 | } |
209 | 209 | ||
210 | static ssize_t tx4939_rtc_nvram_write(struct kobject *kobj, | 210 | static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, |
211 | struct bin_attribute *bin_attr, | 211 | struct bin_attribute *bin_attr, |
212 | char *buf, loff_t pos, size_t size) | 212 | char *buf, loff_t pos, size_t size) |
213 | { | 213 | { |