diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 31 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-at91rm9200.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-at91rm9200.h | 75 | ||||
-rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-da9055.c | 413 | ||||
-rw-r--r-- | drivers/rtc/rtc-davinci.c | 21 | ||||
-rw-r--r-- | drivers/rtc/rtc-dev.c | 19 | ||||
-rw-r--r-- | drivers/rtc/rtc-imxdi.c | 11 | ||||
-rw-r--r-- | drivers/rtc/rtc-isl1208.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-mxc.c | 34 | ||||
-rw-r--r-- | drivers/rtc/rtc-omap.c | 80 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8523.c | 326 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 54 | ||||
-rw-r--r-- | drivers/rtc/rtc-spear.c | 91 | ||||
-rw-r--r-- | drivers/rtc/rtc-test.c | 14 | ||||
-rw-r--r-- | drivers/rtc/rtc-tps65910.c | 9 | ||||
-rw-r--r-- | drivers/rtc/rtc-twl.c | 32 | ||||
-rw-r--r-- | drivers/rtc/rtc-vt8500.c | 15 |
19 files changed, 1048 insertions, 185 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 19c03ab2bdcb..d0cea02b5dfc 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -269,6 +269,15 @@ config RTC_DRV_X1205 | |||
269 | This driver can also be built as a module. If so, the module | 269 | This driver can also be built as a module. If so, the module |
270 | will be called rtc-x1205. | 270 | will be called rtc-x1205. |
271 | 271 | ||
272 | config RTC_DRV_PCF8523 | ||
273 | tristate "NXP PCF8523" | ||
274 | help | ||
275 | If you say yes here you get support for the NXP PCF8523 RTC | ||
276 | chips. | ||
277 | |||
278 | This driver can also be built as a module. If so, the module | ||
279 | will be called rtc-pcf8523. | ||
280 | |||
272 | config RTC_DRV_PCF8563 | 281 | config RTC_DRV_PCF8563 |
273 | tristate "Philips PCF8563/Epson RTC8564" | 282 | tristate "Philips PCF8563/Epson RTC8564" |
274 | help | 283 | help |
@@ -600,6 +609,16 @@ config RTC_DRV_DA9052 | |||
600 | Say y here to support the RTC driver for Dialog Semiconductor | 609 | Say y here to support the RTC driver for Dialog Semiconductor |
601 | DA9052-BC and DA9053-AA/Bx PMICs. | 610 | DA9052-BC and DA9053-AA/Bx PMICs. |
602 | 611 | ||
612 | config RTC_DRV_DA9055 | ||
613 | tristate "Dialog Semiconductor DA9055 RTC" | ||
614 | depends on MFD_DA9055 | ||
615 | help | ||
616 | If you say yes here you will get support for the | ||
617 | RTC of the Dialog DA9055 PMIC. | ||
618 | |||
619 | This driver can also be built as a module. If so, the module | ||
620 | will be called rtc-da9055 | ||
621 | |||
603 | config RTC_DRV_EFI | 622 | config RTC_DRV_EFI |
604 | tristate "EFI RTC" | 623 | tristate "EFI RTC" |
605 | depends on IA64 | 624 | depends on IA64 |
@@ -768,7 +787,7 @@ config RTC_DRV_DAVINCI | |||
768 | 787 | ||
769 | config RTC_DRV_IMXDI | 788 | config RTC_DRV_IMXDI |
770 | tristate "Freescale IMX DryIce Real Time Clock" | 789 | tristate "Freescale IMX DryIce Real Time Clock" |
771 | depends on SOC_IMX25 | 790 | depends on ARCH_MXC |
772 | help | 791 | help |
773 | Support for Freescale IMX DryIce RTC | 792 | Support for Freescale IMX DryIce RTC |
774 | 793 | ||
@@ -777,11 +796,13 @@ config RTC_DRV_IMXDI | |||
777 | 796 | ||
778 | config RTC_DRV_OMAP | 797 | config RTC_DRV_OMAP |
779 | tristate "TI OMAP1" | 798 | tristate "TI OMAP1" |
780 | depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX | 799 | depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX |
781 | help | 800 | help |
782 | Say "yes" here to support the real time clock on TI OMAP1 and | 801 | Say "yes" here to support the on chip real time clock |
783 | DA8xx/OMAP-L13x chips. This driver can also be built as a | 802 | present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x. |
784 | module called rtc-omap. | 803 | |
804 | This driver can also be built as a module, if so, module | ||
805 | will be called rtc-omap. | ||
785 | 806 | ||
786 | config HAVE_S3C_RTC | 807 | config HAVE_S3C_RTC |
787 | bool | 808 | bool |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 56297f0fd388..c3f62c80dc06 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o | |||
29 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 29 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
30 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o | 30 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o |
31 | obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o | 31 | obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o |
32 | obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o | ||
32 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o | 33 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o |
33 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o | 34 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o |
34 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o | 35 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o |
@@ -76,6 +77,7 @@ obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | |||
76 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o | 77 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o |
77 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 78 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o |
78 | obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o | 79 | obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o |
80 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o | ||
79 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 81 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
80 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 82 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
81 | obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o | 83 | obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index fca9790c7de7..b6469e2cae89 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | 33 | ||
34 | #include <mach/at91_rtc.h> | 34 | #include "rtc-at91rm9200.h" |
35 | 35 | ||
36 | #define at91_rtc_read(field) \ | 36 | #define at91_rtc_read(field) \ |
37 | __raw_readl(at91_rtc_regs + field) | 37 | __raw_readl(at91_rtc_regs + field) |
diff --git a/drivers/rtc/rtc-at91rm9200.h b/drivers/rtc/rtc-at91rm9200.h new file mode 100644 index 000000000000..da1945e5f714 --- /dev/null +++ b/drivers/rtc/rtc-at91rm9200.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/include/mach/at91_rtc.h | ||
3 | * | ||
4 | * Copyright (C) 2005 Ivan Kokshaysky | ||
5 | * Copyright (C) SAN People | ||
6 | * | ||
7 | * Real Time Clock (RTC) - System peripheral registers. | ||
8 | * Based on AT91RM9200 datasheet revision E. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifndef AT91_RTC_H | ||
17 | #define AT91_RTC_H | ||
18 | |||
19 | #define AT91_RTC_CR 0x00 /* Control Register */ | ||
20 | #define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ | ||
21 | #define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ | ||
22 | #define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ | ||
23 | #define AT91_RTC_TIMEVSEL_MINUTE (0 << 8) | ||
24 | #define AT91_RTC_TIMEVSEL_HOUR (1 << 8) | ||
25 | #define AT91_RTC_TIMEVSEL_DAY24 (2 << 8) | ||
26 | #define AT91_RTC_TIMEVSEL_DAY12 (3 << 8) | ||
27 | #define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */ | ||
28 | #define AT91_RTC_CALEVSEL_WEEK (0 << 16) | ||
29 | #define AT91_RTC_CALEVSEL_MONTH (1 << 16) | ||
30 | #define AT91_RTC_CALEVSEL_YEAR (2 << 16) | ||
31 | |||
32 | #define AT91_RTC_MR 0x04 /* Mode Register */ | ||
33 | #define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ | ||
34 | |||
35 | #define AT91_RTC_TIMR 0x08 /* Time Register */ | ||
36 | #define AT91_RTC_SEC (0x7f << 0) /* Current Second */ | ||
37 | #define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ | ||
38 | #define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ | ||
39 | #define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ | ||
40 | |||
41 | #define AT91_RTC_CALR 0x0c /* Calendar Register */ | ||
42 | #define AT91_RTC_CENT (0x7f << 0) /* Current Century */ | ||
43 | #define AT91_RTC_YEAR (0xff << 8) /* Current Year */ | ||
44 | #define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ | ||
45 | #define AT91_RTC_DAY (7 << 21) /* Current Day */ | ||
46 | #define AT91_RTC_DATE (0x3f << 24) /* Current Date */ | ||
47 | |||
48 | #define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */ | ||
49 | #define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ | ||
50 | #define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ | ||
51 | #define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ | ||
52 | |||
53 | #define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */ | ||
54 | #define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ | ||
55 | #define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ | ||
56 | |||
57 | #define AT91_RTC_SR 0x18 /* Status Register */ | ||
58 | #define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ | ||
59 | #define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ | ||
60 | #define AT91_RTC_SECEV (1 << 2) /* Second Event */ | ||
61 | #define AT91_RTC_TIMEV (1 << 3) /* Time Event */ | ||
62 | #define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ | ||
63 | |||
64 | #define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */ | ||
65 | #define AT91_RTC_IER 0x20 /* Interrupt Enable Register */ | ||
66 | #define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ | ||
67 | #define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ | ||
68 | |||
69 | #define AT91_RTC_VER 0x2c /* Valid Entry Register */ | ||
70 | #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ | ||
71 | #define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ | ||
72 | #define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ | ||
73 | #define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */ | ||
74 | |||
75 | #endif | ||
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 2dfe7a2fb998..e981798e9a9b 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/ioctl.h> | 20 | #include <linux/ioctl.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/platform_data/atmel.h> | ||
22 | 23 | ||
23 | #include <mach/board.h> | ||
24 | #include <mach/at91_rtt.h> | 24 | #include <mach/at91_rtt.h> |
25 | #include <mach/cpu.h> | 25 | #include <mach/cpu.h> |
26 | 26 | ||
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c new file mode 100644 index 000000000000..96bafc5c3bf8 --- /dev/null +++ b/drivers/rtc/rtc-da9055.c | |||
@@ -0,0 +1,413 @@ | |||
1 | /* | ||
2 | * Real time clock driver for DA9055 | ||
3 | * | ||
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: Dajun Dajun Chen <dajun.chen@diasemi.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 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/rtc.h> | ||
18 | |||
19 | #include <linux/mfd/da9055/core.h> | ||
20 | #include <linux/mfd/da9055/reg.h> | ||
21 | #include <linux/mfd/da9055/pdata.h> | ||
22 | |||
23 | struct da9055_rtc { | ||
24 | struct rtc_device *rtc; | ||
25 | struct da9055 *da9055; | ||
26 | int alarm_enable; | ||
27 | }; | ||
28 | |||
29 | static int da9055_rtc_enable_alarm(struct da9055_rtc *rtc, bool enable) | ||
30 | { | ||
31 | int ret; | ||
32 | if (enable) { | ||
33 | ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y, | ||
34 | DA9055_RTC_ALM_EN, | ||
35 | DA9055_RTC_ALM_EN); | ||
36 | if (ret != 0) | ||
37 | dev_err(rtc->da9055->dev, "Failed to enable ALM: %d\n", | ||
38 | ret); | ||
39 | rtc->alarm_enable = 1; | ||
40 | } else { | ||
41 | ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y, | ||
42 | DA9055_RTC_ALM_EN, 0); | ||
43 | if (ret != 0) | ||
44 | dev_err(rtc->da9055->dev, | ||
45 | "Failed to disable ALM: %d\n", ret); | ||
46 | rtc->alarm_enable = 0; | ||
47 | } | ||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | static irqreturn_t da9055_rtc_alm_irq(int irq, void *data) | ||
52 | { | ||
53 | struct da9055_rtc *rtc = data; | ||
54 | |||
55 | da9055_rtc_enable_alarm(rtc, 0); | ||
56 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
57 | |||
58 | return IRQ_HANDLED; | ||
59 | } | ||
60 | |||
61 | static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) | ||
62 | { | ||
63 | int ret; | ||
64 | uint8_t v[5]; | ||
65 | |||
66 | ret = da9055_group_read(da9055, DA9055_REG_ALARM_MI, 5, v); | ||
67 | if (ret != 0) { | ||
68 | dev_err(da9055->dev, "Failed to group read ALM: %d\n", ret); | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | rtc_tm->tm_year = (v[4] & DA9055_RTC_ALM_YEAR) + 100; | ||
73 | rtc_tm->tm_mon = (v[3] & DA9055_RTC_ALM_MONTH) - 1; | ||
74 | rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; | ||
75 | rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; | ||
76 | rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; | ||
77 | |||
78 | return rtc_valid_tm(rtc_tm); | ||
79 | } | ||
80 | |||
81 | static int da9055_set_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) | ||
82 | { | ||
83 | int ret; | ||
84 | uint8_t v[2]; | ||
85 | |||
86 | rtc_tm->tm_year -= 100; | ||
87 | rtc_tm->tm_mon += 1; | ||
88 | |||
89 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MI, | ||
90 | DA9055_RTC_ALM_MIN, rtc_tm->tm_min); | ||
91 | if (ret != 0) { | ||
92 | dev_err(da9055->dev, "Failed to write ALRM MIN: %d\n", ret); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | v[0] = rtc_tm->tm_hour; | ||
97 | v[1] = rtc_tm->tm_mday; | ||
98 | |||
99 | ret = da9055_group_write(da9055, DA9055_REG_ALARM_H, 2, v); | ||
100 | if (ret < 0) | ||
101 | return ret; | ||
102 | |||
103 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO, | ||
104 | DA9055_RTC_ALM_MONTH, rtc_tm->tm_mon); | ||
105 | if (ret < 0) | ||
106 | dev_err(da9055->dev, "Failed to write ALM Month:%d\n", ret); | ||
107 | |||
108 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_Y, | ||
109 | DA9055_RTC_ALM_YEAR, rtc_tm->tm_year); | ||
110 | if (ret < 0) | ||
111 | dev_err(da9055->dev, "Failed to write ALM Year:%d\n", ret); | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static int da9055_rtc_get_alarm_status(struct da9055 *da9055) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = da9055_reg_read(da9055, DA9055_REG_ALARM_Y); | ||
121 | if (ret < 0) { | ||
122 | dev_err(da9055->dev, "Failed to read ALM: %d\n", ret); | ||
123 | return ret; | ||
124 | } | ||
125 | ret &= DA9055_RTC_ALM_EN; | ||
126 | return (ret > 0) ? 1 : 0; | ||
127 | } | ||
128 | |||
129 | static int da9055_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | ||
130 | { | ||
131 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
132 | uint8_t v[6]; | ||
133 | int ret; | ||
134 | |||
135 | ret = da9055_reg_read(rtc->da9055, DA9055_REG_COUNT_S); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* | ||
140 | * Registers are only valid when RTC_READ | ||
141 | * status bit is asserted | ||
142 | */ | ||
143 | if (!(ret & DA9055_RTC_READ)) | ||
144 | return -EBUSY; | ||
145 | |||
146 | ret = da9055_group_read(rtc->da9055, DA9055_REG_COUNT_S, 6, v); | ||
147 | if (ret < 0) { | ||
148 | dev_err(rtc->da9055->dev, "Failed to read RTC time : %d\n", | ||
149 | ret); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | rtc_tm->tm_year = (v[5] & DA9055_RTC_YEAR) + 100; | ||
154 | rtc_tm->tm_mon = (v[4] & DA9055_RTC_MONTH) - 1; | ||
155 | rtc_tm->tm_mday = v[3] & DA9055_RTC_DAY; | ||
156 | rtc_tm->tm_hour = v[2] & DA9055_RTC_HOUR; | ||
157 | rtc_tm->tm_min = v[1] & DA9055_RTC_MIN; | ||
158 | rtc_tm->tm_sec = v[0] & DA9055_RTC_SEC; | ||
159 | |||
160 | return rtc_valid_tm(rtc_tm); | ||
161 | } | ||
162 | |||
163 | static int da9055_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
164 | { | ||
165 | struct da9055_rtc *rtc; | ||
166 | uint8_t v[6]; | ||
167 | |||
168 | rtc = dev_get_drvdata(dev); | ||
169 | |||
170 | v[0] = tm->tm_sec; | ||
171 | v[1] = tm->tm_min; | ||
172 | v[2] = tm->tm_hour; | ||
173 | v[3] = tm->tm_mday; | ||
174 | v[4] = tm->tm_mon + 1; | ||
175 | v[5] = tm->tm_year - 100; | ||
176 | |||
177 | return da9055_group_write(rtc->da9055, DA9055_REG_COUNT_S, 6, v); | ||
178 | } | ||
179 | |||
180 | static int da9055_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
181 | { | ||
182 | int ret; | ||
183 | struct rtc_time *tm = &alrm->time; | ||
184 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
185 | |||
186 | ret = da9055_read_alarm(rtc->da9055, tm); | ||
187 | |||
188 | if (ret) | ||
189 | return ret; | ||
190 | |||
191 | alrm->enabled = da9055_rtc_get_alarm_status(rtc->da9055); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int da9055_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
197 | { | ||
198 | int ret; | ||
199 | struct rtc_time *tm = &alrm->time; | ||
200 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
201 | |||
202 | ret = da9055_rtc_enable_alarm(rtc, 0); | ||
203 | if (ret < 0) | ||
204 | return ret; | ||
205 | |||
206 | ret = da9055_set_alarm(rtc->da9055, tm); | ||
207 | if (ret) | ||
208 | return ret; | ||
209 | |||
210 | ret = da9055_rtc_enable_alarm(rtc, 1); | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static int da9055_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
216 | { | ||
217 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
218 | |||
219 | return da9055_rtc_enable_alarm(rtc, enabled); | ||
220 | } | ||
221 | |||
222 | static const struct rtc_class_ops da9055_rtc_ops = { | ||
223 | .read_time = da9055_rtc_read_time, | ||
224 | .set_time = da9055_rtc_set_time, | ||
225 | .read_alarm = da9055_rtc_read_alarm, | ||
226 | .set_alarm = da9055_rtc_set_alarm, | ||
227 | .alarm_irq_enable = da9055_rtc_alarm_irq_enable, | ||
228 | }; | ||
229 | |||
230 | static int __init da9055_rtc_device_init(struct da9055 *da9055, | ||
231 | struct da9055_pdata *pdata) | ||
232 | { | ||
233 | int ret; | ||
234 | |||
235 | /* Enable RTC and the internal Crystal */ | ||
236 | ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, | ||
237 | DA9055_RTC_EN, DA9055_RTC_EN); | ||
238 | if (ret < 0) | ||
239 | return ret; | ||
240 | ret = da9055_reg_update(da9055, DA9055_REG_EN_32K, | ||
241 | DA9055_CRYSTAL_EN, DA9055_CRYSTAL_EN); | ||
242 | if (ret < 0) | ||
243 | return ret; | ||
244 | |||
245 | /* Enable RTC in Power Down mode */ | ||
246 | ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, | ||
247 | DA9055_RTC_MODE_PD, DA9055_RTC_MODE_PD); | ||
248 | if (ret < 0) | ||
249 | return ret; | ||
250 | |||
251 | /* Enable RTC in Reset mode */ | ||
252 | if (pdata && pdata->reset_enable) { | ||
253 | ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, | ||
254 | DA9055_RTC_MODE_SD, | ||
255 | DA9055_RTC_MODE_SD << | ||
256 | DA9055_RTC_MODE_SD_SHIFT); | ||
257 | if (ret < 0) | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | /* Disable the RTC TICK ALM */ | ||
262 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO, | ||
263 | DA9055_RTC_TICK_WAKE_MASK, 0); | ||
264 | if (ret < 0) | ||
265 | return ret; | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int da9055_rtc_probe(struct platform_device *pdev) | ||
271 | { | ||
272 | struct da9055_rtc *rtc; | ||
273 | struct da9055_pdata *pdata = NULL; | ||
274 | int ret, alm_irq; | ||
275 | |||
276 | rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9055_rtc), GFP_KERNEL); | ||
277 | if (!rtc) | ||
278 | return -ENOMEM; | ||
279 | |||
280 | rtc->da9055 = dev_get_drvdata(pdev->dev.parent); | ||
281 | pdata = rtc->da9055->dev->platform_data; | ||
282 | platform_set_drvdata(pdev, rtc); | ||
283 | |||
284 | ret = da9055_rtc_device_init(rtc->da9055, pdata); | ||
285 | if (ret < 0) | ||
286 | goto err_rtc; | ||
287 | |||
288 | ret = da9055_reg_read(rtc->da9055, DA9055_REG_ALARM_Y); | ||
289 | if (ret < 0) | ||
290 | goto err_rtc; | ||
291 | |||
292 | if (ret & DA9055_RTC_ALM_EN) | ||
293 | rtc->alarm_enable = 1; | ||
294 | |||
295 | device_init_wakeup(&pdev->dev, 1); | ||
296 | |||
297 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
298 | &da9055_rtc_ops, THIS_MODULE); | ||
299 | if (IS_ERR(rtc->rtc)) { | ||
300 | ret = PTR_ERR(rtc->rtc); | ||
301 | goto err_rtc; | ||
302 | } | ||
303 | |||
304 | alm_irq = platform_get_irq_byname(pdev, "ALM"); | ||
305 | alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, alm_irq); | ||
306 | ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, | ||
307 | da9055_rtc_alm_irq, | ||
308 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
309 | "ALM", rtc); | ||
310 | if (ret != 0) | ||
311 | dev_err(rtc->da9055->dev, "irq registration failed: %d\n", ret); | ||
312 | |||
313 | err_rtc: | ||
314 | return ret; | ||
315 | |||
316 | } | ||
317 | |||
318 | static int da9055_rtc_remove(struct platform_device *pdev) | ||
319 | { | ||
320 | struct da9055_rtc *rtc = pdev->dev.platform_data; | ||
321 | |||
322 | rtc_device_unregister(rtc->rtc); | ||
323 | platform_set_drvdata(pdev, NULL); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | #ifdef CONFIG_PM | ||
329 | /* Turn off the alarm if it should not be a wake source. */ | ||
330 | static int da9055_rtc_suspend(struct device *dev) | ||
331 | { | ||
332 | struct platform_device *pdev = to_platform_device(dev); | ||
333 | struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
334 | int ret; | ||
335 | |||
336 | if (!device_may_wakeup(&pdev->dev)) { | ||
337 | /* Disable the ALM IRQ */ | ||
338 | ret = da9055_rtc_enable_alarm(rtc, 0); | ||
339 | if (ret < 0) | ||
340 | dev_err(&pdev->dev, "Failed to disable RTC ALM\n"); | ||
341 | } | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* Enable the alarm if it should be enabled (in case it was disabled to | ||
347 | * prevent use as a wake source). | ||
348 | */ | ||
349 | static int da9055_rtc_resume(struct device *dev) | ||
350 | { | ||
351 | struct platform_device *pdev = to_platform_device(dev); | ||
352 | struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
353 | int ret; | ||
354 | |||
355 | if (!device_may_wakeup(&pdev->dev)) { | ||
356 | if (rtc->alarm_enable) { | ||
357 | ret = da9055_rtc_enable_alarm(rtc, 1); | ||
358 | if (ret < 0) | ||
359 | dev_err(&pdev->dev, | ||
360 | "Failed to restart RTC ALM\n"); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* Unconditionally disable the alarm */ | ||
368 | static int da9055_rtc_freeze(struct device *dev) | ||
369 | { | ||
370 | struct platform_device *pdev = to_platform_device(dev); | ||
371 | struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
372 | int ret; | ||
373 | |||
374 | ret = da9055_rtc_enable_alarm(rtc, 0); | ||
375 | if (ret < 0) | ||
376 | dev_err(&pdev->dev, "Failed to freeze RTC ALMs\n"); | ||
377 | |||
378 | return 0; | ||
379 | |||
380 | } | ||
381 | #else | ||
382 | #define da9055_rtc_suspend NULL | ||
383 | #define da9055_rtc_resume NULL | ||
384 | #define da9055_rtc_freeze NULL | ||
385 | #endif | ||
386 | |||
387 | static const struct dev_pm_ops da9055_rtc_pm_ops = { | ||
388 | .suspend = da9055_rtc_suspend, | ||
389 | .resume = da9055_rtc_resume, | ||
390 | |||
391 | .freeze = da9055_rtc_freeze, | ||
392 | .thaw = da9055_rtc_resume, | ||
393 | .restore = da9055_rtc_resume, | ||
394 | |||
395 | .poweroff = da9055_rtc_suspend, | ||
396 | }; | ||
397 | |||
398 | static struct platform_driver da9055_rtc_driver = { | ||
399 | .probe = da9055_rtc_probe, | ||
400 | .remove = da9055_rtc_remove, | ||
401 | .driver = { | ||
402 | .name = "da9055-rtc", | ||
403 | .owner = THIS_MODULE, | ||
404 | .pm = &da9055_rtc_pm_ops, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | module_platform_driver(da9055_rtc_driver); | ||
409 | |||
410 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
411 | MODULE_DESCRIPTION("RTC driver for Dialog DA9055 PMIC"); | ||
412 | MODULE_LICENSE("GPL"); | ||
413 | MODULE_ALIAS("platform:da9055-rtc"); | ||
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 14c2109dbaa3..07cd03eae606 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
@@ -485,7 +485,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
485 | struct resource *res, *mem; | 485 | struct resource *res, *mem; |
486 | int ret = 0; | 486 | int ret = 0; |
487 | 487 | ||
488 | davinci_rtc = kzalloc(sizeof(struct davinci_rtc), GFP_KERNEL); | 488 | davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL); |
489 | if (!davinci_rtc) { | 489 | if (!davinci_rtc) { |
490 | dev_dbg(dev, "could not allocate memory for private data\n"); | 490 | dev_dbg(dev, "could not allocate memory for private data\n"); |
491 | return -ENOMEM; | 491 | return -ENOMEM; |
@@ -494,15 +494,13 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
494 | davinci_rtc->irq = platform_get_irq(pdev, 0); | 494 | davinci_rtc->irq = platform_get_irq(pdev, 0); |
495 | if (davinci_rtc->irq < 0) { | 495 | if (davinci_rtc->irq < 0) { |
496 | dev_err(dev, "no RTC irq\n"); | 496 | dev_err(dev, "no RTC irq\n"); |
497 | ret = davinci_rtc->irq; | 497 | return davinci_rtc->irq; |
498 | goto fail1; | ||
499 | } | 498 | } |
500 | 499 | ||
501 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 500 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
502 | if (!res) { | 501 | if (!res) { |
503 | dev_err(dev, "no mem resource\n"); | 502 | dev_err(dev, "no mem resource\n"); |
504 | ret = -EINVAL; | 503 | return -EINVAL; |
505 | goto fail1; | ||
506 | } | 504 | } |
507 | 505 | ||
508 | davinci_rtc->pbase = res->start; | 506 | davinci_rtc->pbase = res->start; |
@@ -513,8 +511,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
513 | if (!mem) { | 511 | if (!mem) { |
514 | dev_err(dev, "RTC registers at %08x are not free\n", | 512 | dev_err(dev, "RTC registers at %08x are not free\n", |
515 | davinci_rtc->pbase); | 513 | davinci_rtc->pbase); |
516 | ret = -EBUSY; | 514 | return -EBUSY; |
517 | goto fail1; | ||
518 | } | 515 | } |
519 | 516 | ||
520 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); | 517 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); |
@@ -529,8 +526,9 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
529 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 526 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
530 | &davinci_rtc_ops, THIS_MODULE); | 527 | &davinci_rtc_ops, THIS_MODULE); |
531 | if (IS_ERR(davinci_rtc->rtc)) { | 528 | if (IS_ERR(davinci_rtc->rtc)) { |
532 | dev_err(dev, "unable to register RTC device, err %ld\n", | 529 | ret = PTR_ERR(davinci_rtc->rtc); |
533 | PTR_ERR(davinci_rtc->rtc)); | 530 | dev_err(dev, "unable to register RTC device, err %d\n", |
531 | ret); | ||
534 | goto fail3; | 532 | goto fail3; |
535 | } | 533 | } |
536 | 534 | ||
@@ -566,9 +564,6 @@ fail3: | |||
566 | iounmap(davinci_rtc->base); | 564 | iounmap(davinci_rtc->base); |
567 | fail2: | 565 | fail2: |
568 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | 566 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); |
569 | fail1: | ||
570 | kfree(davinci_rtc); | ||
571 | |||
572 | return ret; | 567 | return ret; |
573 | } | 568 | } |
574 | 569 | ||
@@ -589,8 +584,6 @@ static int __devexit davinci_rtc_remove(struct platform_device *pdev) | |||
589 | 584 | ||
590 | platform_set_drvdata(pdev, NULL); | 585 | platform_set_drvdata(pdev, NULL); |
591 | 586 | ||
592 | kfree(davinci_rtc); | ||
593 | |||
594 | return 0; | 587 | return 0; |
595 | } | 588 | } |
596 | 589 | ||
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index cace6d3aed9a..9a86b4bd8699 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -379,25 +379,6 @@ static long rtc_dev_ioctl(struct file *file, | |||
379 | err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); | 379 | err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); |
380 | break; | 380 | break; |
381 | 381 | ||
382 | #if 0 | ||
383 | case RTC_EPOCH_SET: | ||
384 | #ifndef rtc_epoch | ||
385 | /* | ||
386 | * There were no RTC clocks before 1900. | ||
387 | */ | ||
388 | if (arg < 1900) { | ||
389 | err = -EINVAL; | ||
390 | break; | ||
391 | } | ||
392 | rtc_epoch = arg; | ||
393 | err = 0; | ||
394 | #endif | ||
395 | break; | ||
396 | |||
397 | case RTC_EPOCH_READ: | ||
398 | err = put_user(rtc_epoch, (unsigned long __user *)uarg); | ||
399 | break; | ||
400 | #endif | ||
401 | case RTC_WKALM_SET: | 382 | case RTC_WKALM_SET: |
402 | mutex_unlock(&rtc->ops_lock); | 383 | mutex_unlock(&rtc->ops_lock); |
403 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) | 384 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) |
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 4eed51044c5d..18a4f0dd78a3 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/rtc.h> | 37 | #include <linux/rtc.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
40 | #include <linux/of.h> | ||
40 | 41 | ||
41 | /* DryIce Register Definitions */ | 42 | /* DryIce Register Definitions */ |
42 | 43 | ||
@@ -495,10 +496,20 @@ static int __devexit dryice_rtc_remove(struct platform_device *pdev) | |||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
497 | 498 | ||
499 | #ifdef CONFIG_OF | ||
500 | static const struct of_device_id dryice_dt_ids[] = { | ||
501 | { .compatible = "fsl,imx25-rtc" }, | ||
502 | { /* sentinel */ } | ||
503 | }; | ||
504 | |||
505 | MODULE_DEVICE_TABLE(of, dryice_dt_ids); | ||
506 | #endif | ||
507 | |||
498 | static struct platform_driver dryice_rtc_driver = { | 508 | static struct platform_driver dryice_rtc_driver = { |
499 | .driver = { | 509 | .driver = { |
500 | .name = "imxdi_rtc", | 510 | .name = "imxdi_rtc", |
501 | .owner = THIS_MODULE, | 511 | .owner = THIS_MODULE, |
512 | .of_match_table = of_match_ptr(dryice_dt_ids), | ||
502 | }, | 513 | }, |
503 | .remove = __devexit_p(dryice_rtc_remove), | 514 | .remove = __devexit_p(dryice_rtc_remove), |
504 | }; | 515 | }; |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 26c81f233606..afb7cfa85ccc 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -118,7 +118,7 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | |||
118 | return ret; | 118 | return ret; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* simple check to see wether we have a isl1208 */ | 121 | /* simple check to see whether we have a isl1208 */ |
122 | static int | 122 | static int |
123 | isl1208_i2c_validate_client(struct i2c_client *client) | 123 | isl1208_i2c_validate_client(struct i2c_client *client) |
124 | { | 124 | { |
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index cd0106293a49..7304139934aa 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
@@ -17,8 +17,6 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | 19 | ||
20 | #include <mach/hardware.h> | ||
21 | |||
22 | #define RTC_INPUT_CLK_32768HZ (0x00 << 5) | 20 | #define RTC_INPUT_CLK_32768HZ (0x00 << 5) |
23 | #define RTC_INPUT_CLK_32000HZ (0x01 << 5) | 21 | #define RTC_INPUT_CLK_32000HZ (0x01 << 5) |
24 | #define RTC_INPUT_CLK_38400HZ (0x02 << 5) | 22 | #define RTC_INPUT_CLK_38400HZ (0x02 << 5) |
@@ -72,14 +70,38 @@ static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = { | |||
72 | #define RTC_TEST2 0x2C /* 32bit rtc test reg 2 */ | 70 | #define RTC_TEST2 0x2C /* 32bit rtc test reg 2 */ |
73 | #define RTC_TEST3 0x30 /* 32bit rtc test reg 3 */ | 71 | #define RTC_TEST3 0x30 /* 32bit rtc test reg 3 */ |
74 | 72 | ||
73 | enum imx_rtc_type { | ||
74 | IMX1_RTC, | ||
75 | IMX21_RTC, | ||
76 | }; | ||
77 | |||
75 | struct rtc_plat_data { | 78 | struct rtc_plat_data { |
76 | struct rtc_device *rtc; | 79 | struct rtc_device *rtc; |
77 | void __iomem *ioaddr; | 80 | void __iomem *ioaddr; |
78 | int irq; | 81 | int irq; |
79 | struct clk *clk; | 82 | struct clk *clk; |
80 | struct rtc_time g_rtc_alarm; | 83 | struct rtc_time g_rtc_alarm; |
84 | enum imx_rtc_type devtype; | ||
81 | }; | 85 | }; |
82 | 86 | ||
87 | static struct platform_device_id imx_rtc_devtype[] = { | ||
88 | { | ||
89 | .name = "imx1-rtc", | ||
90 | .driver_data = IMX1_RTC, | ||
91 | }, { | ||
92 | .name = "imx21-rtc", | ||
93 | .driver_data = IMX21_RTC, | ||
94 | }, { | ||
95 | /* sentinel */ | ||
96 | } | ||
97 | }; | ||
98 | MODULE_DEVICE_TABLE(platform, imx_rtc_devtype); | ||
99 | |||
100 | static inline int is_imx1_rtc(struct rtc_plat_data *data) | ||
101 | { | ||
102 | return data->devtype == IMX1_RTC; | ||
103 | } | ||
104 | |||
83 | /* | 105 | /* |
84 | * This function is used to obtain the RTC time or the alarm value in | 106 | * This function is used to obtain the RTC time or the alarm value in |
85 | * second. | 107 | * second. |
@@ -278,10 +300,13 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
278 | */ | 300 | */ |
279 | static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) | 301 | static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) |
280 | { | 302 | { |
303 | struct platform_device *pdev = to_platform_device(dev); | ||
304 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
305 | |||
281 | /* | 306 | /* |
282 | * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only | 307 | * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only |
283 | */ | 308 | */ |
284 | if (cpu_is_mx1()) { | 309 | if (is_imx1_rtc(pdata)) { |
285 | struct rtc_time tm; | 310 | struct rtc_time tm; |
286 | 311 | ||
287 | rtc_time_to_tm(time, &tm); | 312 | rtc_time_to_tm(time, &tm); |
@@ -360,6 +385,8 @@ static int __devinit mxc_rtc_probe(struct platform_device *pdev) | |||
360 | if (!pdata) | 385 | if (!pdata) |
361 | return -ENOMEM; | 386 | return -ENOMEM; |
362 | 387 | ||
388 | pdata->devtype = pdev->id_entry->driver_data; | ||
389 | |||
363 | if (!devm_request_mem_region(&pdev->dev, res->start, | 390 | if (!devm_request_mem_region(&pdev->dev, res->start, |
364 | resource_size(res), pdev->name)) | 391 | resource_size(res), pdev->name)) |
365 | return -EBUSY; | 392 | return -EBUSY; |
@@ -480,6 +507,7 @@ static struct platform_driver mxc_rtc_driver = { | |||
480 | #endif | 507 | #endif |
481 | .owner = THIS_MODULE, | 508 | .owner = THIS_MODULE, |
482 | }, | 509 | }, |
510 | .id_table = imx_rtc_devtype, | ||
483 | .probe = mxc_rtc_probe, | 511 | .probe = mxc_rtc_probe, |
484 | .remove = __devexit_p(mxc_rtc_remove), | 512 | .remove = __devexit_p(mxc_rtc_remove), |
485 | }; | 513 | }; |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 0b614e32653d..600971407aac 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
25 | #include <linux/pm_runtime.h> | ||
23 | 26 | ||
24 | #include <asm/io.h> | 27 | #include <asm/io.h> |
25 | 28 | ||
@@ -38,6 +41,8 @@ | |||
38 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. | 41 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. |
39 | */ | 42 | */ |
40 | 43 | ||
44 | #define DRIVER_NAME "omap_rtc" | ||
45 | |||
41 | #define OMAP_RTC_BASE 0xfffb4800 | 46 | #define OMAP_RTC_BASE 0xfffb4800 |
42 | 47 | ||
43 | /* RTC registers */ | 48 | /* RTC registers */ |
@@ -64,6 +69,9 @@ | |||
64 | #define OMAP_RTC_COMP_MSB_REG 0x50 | 69 | #define OMAP_RTC_COMP_MSB_REG 0x50 |
65 | #define OMAP_RTC_OSC_REG 0x54 | 70 | #define OMAP_RTC_OSC_REG 0x54 |
66 | 71 | ||
72 | #define OMAP_RTC_KICK0_REG 0x6c | ||
73 | #define OMAP_RTC_KICK1_REG 0x70 | ||
74 | |||
67 | /* OMAP_RTC_CTRL_REG bit fields: */ | 75 | /* OMAP_RTC_CTRL_REG bit fields: */ |
68 | #define OMAP_RTC_CTRL_SPLIT (1<<7) | 76 | #define OMAP_RTC_CTRL_SPLIT (1<<7) |
69 | #define OMAP_RTC_CTRL_DISABLE (1<<6) | 77 | #define OMAP_RTC_CTRL_DISABLE (1<<6) |
@@ -88,10 +96,18 @@ | |||
88 | #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) | 96 | #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) |
89 | #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) | 97 | #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) |
90 | 98 | ||
99 | /* OMAP_RTC_KICKER values */ | ||
100 | #define KICK0_VALUE 0x83e70b13 | ||
101 | #define KICK1_VALUE 0x95a4f1e0 | ||
102 | |||
103 | #define OMAP_RTC_HAS_KICKER 0x1 | ||
104 | |||
91 | static void __iomem *rtc_base; | 105 | static void __iomem *rtc_base; |
92 | 106 | ||
93 | #define rtc_read(addr) __raw_readb(rtc_base + (addr)) | 107 | #define rtc_read(addr) readb(rtc_base + (addr)) |
94 | #define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr)) | 108 | #define rtc_write(val, addr) writeb(val, rtc_base + (addr)) |
109 | |||
110 | #define rtc_writel(val, addr) writel(val, rtc_base + (addr)) | ||
95 | 111 | ||
96 | 112 | ||
97 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), | 113 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), |
@@ -285,11 +301,38 @@ static struct rtc_class_ops omap_rtc_ops = { | |||
285 | static int omap_rtc_alarm; | 301 | static int omap_rtc_alarm; |
286 | static int omap_rtc_timer; | 302 | static int omap_rtc_timer; |
287 | 303 | ||
304 | #define OMAP_RTC_DATA_DA830_IDX 1 | ||
305 | |||
306 | static struct platform_device_id omap_rtc_devtype[] = { | ||
307 | { | ||
308 | .name = DRIVER_NAME, | ||
309 | }, { | ||
310 | .name = "da830-rtc", | ||
311 | .driver_data = OMAP_RTC_HAS_KICKER, | ||
312 | }, | ||
313 | {}, | ||
314 | }; | ||
315 | MODULE_DEVICE_TABLE(platform, omap_rtc_devtype); | ||
316 | |||
317 | static const struct of_device_id omap_rtc_of_match[] = { | ||
318 | { .compatible = "ti,da830-rtc", | ||
319 | .data = &omap_rtc_devtype[OMAP_RTC_DATA_DA830_IDX], | ||
320 | }, | ||
321 | {}, | ||
322 | }; | ||
323 | MODULE_DEVICE_TABLE(of, omap_rtc_of_match); | ||
324 | |||
288 | static int __init omap_rtc_probe(struct platform_device *pdev) | 325 | static int __init omap_rtc_probe(struct platform_device *pdev) |
289 | { | 326 | { |
290 | struct resource *res, *mem; | 327 | struct resource *res, *mem; |
291 | struct rtc_device *rtc; | 328 | struct rtc_device *rtc; |
292 | u8 reg, new_ctrl; | 329 | u8 reg, new_ctrl; |
330 | const struct platform_device_id *id_entry; | ||
331 | const struct of_device_id *of_id; | ||
332 | |||
333 | of_id = of_match_device(omap_rtc_of_match, &pdev->dev); | ||
334 | if (of_id) | ||
335 | pdev->id_entry = of_id->data; | ||
293 | 336 | ||
294 | omap_rtc_timer = platform_get_irq(pdev, 0); | 337 | omap_rtc_timer = platform_get_irq(pdev, 0); |
295 | if (omap_rtc_timer <= 0) { | 338 | if (omap_rtc_timer <= 0) { |
@@ -322,6 +365,16 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
322 | goto fail; | 365 | goto fail; |
323 | } | 366 | } |
324 | 367 | ||
368 | /* Enable the clock/module so that we can access the registers */ | ||
369 | pm_runtime_enable(&pdev->dev); | ||
370 | pm_runtime_get_sync(&pdev->dev); | ||
371 | |||
372 | id_entry = platform_get_device_id(pdev); | ||
373 | if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) { | ||
374 | rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG); | ||
375 | rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG); | ||
376 | } | ||
377 | |||
325 | rtc = rtc_device_register(pdev->name, &pdev->dev, | 378 | rtc = rtc_device_register(pdev->name, &pdev->dev, |
326 | &omap_rtc_ops, THIS_MODULE); | 379 | &omap_rtc_ops, THIS_MODULE); |
327 | if (IS_ERR(rtc)) { | 380 | if (IS_ERR(rtc)) { |
@@ -398,6 +451,10 @@ fail2: | |||
398 | fail1: | 451 | fail1: |
399 | rtc_device_unregister(rtc); | 452 | rtc_device_unregister(rtc); |
400 | fail0: | 453 | fail0: |
454 | if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) | ||
455 | rtc_writel(0, OMAP_RTC_KICK0_REG); | ||
456 | pm_runtime_put_sync(&pdev->dev); | ||
457 | pm_runtime_disable(&pdev->dev); | ||
401 | iounmap(rtc_base); | 458 | iounmap(rtc_base); |
402 | fail: | 459 | fail: |
403 | release_mem_region(mem->start, resource_size(mem)); | 460 | release_mem_region(mem->start, resource_size(mem)); |
@@ -408,6 +465,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
408 | { | 465 | { |
409 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 466 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
410 | struct resource *mem = dev_get_drvdata(&rtc->dev); | 467 | struct resource *mem = dev_get_drvdata(&rtc->dev); |
468 | const struct platform_device_id *id_entry = | ||
469 | platform_get_device_id(pdev); | ||
411 | 470 | ||
412 | device_init_wakeup(&pdev->dev, 0); | 471 | device_init_wakeup(&pdev->dev, 0); |
413 | 472 | ||
@@ -420,6 +479,13 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
420 | free_irq(omap_rtc_alarm, rtc); | 479 | free_irq(omap_rtc_alarm, rtc); |
421 | 480 | ||
422 | rtc_device_unregister(rtc); | 481 | rtc_device_unregister(rtc); |
482 | if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) | ||
483 | rtc_writel(0, OMAP_RTC_KICK0_REG); | ||
484 | |||
485 | /* Disable the clock/module */ | ||
486 | pm_runtime_put_sync(&pdev->dev); | ||
487 | pm_runtime_disable(&pdev->dev); | ||
488 | |||
423 | iounmap(rtc_base); | 489 | iounmap(rtc_base); |
424 | release_mem_region(mem->start, resource_size(mem)); | 490 | release_mem_region(mem->start, resource_size(mem)); |
425 | return 0; | 491 | return 0; |
@@ -442,11 +508,17 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
442 | else | 508 | else |
443 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 509 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); |
444 | 510 | ||
511 | /* Disable the clock/module */ | ||
512 | pm_runtime_put_sync(&pdev->dev); | ||
513 | |||
445 | return 0; | 514 | return 0; |
446 | } | 515 | } |
447 | 516 | ||
448 | static int omap_rtc_resume(struct platform_device *pdev) | 517 | static int omap_rtc_resume(struct platform_device *pdev) |
449 | { | 518 | { |
519 | /* Enable the clock/module so that we can access the registers */ | ||
520 | pm_runtime_get_sync(&pdev->dev); | ||
521 | |||
450 | if (device_may_wakeup(&pdev->dev)) | 522 | if (device_may_wakeup(&pdev->dev)) |
451 | disable_irq_wake(omap_rtc_alarm); | 523 | disable_irq_wake(omap_rtc_alarm); |
452 | else | 524 | else |
@@ -471,9 +543,11 @@ static struct platform_driver omap_rtc_driver = { | |||
471 | .resume = omap_rtc_resume, | 543 | .resume = omap_rtc_resume, |
472 | .shutdown = omap_rtc_shutdown, | 544 | .shutdown = omap_rtc_shutdown, |
473 | .driver = { | 545 | .driver = { |
474 | .name = "omap_rtc", | 546 | .name = DRIVER_NAME, |
475 | .owner = THIS_MODULE, | 547 | .owner = THIS_MODULE, |
548 | .of_match_table = of_match_ptr(omap_rtc_of_match), | ||
476 | }, | 549 | }, |
550 | .id_table = omap_rtc_devtype, | ||
477 | }; | 551 | }; |
478 | 552 | ||
479 | static int __init rtc_init(void) | 553 | static int __init rtc_init(void) |
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c new file mode 100644 index 000000000000..be05a645f99e --- /dev/null +++ b/drivers/rtc/rtc-pcf8523.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Avionic Design GmbH | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/bcd.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/rtc.h> | ||
13 | #include <linux/of.h> | ||
14 | |||
15 | #define DRIVER_NAME "rtc-pcf8523" | ||
16 | |||
17 | #define REG_CONTROL1 0x00 | ||
18 | #define REG_CONTROL1_CAP_SEL (1 << 7) | ||
19 | #define REG_CONTROL1_STOP (1 << 5) | ||
20 | |||
21 | #define REG_CONTROL3 0x02 | ||
22 | #define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */ | ||
23 | #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */ | ||
24 | #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */ | ||
25 | #define REG_CONTROL3_PM_MASK 0xe0 | ||
26 | |||
27 | #define REG_SECONDS 0x03 | ||
28 | #define REG_SECONDS_OS (1 << 7) | ||
29 | |||
30 | #define REG_MINUTES 0x04 | ||
31 | #define REG_HOURS 0x05 | ||
32 | #define REG_DAYS 0x06 | ||
33 | #define REG_WEEKDAYS 0x07 | ||
34 | #define REG_MONTHS 0x08 | ||
35 | #define REG_YEARS 0x09 | ||
36 | |||
37 | struct pcf8523 { | ||
38 | struct rtc_device *rtc; | ||
39 | }; | ||
40 | |||
41 | static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep) | ||
42 | { | ||
43 | struct i2c_msg msgs[2]; | ||
44 | u8 value = 0; | ||
45 | int err; | ||
46 | |||
47 | msgs[0].addr = client->addr; | ||
48 | msgs[0].flags = 0; | ||
49 | msgs[0].len = sizeof(reg); | ||
50 | msgs[0].buf = ® | ||
51 | |||
52 | msgs[1].addr = client->addr; | ||
53 | msgs[1].flags = I2C_M_RD; | ||
54 | msgs[1].len = sizeof(value); | ||
55 | msgs[1].buf = &value; | ||
56 | |||
57 | err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
58 | if (err < 0) | ||
59 | return err; | ||
60 | |||
61 | *valuep = value; | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value) | ||
67 | { | ||
68 | u8 buffer[2] = { reg, value }; | ||
69 | struct i2c_msg msg; | ||
70 | int err; | ||
71 | |||
72 | msg.addr = client->addr; | ||
73 | msg.flags = 0; | ||
74 | msg.len = sizeof(buffer); | ||
75 | msg.buf = buffer; | ||
76 | |||
77 | err = i2c_transfer(client->adapter, &msg, 1); | ||
78 | if (err < 0) | ||
79 | return err; | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int pcf8523_select_capacitance(struct i2c_client *client, bool high) | ||
85 | { | ||
86 | u8 value; | ||
87 | int err; | ||
88 | |||
89 | err = pcf8523_read(client, REG_CONTROL1, &value); | ||
90 | if (err < 0) | ||
91 | return err; | ||
92 | |||
93 | if (!high) | ||
94 | value &= ~REG_CONTROL1_CAP_SEL; | ||
95 | else | ||
96 | value |= REG_CONTROL1_CAP_SEL; | ||
97 | |||
98 | err = pcf8523_write(client, REG_CONTROL1, value); | ||
99 | if (err < 0) | ||
100 | return err; | ||
101 | |||
102 | return err; | ||
103 | } | ||
104 | |||
105 | static int pcf8523_set_pm(struct i2c_client *client, u8 pm) | ||
106 | { | ||
107 | u8 value; | ||
108 | int err; | ||
109 | |||
110 | err = pcf8523_read(client, REG_CONTROL3, &value); | ||
111 | if (err < 0) | ||
112 | return err; | ||
113 | |||
114 | value = (value & ~REG_CONTROL3_PM_MASK) | pm; | ||
115 | |||
116 | err = pcf8523_write(client, REG_CONTROL3, value); | ||
117 | if (err < 0) | ||
118 | return err; | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int pcf8523_stop_rtc(struct i2c_client *client) | ||
124 | { | ||
125 | u8 value; | ||
126 | int err; | ||
127 | |||
128 | err = pcf8523_read(client, REG_CONTROL1, &value); | ||
129 | if (err < 0) | ||
130 | return err; | ||
131 | |||
132 | value |= REG_CONTROL1_STOP; | ||
133 | |||
134 | err = pcf8523_write(client, REG_CONTROL1, value); | ||
135 | if (err < 0) | ||
136 | return err; | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int pcf8523_start_rtc(struct i2c_client *client) | ||
142 | { | ||
143 | u8 value; | ||
144 | int err; | ||
145 | |||
146 | err = pcf8523_read(client, REG_CONTROL1, &value); | ||
147 | if (err < 0) | ||
148 | return err; | ||
149 | |||
150 | value &= ~REG_CONTROL1_STOP; | ||
151 | |||
152 | err = pcf8523_write(client, REG_CONTROL1, value); | ||
153 | if (err < 0) | ||
154 | return err; | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
160 | { | ||
161 | struct i2c_client *client = to_i2c_client(dev); | ||
162 | u8 start = REG_SECONDS, regs[7]; | ||
163 | struct i2c_msg msgs[2]; | ||
164 | int err; | ||
165 | |||
166 | msgs[0].addr = client->addr; | ||
167 | msgs[0].flags = 0; | ||
168 | msgs[0].len = 1; | ||
169 | msgs[0].buf = &start; | ||
170 | |||
171 | msgs[1].addr = client->addr; | ||
172 | msgs[1].flags = I2C_M_RD; | ||
173 | msgs[1].len = sizeof(regs); | ||
174 | msgs[1].buf = regs; | ||
175 | |||
176 | err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
177 | if (err < 0) | ||
178 | return err; | ||
179 | |||
180 | if (regs[0] & REG_SECONDS_OS) { | ||
181 | /* | ||
182 | * If the oscillator was stopped, try to clear the flag. Upon | ||
183 | * power-up the flag is always set, but if we cannot clear it | ||
184 | * the oscillator isn't running properly for some reason. The | ||
185 | * sensible thing therefore is to return an error, signalling | ||
186 | * that the clock cannot be assumed to be correct. | ||
187 | */ | ||
188 | |||
189 | regs[0] &= ~REG_SECONDS_OS; | ||
190 | |||
191 | err = pcf8523_write(client, REG_SECONDS, regs[0]); | ||
192 | if (err < 0) | ||
193 | return err; | ||
194 | |||
195 | err = pcf8523_read(client, REG_SECONDS, ®s[0]); | ||
196 | if (err < 0) | ||
197 | return err; | ||
198 | |||
199 | if (regs[0] & REG_SECONDS_OS) | ||
200 | return -EAGAIN; | ||
201 | } | ||
202 | |||
203 | tm->tm_sec = bcd2bin(regs[0] & 0x7f); | ||
204 | tm->tm_min = bcd2bin(regs[1] & 0x7f); | ||
205 | tm->tm_hour = bcd2bin(regs[2] & 0x3f); | ||
206 | tm->tm_mday = bcd2bin(regs[3] & 0x3f); | ||
207 | tm->tm_wday = regs[4] & 0x7; | ||
208 | tm->tm_mon = bcd2bin(regs[5] & 0x1f); | ||
209 | tm->tm_year = bcd2bin(regs[6]) + 100; | ||
210 | |||
211 | return rtc_valid_tm(tm); | ||
212 | } | ||
213 | |||
214 | static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
215 | { | ||
216 | struct i2c_client *client = to_i2c_client(dev); | ||
217 | struct i2c_msg msg; | ||
218 | u8 regs[8]; | ||
219 | int err; | ||
220 | |||
221 | err = pcf8523_stop_rtc(client); | ||
222 | if (err < 0) | ||
223 | return err; | ||
224 | |||
225 | regs[0] = REG_SECONDS; | ||
226 | regs[1] = bin2bcd(tm->tm_sec); | ||
227 | regs[2] = bin2bcd(tm->tm_min); | ||
228 | regs[3] = bin2bcd(tm->tm_hour); | ||
229 | regs[4] = bin2bcd(tm->tm_mday); | ||
230 | regs[5] = tm->tm_wday; | ||
231 | regs[6] = bin2bcd(tm->tm_mon); | ||
232 | regs[7] = bin2bcd(tm->tm_year - 100); | ||
233 | |||
234 | msg.addr = client->addr; | ||
235 | msg.flags = 0; | ||
236 | msg.len = sizeof(regs); | ||
237 | msg.buf = regs; | ||
238 | |||
239 | err = i2c_transfer(client->adapter, &msg, 1); | ||
240 | if (err < 0) { | ||
241 | /* | ||
242 | * If the time cannot be set, restart the RTC anyway. Note | ||
243 | * that errors are ignored if the RTC cannot be started so | ||
244 | * that we have a chance to propagate the original error. | ||
245 | */ | ||
246 | pcf8523_start_rtc(client); | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | return pcf8523_start_rtc(client); | ||
251 | } | ||
252 | |||
253 | static const struct rtc_class_ops pcf8523_rtc_ops = { | ||
254 | .read_time = pcf8523_rtc_read_time, | ||
255 | .set_time = pcf8523_rtc_set_time, | ||
256 | }; | ||
257 | |||
258 | static int pcf8523_probe(struct i2c_client *client, | ||
259 | const struct i2c_device_id *id) | ||
260 | { | ||
261 | struct pcf8523 *pcf; | ||
262 | int err; | ||
263 | |||
264 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
265 | return -ENODEV; | ||
266 | |||
267 | pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL); | ||
268 | if (!pcf) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | err = pcf8523_select_capacitance(client, true); | ||
272 | if (err < 0) | ||
273 | return err; | ||
274 | |||
275 | err = pcf8523_set_pm(client, 0); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | |||
279 | pcf->rtc = rtc_device_register(DRIVER_NAME, &client->dev, | ||
280 | &pcf8523_rtc_ops, THIS_MODULE); | ||
281 | if (IS_ERR(pcf->rtc)) | ||
282 | return PTR_ERR(pcf->rtc); | ||
283 | |||
284 | i2c_set_clientdata(client, pcf); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int pcf8523_remove(struct i2c_client *client) | ||
290 | { | ||
291 | struct pcf8523 *pcf = i2c_get_clientdata(client); | ||
292 | |||
293 | rtc_device_unregister(pcf->rtc); | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static const struct i2c_device_id pcf8523_id[] = { | ||
299 | { "pcf8523", 0 }, | ||
300 | { } | ||
301 | }; | ||
302 | MODULE_DEVICE_TABLE(i2c, pcf8523_id); | ||
303 | |||
304 | #ifdef CONFIG_OF | ||
305 | static const struct of_device_id pcf8523_of_match[] = { | ||
306 | { .compatible = "nxp,pcf8523" }, | ||
307 | { } | ||
308 | }; | ||
309 | MODULE_DEVICE_TABLE(of, pcf8523_of_match); | ||
310 | #endif | ||
311 | |||
312 | static struct i2c_driver pcf8523_driver = { | ||
313 | .driver = { | ||
314 | .name = DRIVER_NAME, | ||
315 | .owner = THIS_MODULE, | ||
316 | .of_match_table = of_match_ptr(pcf8523_of_match), | ||
317 | }, | ||
318 | .probe = pcf8523_probe, | ||
319 | .remove = pcf8523_remove, | ||
320 | .id_table = pcf8523_id, | ||
321 | }; | ||
322 | module_i2c_driver(pcf8523_driver); | ||
323 | |||
324 | MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); | ||
325 | MODULE_DESCRIPTION("NXP PCF8523 RTC driver"); | ||
326 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 77823d21d314..4bd9414aee65 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -47,8 +47,6 @@ struct s3c_rtc_drv_data { | |||
47 | /* I have yet to find an S3C implementation with more than one | 47 | /* I have yet to find an S3C implementation with more than one |
48 | * of these rtc blocks in */ | 48 | * of these rtc blocks in */ |
49 | 49 | ||
50 | static struct resource *s3c_rtc_mem; | ||
51 | |||
52 | static struct clk *rtc_clk; | 50 | static struct clk *rtc_clk; |
53 | static void __iomem *s3c_rtc_base; | 51 | static void __iomem *s3c_rtc_base; |
54 | static int s3c_rtc_alarmno = NO_IRQ; | 52 | static int s3c_rtc_alarmno = NO_IRQ; |
@@ -186,7 +184,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
186 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); | 184 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); |
187 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); | 185 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); |
188 | 186 | ||
189 | /* the only way to work out wether the system was mid-update | 187 | /* the only way to work out whether the system was mid-update |
190 | * when we read it is to check the second counter, and if it | 188 | * when we read it is to check the second counter, and if it |
191 | * is zero, then we re-try the entire read | 189 | * is zero, then we re-try the entire read |
192 | */ | 190 | */ |
@@ -427,21 +425,13 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
427 | { | 425 | { |
428 | struct rtc_device *rtc = platform_get_drvdata(dev); | 426 | struct rtc_device *rtc = platform_get_drvdata(dev); |
429 | 427 | ||
430 | free_irq(s3c_rtc_alarmno, rtc); | ||
431 | free_irq(s3c_rtc_tickno, rtc); | ||
432 | |||
433 | platform_set_drvdata(dev, NULL); | 428 | platform_set_drvdata(dev, NULL); |
434 | rtc_device_unregister(rtc); | 429 | rtc_device_unregister(rtc); |
435 | 430 | ||
436 | s3c_rtc_setaie(&dev->dev, 0); | 431 | s3c_rtc_setaie(&dev->dev, 0); |
437 | 432 | ||
438 | clk_put(rtc_clk); | ||
439 | rtc_clk = NULL; | 433 | rtc_clk = NULL; |
440 | 434 | ||
441 | iounmap(s3c_rtc_base); | ||
442 | release_resource(s3c_rtc_mem); | ||
443 | kfree(s3c_rtc_mem); | ||
444 | |||
445 | return 0; | 435 | return 0; |
446 | } | 436 | } |
447 | 437 | ||
@@ -496,28 +486,18 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
496 | return -ENOENT; | 486 | return -ENOENT; |
497 | } | 487 | } |
498 | 488 | ||
499 | s3c_rtc_mem = request_mem_region(res->start, resource_size(res), | 489 | s3c_rtc_base = devm_request_and_ioremap(&pdev->dev, res); |
500 | pdev->name); | ||
501 | |||
502 | if (s3c_rtc_mem == NULL) { | ||
503 | dev_err(&pdev->dev, "failed to reserve memory region\n"); | ||
504 | ret = -ENOENT; | ||
505 | goto err_nores; | ||
506 | } | ||
507 | |||
508 | s3c_rtc_base = ioremap(res->start, resource_size(res)); | ||
509 | if (s3c_rtc_base == NULL) { | 490 | if (s3c_rtc_base == NULL) { |
510 | dev_err(&pdev->dev, "failed ioremap()\n"); | 491 | dev_err(&pdev->dev, "failed to ioremap memory region\n"); |
511 | ret = -EINVAL; | 492 | return -EINVAL; |
512 | goto err_nomap; | ||
513 | } | 493 | } |
514 | 494 | ||
515 | rtc_clk = clk_get(&pdev->dev, "rtc"); | 495 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); |
516 | if (IS_ERR(rtc_clk)) { | 496 | if (IS_ERR(rtc_clk)) { |
517 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | 497 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); |
518 | ret = PTR_ERR(rtc_clk); | 498 | ret = PTR_ERR(rtc_clk); |
519 | rtc_clk = NULL; | 499 | rtc_clk = NULL; |
520 | goto err_clk; | 500 | return ret; |
521 | } | 501 | } |
522 | 502 | ||
523 | clk_enable(rtc_clk); | 503 | clk_enable(rtc_clk); |
@@ -576,28 +556,24 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
576 | 556 | ||
577 | s3c_rtc_setfreq(&pdev->dev, 1); | 557 | s3c_rtc_setfreq(&pdev->dev, 1); |
578 | 558 | ||
579 | ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, | 559 | ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq, |
580 | 0, "s3c2410-rtc alarm", rtc); | 560 | 0, "s3c2410-rtc alarm", rtc); |
581 | if (ret) { | 561 | if (ret) { |
582 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); | 562 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); |
583 | goto err_alarm_irq; | 563 | goto err_alarm_irq; |
584 | } | 564 | } |
585 | 565 | ||
586 | ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, | 566 | ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, |
587 | 0, "s3c2410-rtc tick", rtc); | 567 | 0, "s3c2410-rtc tick", rtc); |
588 | if (ret) { | 568 | if (ret) { |
589 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); | 569 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); |
590 | free_irq(s3c_rtc_alarmno, rtc); | 570 | goto err_alarm_irq; |
591 | goto err_tick_irq; | ||
592 | } | 571 | } |
593 | 572 | ||
594 | clk_disable(rtc_clk); | 573 | clk_disable(rtc_clk); |
595 | 574 | ||
596 | return 0; | 575 | return 0; |
597 | 576 | ||
598 | err_tick_irq: | ||
599 | free_irq(s3c_rtc_alarmno, rtc); | ||
600 | |||
601 | err_alarm_irq: | 577 | err_alarm_irq: |
602 | platform_set_drvdata(pdev, NULL); | 578 | platform_set_drvdata(pdev, NULL); |
603 | rtc_device_unregister(rtc); | 579 | rtc_device_unregister(rtc); |
@@ -605,15 +581,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
605 | err_nortc: | 581 | err_nortc: |
606 | s3c_rtc_enable(pdev, 0); | 582 | s3c_rtc_enable(pdev, 0); |
607 | clk_disable(rtc_clk); | 583 | clk_disable(rtc_clk); |
608 | clk_put(rtc_clk); | ||
609 | 584 | ||
610 | err_clk: | ||
611 | iounmap(s3c_rtc_base); | ||
612 | |||
613 | err_nomap: | ||
614 | release_resource(s3c_rtc_mem); | ||
615 | |||
616 | err_nores: | ||
617 | return ret; | 585 | return ret; |
618 | } | 586 | } |
619 | 587 | ||
@@ -695,8 +663,6 @@ static const struct of_device_id s3c_rtc_dt_match[] = { | |||
695 | {}, | 663 | {}, |
696 | }; | 664 | }; |
697 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); | 665 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); |
698 | #else | ||
699 | #define s3c_rtc_dt_match NULL | ||
700 | #endif | 666 | #endif |
701 | 667 | ||
702 | static struct platform_device_id s3c_rtc_driver_ids[] = { | 668 | static struct platform_device_id s3c_rtc_driver_ids[] = { |
@@ -727,7 +693,7 @@ static struct platform_driver s3c_rtc_driver = { | |||
727 | .driver = { | 693 | .driver = { |
728 | .name = "s3c-rtc", | 694 | .name = "s3c-rtc", |
729 | .owner = THIS_MODULE, | 695 | .owner = THIS_MODULE, |
730 | .of_match_table = s3c_rtc_dt_match, | 696 | .of_match_table = of_match_ptr(s3c_rtc_dt_match), |
731 | }, | 697 | }, |
732 | }; | 698 | }; |
733 | 699 | ||
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index bb507d23f6ce..141fc945295f 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c | |||
@@ -363,35 +363,42 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) | |||
363 | dev_err(&pdev->dev, "no resource defined\n"); | 363 | dev_err(&pdev->dev, "no resource defined\n"); |
364 | return -EBUSY; | 364 | return -EBUSY; |
365 | } | 365 | } |
366 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
367 | dev_err(&pdev->dev, "rtc region already claimed\n"); | ||
368 | return -EBUSY; | ||
369 | } | ||
370 | 366 | ||
371 | config = kzalloc(sizeof(*config), GFP_KERNEL); | 367 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); |
372 | if (!config) { | 368 | if (!config) { |
373 | dev_err(&pdev->dev, "out of memory\n"); | 369 | dev_err(&pdev->dev, "out of memory\n"); |
374 | status = -ENOMEM; | 370 | return -ENOMEM; |
375 | goto err_release_region; | ||
376 | } | 371 | } |
377 | 372 | ||
378 | config->clk = clk_get(&pdev->dev, NULL); | 373 | /* alarm irqs */ |
379 | if (IS_ERR(config->clk)) { | 374 | irq = platform_get_irq(pdev, 0); |
380 | status = PTR_ERR(config->clk); | 375 | if (irq < 0) { |
381 | goto err_kfree; | 376 | dev_err(&pdev->dev, "no update irq?\n"); |
377 | return irq; | ||
382 | } | 378 | } |
383 | 379 | ||
384 | status = clk_enable(config->clk); | 380 | status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name, |
385 | if (status < 0) | 381 | config); |
386 | goto err_clk_put; | 382 | if (status) { |
383 | dev_err(&pdev->dev, "Alarm interrupt IRQ%d already claimed\n", | ||
384 | irq); | ||
385 | return status; | ||
386 | } | ||
387 | 387 | ||
388 | config->ioaddr = ioremap(res->start, resource_size(res)); | 388 | config->ioaddr = devm_request_and_ioremap(&pdev->dev, res); |
389 | if (!config->ioaddr) { | 389 | if (!config->ioaddr) { |
390 | dev_err(&pdev->dev, "ioremap fail\n"); | 390 | dev_err(&pdev->dev, "request-ioremap fail\n"); |
391 | status = -ENOMEM; | 391 | return -ENOMEM; |
392 | goto err_disable_clock; | ||
393 | } | 392 | } |
394 | 393 | ||
394 | config->clk = devm_clk_get(&pdev->dev, NULL); | ||
395 | if (IS_ERR(config->clk)) | ||
396 | return PTR_ERR(config->clk); | ||
397 | |||
398 | status = clk_prepare_enable(config->clk); | ||
399 | if (status < 0) | ||
400 | return status; | ||
401 | |||
395 | spin_lock_init(&config->lock); | 402 | spin_lock_init(&config->lock); |
396 | platform_set_drvdata(pdev, config); | 403 | platform_set_drvdata(pdev, config); |
397 | 404 | ||
@@ -401,42 +408,19 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) | |||
401 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", | 408 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", |
402 | PTR_ERR(config->rtc)); | 409 | PTR_ERR(config->rtc)); |
403 | status = PTR_ERR(config->rtc); | 410 | status = PTR_ERR(config->rtc); |
404 | goto err_iounmap; | 411 | goto err_disable_clock; |
405 | } | ||
406 | |||
407 | /* alarm irqs */ | ||
408 | irq = platform_get_irq(pdev, 0); | ||
409 | if (irq < 0) { | ||
410 | dev_err(&pdev->dev, "no update irq?\n"); | ||
411 | status = irq; | ||
412 | goto err_clear_platdata; | ||
413 | } | 412 | } |
414 | 413 | ||
415 | status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config); | 414 | config->rtc->uie_unsupported = 1; |
416 | if (status) { | ||
417 | dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \ | ||
418 | claimed\n", irq); | ||
419 | goto err_clear_platdata; | ||
420 | } | ||
421 | 415 | ||
422 | if (!device_can_wakeup(&pdev->dev)) | 416 | if (!device_can_wakeup(&pdev->dev)) |
423 | device_init_wakeup(&pdev->dev, 1); | 417 | device_init_wakeup(&pdev->dev, 1); |
424 | 418 | ||
425 | return 0; | 419 | return 0; |
426 | 420 | ||
427 | err_clear_platdata: | ||
428 | platform_set_drvdata(pdev, NULL); | ||
429 | rtc_device_unregister(config->rtc); | ||
430 | err_iounmap: | ||
431 | iounmap(config->ioaddr); | ||
432 | err_disable_clock: | 421 | err_disable_clock: |
433 | clk_disable(config->clk); | 422 | platform_set_drvdata(pdev, NULL); |
434 | err_clk_put: | 423 | clk_disable_unprepare(config->clk); |
435 | clk_put(config->clk); | ||
436 | err_kfree: | ||
437 | kfree(config); | ||
438 | err_release_region: | ||
439 | release_mem_region(res->start, resource_size(res)); | ||
440 | 424 | ||
441 | return status; | 425 | return status; |
442 | } | 426 | } |
@@ -444,24 +428,11 @@ err_release_region: | |||
444 | static int __devexit spear_rtc_remove(struct platform_device *pdev) | 428 | static int __devexit spear_rtc_remove(struct platform_device *pdev) |
445 | { | 429 | { |
446 | struct spear_rtc_config *config = platform_get_drvdata(pdev); | 430 | struct spear_rtc_config *config = platform_get_drvdata(pdev); |
447 | int irq; | ||
448 | struct resource *res; | ||
449 | 431 | ||
450 | /* leave rtc running, but disable irqs */ | 432 | rtc_device_unregister(config->rtc); |
451 | spear_rtc_disable_interrupt(config); | 433 | spear_rtc_disable_interrupt(config); |
434 | clk_disable_unprepare(config->clk); | ||
452 | device_init_wakeup(&pdev->dev, 0); | 435 | device_init_wakeup(&pdev->dev, 0); |
453 | irq = platform_get_irq(pdev, 0); | ||
454 | if (irq) | ||
455 | free_irq(irq, pdev); | ||
456 | clk_disable(config->clk); | ||
457 | clk_put(config->clk); | ||
458 | iounmap(config->ioaddr); | ||
459 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
460 | if (res) | ||
461 | release_mem_region(res->start, resource_size(res)); | ||
462 | platform_set_drvdata(pdev, NULL); | ||
463 | rtc_device_unregister(config->rtc); | ||
464 | kfree(config); | ||
465 | 436 | ||
466 | return 0; | 437 | return 0; |
467 | } | 438 | } |
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 7e96254bd365..974b9ae252ab 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -152,24 +152,24 @@ static int __init test_init(void) | |||
152 | 152 | ||
153 | if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) { | 153 | if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) { |
154 | err = -ENOMEM; | 154 | err = -ENOMEM; |
155 | goto exit_free_test0; | 155 | goto exit_put_test0; |
156 | } | 156 | } |
157 | 157 | ||
158 | if ((err = platform_device_add(test0))) | 158 | if ((err = platform_device_add(test0))) |
159 | goto exit_free_test1; | 159 | goto exit_put_test1; |
160 | 160 | ||
161 | if ((err = platform_device_add(test1))) | 161 | if ((err = platform_device_add(test1))) |
162 | goto exit_device_unregister; | 162 | goto exit_del_test0; |
163 | 163 | ||
164 | return 0; | 164 | return 0; |
165 | 165 | ||
166 | exit_device_unregister: | 166 | exit_del_test0: |
167 | platform_device_unregister(test0); | 167 | platform_device_del(test0); |
168 | 168 | ||
169 | exit_free_test1: | 169 | exit_put_test1: |
170 | platform_device_put(test1); | 170 | platform_device_put(test1); |
171 | 171 | ||
172 | exit_free_test0: | 172 | exit_put_test0: |
173 | platform_device_put(test0); | 173 | platform_device_put(test0); |
174 | 174 | ||
175 | exit_driver_unregister: | 175 | exit_driver_unregister: |
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index 073108dcf9e7..22eb4ebfa1a6 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c | |||
@@ -247,6 +247,13 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev) | |||
247 | return ret; | 247 | return ret; |
248 | 248 | ||
249 | dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n"); | 249 | dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n"); |
250 | |||
251 | /* Enable RTC digital power domain */ | ||
252 | ret = regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL, | ||
253 | DEVCTRL_RTC_PWDN_MASK, 0 << DEVCTRL_RTC_PWDN_SHIFT); | ||
254 | if (ret < 0) | ||
255 | return ret; | ||
256 | |||
250 | rtc_reg = TPS65910_RTC_CTRL_STOP_RTC; | 257 | rtc_reg = TPS65910_RTC_CTRL_STOP_RTC; |
251 | ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg); | 258 | ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg); |
252 | if (ret < 0) | 259 | if (ret < 0) |
@@ -261,7 +268,7 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev) | |||
261 | 268 | ||
262 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 269 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
263 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW, | 270 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW, |
264 | "rtc-tps65910", &pdev->dev); | 271 | dev_name(&pdev->dev), &pdev->dev); |
265 | if (ret < 0) { | 272 | if (ret < 0) { |
266 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 273 | dev_err(&pdev->dev, "IRQ is not free.\n"); |
267 | return ret; | 274 | return ret; |
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 9277d945bf48..8b7464c8b5cf 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
@@ -233,7 +233,7 @@ static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | |||
233 | */ | 233 | */ |
234 | static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) | 234 | static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) |
235 | { | 235 | { |
236 | unsigned char rtc_data[ALL_TIME_REGS + 1]; | 236 | unsigned char rtc_data[ALL_TIME_REGS]; |
237 | int ret; | 237 | int ret; |
238 | u8 save_control; | 238 | u8 save_control; |
239 | u8 rtc_control; | 239 | u8 rtc_control; |
@@ -300,15 +300,15 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
300 | static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm) | 300 | static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm) |
301 | { | 301 | { |
302 | unsigned char save_control; | 302 | unsigned char save_control; |
303 | unsigned char rtc_data[ALL_TIME_REGS + 1]; | 303 | unsigned char rtc_data[ALL_TIME_REGS]; |
304 | int ret; | 304 | int ret; |
305 | 305 | ||
306 | rtc_data[1] = bin2bcd(tm->tm_sec); | 306 | rtc_data[0] = bin2bcd(tm->tm_sec); |
307 | rtc_data[2] = bin2bcd(tm->tm_min); | 307 | rtc_data[1] = bin2bcd(tm->tm_min); |
308 | rtc_data[3] = bin2bcd(tm->tm_hour); | 308 | rtc_data[2] = bin2bcd(tm->tm_hour); |
309 | rtc_data[4] = bin2bcd(tm->tm_mday); | 309 | rtc_data[3] = bin2bcd(tm->tm_mday); |
310 | rtc_data[5] = bin2bcd(tm->tm_mon + 1); | 310 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); |
311 | rtc_data[6] = bin2bcd(tm->tm_year - 100); | 311 | rtc_data[5] = bin2bcd(tm->tm_year - 100); |
312 | 312 | ||
313 | /* Stop RTC while updating the TC registers */ | 313 | /* Stop RTC while updating the TC registers */ |
314 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); | 314 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); |
@@ -341,7 +341,7 @@ out: | |||
341 | */ | 341 | */ |
342 | static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | 342 | static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
343 | { | 343 | { |
344 | unsigned char rtc_data[ALL_TIME_REGS + 1]; | 344 | unsigned char rtc_data[ALL_TIME_REGS]; |
345 | int ret; | 345 | int ret; |
346 | 346 | ||
347 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, | 347 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, |
@@ -368,19 +368,19 @@ static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
368 | 368 | ||
369 | static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | 369 | static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
370 | { | 370 | { |
371 | unsigned char alarm_data[ALL_TIME_REGS + 1]; | 371 | unsigned char alarm_data[ALL_TIME_REGS]; |
372 | int ret; | 372 | int ret; |
373 | 373 | ||
374 | ret = twl_rtc_alarm_irq_enable(dev, 0); | 374 | ret = twl_rtc_alarm_irq_enable(dev, 0); |
375 | if (ret) | 375 | if (ret) |
376 | goto out; | 376 | goto out; |
377 | 377 | ||
378 | alarm_data[1] = bin2bcd(alm->time.tm_sec); | 378 | alarm_data[0] = bin2bcd(alm->time.tm_sec); |
379 | alarm_data[2] = bin2bcd(alm->time.tm_min); | 379 | alarm_data[1] = bin2bcd(alm->time.tm_min); |
380 | alarm_data[3] = bin2bcd(alm->time.tm_hour); | 380 | alarm_data[2] = bin2bcd(alm->time.tm_hour); |
381 | alarm_data[4] = bin2bcd(alm->time.tm_mday); | 381 | alarm_data[3] = bin2bcd(alm->time.tm_mday); |
382 | alarm_data[5] = bin2bcd(alm->time.tm_mon + 1); | 382 | alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); |
383 | alarm_data[6] = bin2bcd(alm->time.tm_year - 100); | 383 | alarm_data[5] = bin2bcd(alm->time.tm_year - 100); |
384 | 384 | ||
385 | /* update all the alarm registers in one shot */ | 385 | /* update all the alarm registers in one shot */ |
386 | ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data, | 386 | ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data, |
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 07bf19364a74..14e2d8cfcc83 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -210,7 +210,8 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | |||
210 | struct vt8500_rtc *vt8500_rtc; | 210 | struct vt8500_rtc *vt8500_rtc; |
211 | int ret; | 211 | int ret; |
212 | 212 | ||
213 | vt8500_rtc = kzalloc(sizeof(struct vt8500_rtc), GFP_KERNEL); | 213 | vt8500_rtc = devm_kzalloc(&pdev->dev, |
214 | sizeof(struct vt8500_rtc), GFP_KERNEL); | ||
214 | if (!vt8500_rtc) | 215 | if (!vt8500_rtc) |
215 | return -ENOMEM; | 216 | return -ENOMEM; |
216 | 217 | ||
@@ -220,15 +221,13 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | |||
220 | vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 221 | vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
221 | if (!vt8500_rtc->res) { | 222 | if (!vt8500_rtc->res) { |
222 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); | 223 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); |
223 | ret = -ENXIO; | 224 | return -ENXIO; |
224 | goto err_free; | ||
225 | } | 225 | } |
226 | 226 | ||
227 | vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0); | 227 | vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0); |
228 | if (vt8500_rtc->irq_alarm < 0) { | 228 | if (vt8500_rtc->irq_alarm < 0) { |
229 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); | 229 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); |
230 | ret = -ENXIO; | 230 | return -ENXIO; |
231 | goto err_free; | ||
232 | } | 231 | } |
233 | 232 | ||
234 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, | 233 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, |
@@ -236,8 +235,7 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | |||
236 | "vt8500-rtc"); | 235 | "vt8500-rtc"); |
237 | if (vt8500_rtc->res == NULL) { | 236 | if (vt8500_rtc->res == NULL) { |
238 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 237 | dev_err(&pdev->dev, "failed to request I/O memory\n"); |
239 | ret = -EBUSY; | 238 | return -EBUSY; |
240 | goto err_free; | ||
241 | } | 239 | } |
242 | 240 | ||
243 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, | 241 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, |
@@ -278,8 +276,6 @@ err_unmap: | |||
278 | err_release: | 276 | err_release: |
279 | release_mem_region(vt8500_rtc->res->start, | 277 | release_mem_region(vt8500_rtc->res->start, |
280 | resource_size(vt8500_rtc->res)); | 278 | resource_size(vt8500_rtc->res)); |
281 | err_free: | ||
282 | kfree(vt8500_rtc); | ||
283 | return ret; | 279 | return ret; |
284 | } | 280 | } |
285 | 281 | ||
@@ -297,7 +293,6 @@ static int __devexit vt8500_rtc_remove(struct platform_device *pdev) | |||
297 | release_mem_region(vt8500_rtc->res->start, | 293 | release_mem_region(vt8500_rtc->res->start, |
298 | resource_size(vt8500_rtc->res)); | 294 | resource_size(vt8500_rtc->res)); |
299 | 295 | ||
300 | kfree(vt8500_rtc); | ||
301 | platform_set_drvdata(pdev, NULL); | 296 | platform_set_drvdata(pdev, NULL); |
302 | 297 | ||
303 | return 0; | 298 | return 0; |