diff options
Diffstat (limited to 'drivers/rtc')
43 files changed, 1573 insertions, 730 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 9e7de63b26ef..fc85bf2e4a97 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -20,10 +20,6 @@ menuconfig RTC_CLASS | |||
20 | 20 | ||
21 | if RTC_CLASS | 21 | if RTC_CLASS |
22 | 22 | ||
23 | if GEN_RTC || RTC | ||
24 | comment "Conflicting RTC option has been selected, check GEN_RTC and RTC" | ||
25 | endif | ||
26 | |||
27 | config RTC_HCTOSYS | 23 | config RTC_HCTOSYS |
28 | bool "Set system time from RTC on startup and resume" | 24 | bool "Set system time from RTC on startup and resume" |
29 | depends on RTC_CLASS = y | 25 | depends on RTC_CLASS = y |
@@ -252,6 +248,7 @@ config RTC_DRV_TWL92330 | |||
252 | 248 | ||
253 | config RTC_DRV_S35390A | 249 | config RTC_DRV_S35390A |
254 | tristate "Seiko Instruments S-35390A" | 250 | tristate "Seiko Instruments S-35390A" |
251 | select BITREVERSE | ||
255 | help | 252 | help |
256 | If you say yes here you will get support for the Seiko | 253 | If you say yes here you will get support for the Seiko |
257 | Instruments S-35390A. | 254 | Instruments S-35390A. |
@@ -259,6 +256,17 @@ config RTC_DRV_S35390A | |||
259 | This driver can also be built as a module. If so the module | 256 | This driver can also be built as a module. If so the module |
260 | will be called rtc-s35390a. | 257 | will be called rtc-s35390a. |
261 | 258 | ||
259 | config RTC_DRV_FM3130 | ||
260 | tristate "Ramtron FM3130" | ||
261 | help | ||
262 | If you say Y here you will get support for the | ||
263 | Ramtron FM3130 RTC chips. | ||
264 | Ramtron FM3130 is a chip with two separate devices inside, | ||
265 | RTC clock and FRAM. This driver provides only RTC functionality. | ||
266 | |||
267 | This driver can also be built as a module. If so the module | ||
268 | will be called rtc-fm3130. | ||
269 | |||
262 | endif # I2C | 270 | endif # I2C |
263 | 271 | ||
264 | comment "SPI RTC drivers" | 272 | comment "SPI RTC drivers" |
@@ -303,6 +311,7 @@ comment "Platform RTC drivers" | |||
303 | config RTC_DRV_CMOS | 311 | config RTC_DRV_CMOS |
304 | tristate "PC-style 'CMOS'" | 312 | tristate "PC-style 'CMOS'" |
305 | depends on X86 || ALPHA || ARM || M32R || ATARI || PPC || MIPS | 313 | depends on X86 || ALPHA || ARM || M32R || ATARI || PPC || MIPS |
314 | default y if X86 | ||
306 | help | 315 | help |
307 | Say "yes" here to get direct support for the real time clock | 316 | Say "yes" here to get direct support for the real time clock |
308 | found in every PC or ACPI-based system, and some other boards. | 317 | found in every PC or ACPI-based system, and some other boards. |
@@ -460,6 +469,16 @@ config RTC_DRV_VR41XX | |||
460 | To compile this driver as a module, choose M here: the | 469 | To compile this driver as a module, choose M here: the |
461 | module will be called rtc-vr41xx. | 470 | module will be called rtc-vr41xx. |
462 | 471 | ||
472 | config RTC_DRV_PL030 | ||
473 | tristate "ARM AMBA PL030 RTC" | ||
474 | depends on ARM_AMBA | ||
475 | help | ||
476 | If you say Y here you will get access to ARM AMBA | ||
477 | PrimeCell PL030 RTC found on certain ARM SOCs. | ||
478 | |||
479 | To compile this driver as a module, choose M here: the | ||
480 | module will be called rtc-pl030. | ||
481 | |||
463 | config RTC_DRV_PL031 | 482 | config RTC_DRV_PL031 |
464 | tristate "ARM AMBA PL031 RTC" | 483 | tristate "ARM AMBA PL031 RTC" |
465 | depends on ARM_AMBA | 484 | depends on ARM_AMBA |
@@ -486,12 +505,13 @@ config RTC_DRV_AT91RM9200 | |||
486 | this is powered by the backup power supply. | 505 | this is powered by the backup power supply. |
487 | 506 | ||
488 | config RTC_DRV_AT91SAM9 | 507 | config RTC_DRV_AT91SAM9 |
489 | tristate "AT91SAM9x" | 508 | tristate "AT91SAM9x/AT91CAP9" |
490 | depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) | 509 | depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) |
491 | help | 510 | help |
492 | RTC driver for the Atmel AT91SAM9x internal RTT (Real Time Timer). | 511 | RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT |
493 | These timers are powered by the backup power supply (such as a | 512 | (Real Time Timer). These timers are powered by the backup power |
494 | small coin cell battery), but do not need to be used as RTCs. | 513 | supply (such as a small coin cell battery), but do not need to |
514 | be used as RTCs. | ||
495 | 515 | ||
496 | (On AT91SAM9rl chips you probably want to use the dedicated RTC | 516 | (On AT91SAM9rl chips you probably want to use the dedicated RTC |
497 | module and leave the RTT available for other uses.) | 517 | module and leave the RTT available for other uses.) |
@@ -536,4 +556,12 @@ config RTC_DRV_RS5C313 | |||
536 | help | 556 | help |
537 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. | 557 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. |
538 | 558 | ||
559 | config RTC_DRV_PPC | ||
560 | tristate "PowerPC machine dependent RTC support" | ||
561 | depends on PPC_MERGE | ||
562 | help | ||
563 | The PowerPC kernel has machine-specific functions for accessing | ||
564 | the RTC. This exposes that functionality through the generic RTC | ||
565 | class. | ||
566 | |||
539 | endif # RTC_CLASS | 567 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 872f1218ff9f..b5d9d67df887 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | |||
31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
34 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | ||
34 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 35 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
35 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 36 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
36 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 37 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
@@ -40,7 +41,9 @@ obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | |||
40 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 41 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o |
41 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 42 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
42 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 43 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
44 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o | ||
43 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 45 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
46 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | ||
44 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 47 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 48 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 49 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index d3b9b14267ab..2ef8cdfda4a7 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c | |||
@@ -94,8 +94,11 @@ static int at32_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
94 | { | 94 | { |
95 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | 95 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); |
96 | 96 | ||
97 | spin_lock_irq(&rtc->lock); | ||
97 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); | 98 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); |
98 | alrm->pending = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; | 99 | alrm->enabled = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; |
100 | alrm->pending = rtc_readl(rtc, ISR) & RTC_BIT(ISR_TOPI) ? 1 : 0; | ||
101 | spin_unlock_irq(&rtc->lock); | ||
99 | 102 | ||
100 | return 0; | 103 | return 0; |
101 | } | 104 | } |
@@ -119,7 +122,7 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
119 | spin_lock_irq(&rtc->lock); | 122 | spin_lock_irq(&rtc->lock); |
120 | rtc->alarm_time = alarm_unix_time; | 123 | rtc->alarm_time = alarm_unix_time; |
121 | rtc_writel(rtc, TOP, rtc->alarm_time); | 124 | rtc_writel(rtc, TOP, rtc->alarm_time); |
122 | if (alrm->pending) | 125 | if (alrm->enabled) |
123 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | 126 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) |
124 | | RTC_BIT(CTRL_TOPEN)); | 127 | | RTC_BIT(CTRL_TOPEN)); |
125 | else | 128 | else |
@@ -290,7 +293,7 @@ static int __exit at32_rtc_remove(struct platform_device *pdev) | |||
290 | return 0; | 293 | return 0; |
291 | } | 294 | } |
292 | 295 | ||
293 | MODULE_ALIAS("at32ap700x_rtc"); | 296 | MODULE_ALIAS("platform:at32ap700x_rtc"); |
294 | 297 | ||
295 | static struct platform_driver at32_rtc_driver = { | 298 | static struct platform_driver at32_rtc_driver = { |
296 | .remove = __exit_p(at32_rtc_remove), | 299 | .remove = __exit_p(at32_rtc_remove), |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 33795e5a5595..9c3db934cc24 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -29,10 +29,6 @@ | |||
29 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
30 | 30 | ||
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | #include <asm/rtc.h> | ||
33 | |||
34 | #include <asm/mach/time.h> | ||
35 | |||
36 | #include <asm/arch/at91_rtc.h> | 32 | #include <asm/arch/at91_rtc.h> |
37 | 33 | ||
38 | 34 | ||
@@ -83,7 +79,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) | |||
83 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | 79 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); |
84 | tm->tm_year = tm->tm_year - 1900; | 80 | tm->tm_year = tm->tm_year - 1900; |
85 | 81 | ||
86 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | 82 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
87 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 83 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
88 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 84 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
89 | 85 | ||
@@ -97,7 +93,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
97 | { | 93 | { |
98 | unsigned long cr; | 94 | unsigned long cr; |
99 | 95 | ||
100 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | 96 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
101 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 97 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
102 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 98 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
103 | 99 | ||
@@ -142,7 +138,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
142 | alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM) | 138 | alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM) |
143 | ? 1 : 0; | 139 | ? 1 : 0; |
144 | 140 | ||
145 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | 141 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
146 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 142 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
147 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 143 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
148 | 144 | ||
@@ -178,7 +174,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
178 | if (alrm->enabled) | 174 | if (alrm->enabled) |
179 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); | 175 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); |
180 | 176 | ||
181 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | 177 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
182 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 178 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, |
183 | tm.tm_min, tm.tm_sec); | 179 | tm.tm_min, tm.tm_sec); |
184 | 180 | ||
@@ -193,7 +189,7 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
193 | { | 189 | { |
194 | int ret = 0; | 190 | int ret = 0; |
195 | 191 | ||
196 | pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __FUNCTION__, cmd, arg); | 192 | pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); |
197 | 193 | ||
198 | switch (cmd) { | 194 | switch (cmd) { |
199 | case RTC_AIE_OFF: /* alarm off */ | 195 | case RTC_AIE_OFF: /* alarm off */ |
@@ -265,7 +261,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
265 | 261 | ||
266 | rtc_update_irq(rtc, 1, events); | 262 | rtc_update_irq(rtc, 1, events); |
267 | 263 | ||
268 | pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__, | 264 | pr_debug("%s(): num=%ld, events=0x%02lx\n", __func__, |
269 | events >> 8, events & 0x000000FF); | 265 | events >> 8, events & 0x000000FF); |
270 | 266 | ||
271 | return IRQ_HANDLED; | 267 | return IRQ_HANDLED; |
@@ -407,3 +403,4 @@ module_exit(at91_rtc_exit); | |||
407 | MODULE_AUTHOR("Rick Bronson"); | 403 | MODULE_AUTHOR("Rick Bronson"); |
408 | MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200"); | 404 | MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200"); |
409 | MODULE_LICENSE("GPL"); | 405 | MODULE_LICENSE("GPL"); |
406 | MODULE_ALIAS("platform:at91_rtc"); | ||
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 56728a2a3385..f0246ef413a4 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/ioctl.h> | 20 | #include <linux/ioctl.h> |
21 | 21 | ||
22 | #include <asm/mach/time.h> | ||
23 | #include <asm/arch/board.h> | 22 | #include <asm/arch/board.h> |
24 | #include <asm/arch/at91_rtt.h> | 23 | #include <asm/arch/at91_rtt.h> |
25 | 24 | ||
@@ -288,7 +287,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | |||
288 | 287 | ||
289 | rtc_update_irq(rtc->rtcdev, 1, events); | 288 | rtc_update_irq(rtc->rtcdev, 1, events); |
290 | 289 | ||
291 | pr_debug("%s: num=%ld, events=0x%02lx\n", __FUNCTION__, | 290 | pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, |
292 | events >> 8, events & 0x000000FF); | 291 | events >> 8, events & 0x000000FF); |
293 | 292 | ||
294 | return IRQ_HANDLED; | 293 | return IRQ_HANDLED; |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index d90ba860d216..8624f55d0560 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -419,7 +419,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
419 | return -ENOMEM; | 419 | return -ENOMEM; |
420 | 420 | ||
421 | rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); | 421 | rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); |
422 | if (unlikely(IS_ERR(rtc))) { | 422 | if (IS_ERR(rtc)) { |
423 | ret = PTR_ERR(rtc->rtc_dev); | 423 | ret = PTR_ERR(rtc->rtc_dev); |
424 | goto err; | 424 | goto err; |
425 | } | 425 | } |
@@ -470,3 +470,4 @@ module_exit(bfin_rtc_exit); | |||
470 | MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); | 470 | MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); |
471 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); | 471 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); |
472 | MODULE_LICENSE("GPL"); | 472 | MODULE_LICENSE("GPL"); |
473 | MODULE_ALIAS("platform:rtc-bfin"); | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index f3ee2ad566b4..d7bb9bac71df 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -198,9 +198,8 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
198 | 198 | ||
199 | /* Writing 0xff means "don't care" or "match all". */ | 199 | /* Writing 0xff means "don't care" or "match all". */ |
200 | 200 | ||
201 | mon = t->time.tm_mon; | 201 | mon = t->time.tm_mon + 1; |
202 | mon = (mon < 12) ? BIN2BCD(mon) : 0xff; | 202 | mon = (mon <= 12) ? BIN2BCD(mon) : 0xff; |
203 | mon++; | ||
204 | 203 | ||
205 | mday = t->time.tm_mday; | 204 | mday = t->time.tm_mday; |
206 | mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff; | 205 | mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff; |
@@ -855,11 +854,12 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) | |||
855 | * don't define the IRQ. It should always be safe to | 854 | * don't define the IRQ. It should always be safe to |
856 | * hardcode it in these cases | 855 | * hardcode it in these cases |
857 | */ | 856 | */ |
858 | return cmos_do_probe(&pnp->dev, &pnp->res.port_resource[0], 8); | 857 | return cmos_do_probe(&pnp->dev, |
858 | pnp_get_resource(pnp, IORESOURCE_IO, 0), 8); | ||
859 | else | 859 | else |
860 | return cmos_do_probe(&pnp->dev, | 860 | return cmos_do_probe(&pnp->dev, |
861 | &pnp->res.port_resource[0], | 861 | pnp_get_resource(pnp, IORESOURCE_IO, 0), |
862 | pnp->res.irq_resource[0].start); | 862 | pnp_irq(pnp, 0)); |
863 | } | 863 | } |
864 | 864 | ||
865 | static void __exit cmos_pnp_remove(struct pnp_dev *pnp) | 865 | static void __exit cmos_pnp_remove(struct pnp_dev *pnp) |
@@ -905,19 +905,7 @@ static struct pnp_driver cmos_pnp_driver = { | |||
905 | .resume = cmos_pnp_resume, | 905 | .resume = cmos_pnp_resume, |
906 | }; | 906 | }; |
907 | 907 | ||
908 | static int __init cmos_init(void) | 908 | #endif /* CONFIG_PNP */ |
909 | { | ||
910 | return pnp_register_driver(&cmos_pnp_driver); | ||
911 | } | ||
912 | module_init(cmos_init); | ||
913 | |||
914 | static void __exit cmos_exit(void) | ||
915 | { | ||
916 | pnp_unregister_driver(&cmos_pnp_driver); | ||
917 | } | ||
918 | module_exit(cmos_exit); | ||
919 | |||
920 | #else /* no PNP */ | ||
921 | 909 | ||
922 | /*----------------------------------------------------------------*/ | 910 | /*----------------------------------------------------------------*/ |
923 | 911 | ||
@@ -943,6 +931,9 @@ static void cmos_platform_shutdown(struct platform_device *pdev) | |||
943 | cmos_do_shutdown(); | 931 | cmos_do_shutdown(); |
944 | } | 932 | } |
945 | 933 | ||
934 | /* work with hotplug and coldplug */ | ||
935 | MODULE_ALIAS("platform:rtc_cmos"); | ||
936 | |||
946 | static struct platform_driver cmos_platform_driver = { | 937 | static struct platform_driver cmos_platform_driver = { |
947 | .remove = __exit_p(cmos_platform_remove), | 938 | .remove = __exit_p(cmos_platform_remove), |
948 | .shutdown = cmos_platform_shutdown, | 939 | .shutdown = cmos_platform_shutdown, |
@@ -955,20 +946,33 @@ static struct platform_driver cmos_platform_driver = { | |||
955 | 946 | ||
956 | static int __init cmos_init(void) | 947 | static int __init cmos_init(void) |
957 | { | 948 | { |
949 | #ifdef CONFIG_PNP | ||
950 | if (pnp_platform_devices) | ||
951 | return pnp_register_driver(&cmos_pnp_driver); | ||
952 | else | ||
953 | return platform_driver_probe(&cmos_platform_driver, | ||
954 | cmos_platform_probe); | ||
955 | #else | ||
958 | return platform_driver_probe(&cmos_platform_driver, | 956 | return platform_driver_probe(&cmos_platform_driver, |
959 | cmos_platform_probe); | 957 | cmos_platform_probe); |
958 | #endif /* CONFIG_PNP */ | ||
960 | } | 959 | } |
961 | module_init(cmos_init); | 960 | module_init(cmos_init); |
962 | 961 | ||
963 | static void __exit cmos_exit(void) | 962 | static void __exit cmos_exit(void) |
964 | { | 963 | { |
964 | #ifdef CONFIG_PNP | ||
965 | if (pnp_platform_devices) | ||
966 | pnp_unregister_driver(&cmos_pnp_driver); | ||
967 | else | ||
968 | platform_driver_unregister(&cmos_platform_driver); | ||
969 | #else | ||
965 | platform_driver_unregister(&cmos_platform_driver); | 970 | platform_driver_unregister(&cmos_platform_driver); |
971 | #endif /* CONFIG_PNP */ | ||
966 | } | 972 | } |
967 | module_exit(cmos_exit); | 973 | module_exit(cmos_exit); |
968 | 974 | ||
969 | 975 | ||
970 | #endif /* !PNP */ | ||
971 | |||
972 | MODULE_AUTHOR("David Brownell"); | 976 | MODULE_AUTHOR("David Brownell"); |
973 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); | 977 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); |
974 | MODULE_LICENSE("GPL"); | 978 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 83efb88f8f23..0b17770b032b 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c | |||
@@ -221,6 +221,7 @@ MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); | |||
221 | MODULE_DESCRIPTION("DS1216 RTC driver"); | 221 | MODULE_DESCRIPTION("DS1216 RTC driver"); |
222 | MODULE_LICENSE("GPL"); | 222 | MODULE_LICENSE("GPL"); |
223 | MODULE_VERSION(DRV_VERSION); | 223 | MODULE_VERSION(DRV_VERSION); |
224 | MODULE_ALIAS("platform:rtc-ds1216"); | ||
224 | 225 | ||
225 | module_init(ds1216_rtc_init); | 226 | module_init(ds1216_rtc_init); |
226 | module_exit(ds1216_rtc_exit); | 227 | module_exit(ds1216_rtc_exit); |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 7b002ceeaa7d..b9397818f73a 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -122,7 +122,7 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
122 | 122 | ||
123 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 123 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
124 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 124 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
125 | __FUNCTION__, | 125 | __func__, |
126 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 126 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
127 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); | 127 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); |
128 | 128 | ||
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f389a28720d2..bbf97e65202a 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -99,45 +99,38 @@ struct ds1307 { | |||
99 | }; | 99 | }; |
100 | 100 | ||
101 | struct chip_desc { | 101 | struct chip_desc { |
102 | char name[9]; | ||
103 | unsigned nvram56:1; | 102 | unsigned nvram56:1; |
104 | unsigned alarm:1; | 103 | unsigned alarm:1; |
105 | enum ds_type type; | ||
106 | }; | 104 | }; |
107 | 105 | ||
108 | static const struct chip_desc chips[] = { { | 106 | static const struct chip_desc chips[] = { |
109 | .name = "ds1307", | 107 | [ds_1307] = { |
110 | .type = ds_1307, | ||
111 | .nvram56 = 1, | 108 | .nvram56 = 1, |
112 | }, { | 109 | }, |
113 | .name = "ds1337", | 110 | [ds_1337] = { |
114 | .type = ds_1337, | ||
115 | .alarm = 1, | 111 | .alarm = 1, |
116 | }, { | 112 | }, |
117 | .name = "ds1338", | 113 | [ds_1338] = { |
118 | .type = ds_1338, | ||
119 | .nvram56 = 1, | 114 | .nvram56 = 1, |
120 | }, { | 115 | }, |
121 | .name = "ds1339", | 116 | [ds_1339] = { |
122 | .type = ds_1339, | ||
123 | .alarm = 1, | 117 | .alarm = 1, |
124 | }, { | 118 | }, |
125 | .name = "ds1340", | 119 | [ds_1340] = { |
126 | .type = ds_1340, | 120 | }, |
127 | }, { | 121 | [m41t00] = { |
128 | .name = "m41t00", | ||
129 | .type = m41t00, | ||
130 | }, }; | 122 | }, }; |
131 | 123 | ||
132 | static inline const struct chip_desc *find_chip(const char *s) | 124 | static const struct i2c_device_id ds1307_id[] = { |
133 | { | 125 | { "ds1307", ds_1307 }, |
134 | unsigned i; | 126 | { "ds1337", ds_1337 }, |
135 | 127 | { "ds1338", ds_1338 }, | |
136 | for (i = 0; i < ARRAY_SIZE(chips); i++) | 128 | { "ds1339", ds_1339 }, |
137 | if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0) | 129 | { "ds1340", ds_1340 }, |
138 | return &chips[i]; | 130 | { "m41t00", m41t00 }, |
139 | return NULL; | 131 | { } |
140 | } | 132 | }; |
133 | MODULE_DEVICE_TABLE(i2c, ds1307_id); | ||
141 | 134 | ||
142 | static int ds1307_get_time(struct device *dev, struct rtc_time *t) | 135 | static int ds1307_get_time(struct device *dev, struct rtc_time *t) |
143 | { | 136 | { |
@@ -326,21 +319,15 @@ static struct bin_attribute nvram = { | |||
326 | 319 | ||
327 | static struct i2c_driver ds1307_driver; | 320 | static struct i2c_driver ds1307_driver; |
328 | 321 | ||
329 | static int __devinit ds1307_probe(struct i2c_client *client) | 322 | static int __devinit ds1307_probe(struct i2c_client *client, |
323 | const struct i2c_device_id *id) | ||
330 | { | 324 | { |
331 | struct ds1307 *ds1307; | 325 | struct ds1307 *ds1307; |
332 | int err = -ENODEV; | 326 | int err = -ENODEV; |
333 | int tmp; | 327 | int tmp; |
334 | const struct chip_desc *chip; | 328 | const struct chip_desc *chip = &chips[id->driver_data]; |
335 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 329 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
336 | 330 | ||
337 | chip = find_chip(client->name); | ||
338 | if (!chip) { | ||
339 | dev_err(&client->dev, "unknown chip type '%s'\n", | ||
340 | client->name); | ||
341 | return -ENODEV; | ||
342 | } | ||
343 | |||
344 | if (!i2c_check_functionality(adapter, | 331 | if (!i2c_check_functionality(adapter, |
345 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 332 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) |
346 | return -EIO; | 333 | return -EIO; |
@@ -361,7 +348,7 @@ static int __devinit ds1307_probe(struct i2c_client *client) | |||
361 | ds1307->msg[1].len = sizeof(ds1307->regs); | 348 | ds1307->msg[1].len = sizeof(ds1307->regs); |
362 | ds1307->msg[1].buf = ds1307->regs; | 349 | ds1307->msg[1].buf = ds1307->regs; |
363 | 350 | ||
364 | ds1307->type = chip->type; | 351 | ds1307->type = id->driver_data; |
365 | 352 | ||
366 | switch (ds1307->type) { | 353 | switch (ds1307->type) { |
367 | case ds_1337: | 354 | case ds_1337: |
@@ -550,6 +537,7 @@ static struct i2c_driver ds1307_driver = { | |||
550 | }, | 537 | }, |
551 | .probe = ds1307_probe, | 538 | .probe = ds1307_probe, |
552 | .remove = __devexit_p(ds1307_remove), | 539 | .remove = __devexit_p(ds1307_remove), |
540 | .id_table = ds1307_id, | ||
553 | }; | 541 | }; |
554 | 542 | ||
555 | static int __init ds1307_init(void) | 543 | static int __init ds1307_init(void) |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 45bda186befc..640acd20fdde 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -41,6 +41,12 @@ | |||
41 | #define DS1374_REG_SR_AF 0x01 /* Alarm Flag */ | 41 | #define DS1374_REG_SR_AF 0x01 /* Alarm Flag */ |
42 | #define DS1374_REG_TCR 0x09 /* Trickle Charge */ | 42 | #define DS1374_REG_TCR 0x09 /* Trickle Charge */ |
43 | 43 | ||
44 | static const struct i2c_device_id ds1374_id[] = { | ||
45 | { "ds1374", 0 }, | ||
46 | { } | ||
47 | }; | ||
48 | MODULE_DEVICE_TABLE(i2c, ds1374_id); | ||
49 | |||
44 | struct ds1374 { | 50 | struct ds1374 { |
45 | struct i2c_client *client; | 51 | struct i2c_client *client; |
46 | struct rtc_device *rtc; | 52 | struct rtc_device *rtc; |
@@ -355,7 +361,8 @@ static const struct rtc_class_ops ds1374_rtc_ops = { | |||
355 | .ioctl = ds1374_ioctl, | 361 | .ioctl = ds1374_ioctl, |
356 | }; | 362 | }; |
357 | 363 | ||
358 | static int ds1374_probe(struct i2c_client *client) | 364 | static int ds1374_probe(struct i2c_client *client, |
365 | const struct i2c_device_id *id) | ||
359 | { | 366 | { |
360 | struct ds1374 *ds1374; | 367 | struct ds1374 *ds1374; |
361 | int ret; | 368 | int ret; |
@@ -429,6 +436,7 @@ static struct i2c_driver ds1374_driver = { | |||
429 | }, | 436 | }, |
430 | .probe = ds1374_probe, | 437 | .probe = ds1374_probe, |
431 | .remove = __devexit_p(ds1374_remove), | 438 | .remove = __devexit_p(ds1374_remove), |
439 | .id_table = ds1374_id, | ||
432 | }; | 440 | }; |
433 | 441 | ||
434 | static int __init ds1374_init(void) | 442 | static int __init ds1374_init(void) |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index d74b8086fa31..0f0d27d1c4ca 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -181,11 +181,10 @@ ds1511_wdog_disable(void) | |||
181 | * stupidly, some callers call with year unmolested; | 181 | * stupidly, some callers call with year unmolested; |
182 | * and some call with year = year - 1900. thanks. | 182 | * and some call with year = year - 1900. thanks. |
183 | */ | 183 | */ |
184 | int | 184 | static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) |
185 | ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | ||
186 | { | 185 | { |
187 | u8 mon, day, dow, hrs, min, sec, yrs, cen; | 186 | u8 mon, day, dow, hrs, min, sec, yrs, cen; |
188 | unsigned int flags; | 187 | unsigned long flags; |
189 | 188 | ||
190 | /* | 189 | /* |
191 | * won't have to change this for a while | 190 | * won't have to change this for a while |
@@ -245,11 +244,10 @@ ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | |||
245 | return 0; | 244 | return 0; |
246 | } | 245 | } |
247 | 246 | ||
248 | int | 247 | static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) |
249 | ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | ||
250 | { | 248 | { |
251 | unsigned int century; | 249 | unsigned int century; |
252 | unsigned int flags; | 250 | unsigned long flags; |
253 | 251 | ||
254 | spin_lock_irqsave(&ds1511_lock, flags); | 252 | spin_lock_irqsave(&ds1511_lock, flags); |
255 | rtc_disable_update(); | 253 | rtc_disable_update(); |
@@ -626,6 +624,9 @@ ds1511_rtc_remove(struct platform_device *pdev) | |||
626 | return 0; | 624 | return 0; |
627 | } | 625 | } |
628 | 626 | ||
627 | /* work with hotplug and coldplug */ | ||
628 | MODULE_ALIAS("platform:ds1511"); | ||
629 | |||
629 | static struct platform_driver ds1511_rtc_driver = { | 630 | static struct platform_driver ds1511_rtc_driver = { |
630 | .probe = ds1511_rtc_probe, | 631 | .probe = ds1511_rtc_probe, |
631 | .remove = __devexit_p(ds1511_rtc_remove), | 632 | .remove = __devexit_p(ds1511_rtc_remove), |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index d9e848dcd450..a19f11415540 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -391,6 +391,9 @@ static int __devexit ds1553_rtc_remove(struct platform_device *pdev) | |||
391 | return 0; | 391 | return 0; |
392 | } | 392 | } |
393 | 393 | ||
394 | /* work with hotplug and coldplug */ | ||
395 | MODULE_ALIAS("platform:rtc-ds1553"); | ||
396 | |||
394 | static struct platform_driver ds1553_rtc_driver = { | 397 | static struct platform_driver ds1553_rtc_driver = { |
395 | .probe = ds1553_rtc_probe, | 398 | .probe = ds1553_rtc_probe, |
396 | .remove = __devexit_p(ds1553_rtc_remove), | 399 | .remove = __devexit_p(ds1553_rtc_remove), |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index e0900ca678ec..6fa4556f5f5c 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -50,13 +50,13 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
50 | 50 | ||
51 | /* read date registers */ | 51 | /* read date registers */ |
52 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 52 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
53 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 53 | dev_err(&client->dev, "%s: read error\n", __func__); |
54 | return -EIO; | 54 | return -EIO; |
55 | } | 55 | } |
56 | 56 | ||
57 | dev_dbg(&client->dev, | 57 | dev_dbg(&client->dev, |
58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n", | 58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n", |
59 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); | 59 | __func__, buf[0], buf[1], buf[2], buf[3]); |
60 | 60 | ||
61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | 61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
62 | 62 | ||
@@ -64,7 +64,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
64 | 64 | ||
65 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 65 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
66 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 66 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
67 | __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, | 67 | __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, |
68 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 68 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
69 | 69 | ||
70 | return 0; | 70 | return 0; |
@@ -84,7 +84,7 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) | |||
84 | 84 | ||
85 | xfer = i2c_master_send(client, buf, 6); | 85 | xfer = i2c_master_send(client, buf, 6); |
86 | if (xfer != 6) { | 86 | if (xfer != 6) { |
87 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); | 87 | dev_err(&client->dev, "%s: send: %d\n", __func__, xfer); |
88 | return -EIO; | 88 | return -EIO; |
89 | } | 89 | } |
90 | 90 | ||
@@ -98,7 +98,7 @@ static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
98 | dev_dbg(&client->dev, | 98 | dev_dbg(&client->dev, |
99 | "%s: secs=%d, mins=%d, hours=%d, " | 99 | "%s: secs=%d, mins=%d, hours=%d, " |
100 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 100 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
101 | __FUNCTION__, | 101 | __func__, |
102 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 102 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
103 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 103 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
104 | 104 | ||
@@ -133,7 +133,7 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status) | |||
133 | 133 | ||
134 | /* read control register */ | 134 | /* read control register */ |
135 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 135 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
136 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 136 | dev_err(&client->dev, "%s: read error\n", __func__); |
137 | return -EIO; | 137 | return -EIO; |
138 | } | 138 | } |
139 | 139 | ||
@@ -199,7 +199,7 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | |||
199 | struct i2c_client *client; | 199 | struct i2c_client *client; |
200 | struct rtc_device *rtc; | 200 | struct rtc_device *rtc; |
201 | 201 | ||
202 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | 202 | dev_dbg(&adapter->dev, "%s\n", __func__); |
203 | 203 | ||
204 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { | 204 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { |
205 | err = -ENODEV; | 205 | err = -ENODEV; |
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 2e73f0b183b2..24d35ede2dbf 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -276,3 +276,4 @@ MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | |||
276 | MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); | 276 | MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); |
277 | MODULE_LICENSE("GPL"); | 277 | MODULE_LICENSE("GPL"); |
278 | MODULE_VERSION(DRV_VERSION); | 278 | MODULE_VERSION(DRV_VERSION); |
279 | MODULE_ALIAS("platform:rtc-ds1742"); | ||
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index ef4f147f3c0c..1e99325270df 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -132,6 +132,9 @@ static int __devexit ep93xx_rtc_remove(struct platform_device *dev) | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* work with hotplug and coldplug */ | ||
136 | MODULE_ALIAS("platform:ep93xx-rtc"); | ||
137 | |||
135 | static struct platform_driver ep93xx_rtc_platform_driver = { | 138 | static struct platform_driver ep93xx_rtc_platform_driver = { |
136 | .driver = { | 139 | .driver = { |
137 | .name = "ep93xx-rtc", | 140 | .name = "ep93xx-rtc", |
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c new file mode 100644 index 000000000000..11644c8fca82 --- /dev/null +++ b/drivers/rtc/rtc-fm3130.c | |||
@@ -0,0 +1,501 @@ | |||
1 | /* | ||
2 | * rtc-fm3130.c - RTC driver for Ramtron FM3130 I2C chip. | ||
3 | * | ||
4 | * Copyright (C) 2008 Sergey Lapin | ||
5 | * Based on ds1307 driver by James Chapman and David Brownell | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/rtc.h> | ||
15 | #include <linux/bcd.h> | ||
16 | |||
17 | #define FM3130_RTC_CONTROL (0x0) | ||
18 | #define FM3130_CAL_CONTROL (0x1) | ||
19 | #define FM3130_RTC_SECONDS (0x2) | ||
20 | #define FM3130_RTC_MINUTES (0x3) | ||
21 | #define FM3130_RTC_HOURS (0x4) | ||
22 | #define FM3130_RTC_DAY (0x5) | ||
23 | #define FM3130_RTC_DATE (0x6) | ||
24 | #define FM3130_RTC_MONTHS (0x7) | ||
25 | #define FM3130_RTC_YEARS (0x8) | ||
26 | |||
27 | #define FM3130_ALARM_SECONDS (0x9) | ||
28 | #define FM3130_ALARM_MINUTES (0xa) | ||
29 | #define FM3130_ALARM_HOURS (0xb) | ||
30 | #define FM3130_ALARM_DATE (0xc) | ||
31 | #define FM3130_ALARM_MONTHS (0xd) | ||
32 | #define FM3130_ALARM_WP_CONTROL (0xe) | ||
33 | |||
34 | #define FM3130_CAL_CONTROL_BIT_nOSCEN (1 << 7) /* Osciallator enabled */ | ||
35 | #define FM3130_RTC_CONTROL_BIT_LB (1 << 7) /* Low battery */ | ||
36 | #define FM3130_RTC_CONTROL_BIT_AF (1 << 6) /* Alarm flag */ | ||
37 | #define FM3130_RTC_CONTROL_BIT_CF (1 << 5) /* Century overflow */ | ||
38 | #define FM3130_RTC_CONTROL_BIT_POR (1 << 4) /* Power on reset */ | ||
39 | #define FM3130_RTC_CONTROL_BIT_AEN (1 << 3) /* Alarm enable */ | ||
40 | #define FM3130_RTC_CONTROL_BIT_CAL (1 << 2) /* Calibration mode */ | ||
41 | #define FM3130_RTC_CONTROL_BIT_WRITE (1 << 1) /* W=1 -> write mode W=0 normal */ | ||
42 | #define FM3130_RTC_CONTROL_BIT_READ (1 << 0) /* R=1 -> read mode R=0 normal */ | ||
43 | |||
44 | #define FM3130_CLOCK_REGS 7 | ||
45 | #define FM3130_ALARM_REGS 5 | ||
46 | |||
47 | struct fm3130 { | ||
48 | u8 reg_addr_time; | ||
49 | u8 reg_addr_alarm; | ||
50 | u8 regs[15]; | ||
51 | struct i2c_msg msg[4]; | ||
52 | struct i2c_client *client; | ||
53 | struct rtc_device *rtc; | ||
54 | int data_valid; | ||
55 | int alarm; | ||
56 | }; | ||
57 | static const struct i2c_device_id fm3130_id[] = { | ||
58 | { "fm3130-rtc", 0 }, | ||
59 | { } | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(i2c, fm3130_id); | ||
62 | |||
63 | #define FM3130_MODE_NORMAL 0 | ||
64 | #define FM3130_MODE_WRITE 1 | ||
65 | #define FM3130_MODE_READ 2 | ||
66 | |||
67 | static void fm3130_rtc_mode(struct device *dev, int mode) | ||
68 | { | ||
69 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
70 | |||
71 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
72 | i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); | ||
73 | switch (mode) { | ||
74 | case FM3130_MODE_NORMAL: | ||
75 | fm3130->regs[FM3130_RTC_CONTROL] &= | ||
76 | ~(FM3130_RTC_CONTROL_BIT_WRITE | | ||
77 | FM3130_RTC_CONTROL_BIT_READ); | ||
78 | break; | ||
79 | case FM3130_MODE_WRITE: | ||
80 | fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_WRITE; | ||
81 | break; | ||
82 | case FM3130_MODE_READ: | ||
83 | fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_READ; | ||
84 | break; | ||
85 | default: | ||
86 | dev_dbg(dev, "invalid mode %d\n", mode); | ||
87 | break; | ||
88 | } | ||
89 | /* Checking for alarm */ | ||
90 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
91 | fm3130->alarm = 1; | ||
92 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
93 | } | ||
94 | i2c_smbus_write_byte_data(fm3130->client, | ||
95 | FM3130_RTC_CONTROL, fm3130->regs[FM3130_RTC_CONTROL]); | ||
96 | } | ||
97 | |||
98 | static int fm3130_get_time(struct device *dev, struct rtc_time *t) | ||
99 | { | ||
100 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
101 | int tmp; | ||
102 | |||
103 | if (!fm3130->data_valid) { | ||
104 | /* We have invalid data in RTC, probably due | ||
105 | to battery faults or other problems. Return EIO | ||
106 | for now, it will allow us to set data later insted | ||
107 | of error during probing which disables device */ | ||
108 | return -EIO; | ||
109 | } | ||
110 | fm3130_rtc_mode(dev, FM3130_MODE_READ); | ||
111 | |||
112 | /* read the RTC date and time registers all at once */ | ||
113 | tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), | ||
114 | fm3130->msg, 2); | ||
115 | if (tmp != 2) { | ||
116 | dev_err(dev, "%s error %d\n", "read", tmp); | ||
117 | return -EIO; | ||
118 | } | ||
119 | |||
120 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | ||
121 | |||
122 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | ||
123 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
124 | "read", | ||
125 | fm3130->regs[0], fm3130->regs[1], | ||
126 | fm3130->regs[2], fm3130->regs[3], | ||
127 | fm3130->regs[4], fm3130->regs[5], | ||
128 | fm3130->regs[6], fm3130->regs[7], | ||
129 | fm3130->regs[8], fm3130->regs[9], | ||
130 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
131 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
132 | fm3130->regs[0xe]); | ||
133 | |||
134 | t->tm_sec = BCD2BIN(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | ||
135 | t->tm_min = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | ||
136 | tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f; | ||
137 | t->tm_hour = BCD2BIN(tmp); | ||
138 | t->tm_wday = BCD2BIN(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1; | ||
139 | t->tm_mday = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | ||
140 | tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f; | ||
141 | t->tm_mon = BCD2BIN(tmp) - 1; | ||
142 | |||
143 | /* assume 20YY not 19YY, and ignore CF bit */ | ||
144 | t->tm_year = BCD2BIN(fm3130->regs[FM3130_RTC_YEARS]) + 100; | ||
145 | |||
146 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
147 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
148 | "read", t->tm_sec, t->tm_min, | ||
149 | t->tm_hour, t->tm_mday, | ||
150 | t->tm_mon, t->tm_year, t->tm_wday); | ||
151 | |||
152 | /* initial clock setting can be undefined */ | ||
153 | return rtc_valid_tm(t); | ||
154 | } | ||
155 | |||
156 | |||
157 | static int fm3130_set_time(struct device *dev, struct rtc_time *t) | ||
158 | { | ||
159 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
160 | int tmp, i; | ||
161 | u8 *buf = fm3130->regs; | ||
162 | |||
163 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
164 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
165 | "write", t->tm_sec, t->tm_min, | ||
166 | t->tm_hour, t->tm_mday, | ||
167 | t->tm_mon, t->tm_year, t->tm_wday); | ||
168 | |||
169 | /* first register addr */ | ||
170 | buf[FM3130_RTC_SECONDS] = BIN2BCD(t->tm_sec); | ||
171 | buf[FM3130_RTC_MINUTES] = BIN2BCD(t->tm_min); | ||
172 | buf[FM3130_RTC_HOURS] = BIN2BCD(t->tm_hour); | ||
173 | buf[FM3130_RTC_DAY] = BIN2BCD(t->tm_wday + 1); | ||
174 | buf[FM3130_RTC_DATE] = BIN2BCD(t->tm_mday); | ||
175 | buf[FM3130_RTC_MONTHS] = BIN2BCD(t->tm_mon + 1); | ||
176 | |||
177 | /* assume 20YY not 19YY */ | ||
178 | tmp = t->tm_year - 100; | ||
179 | buf[FM3130_RTC_YEARS] = BIN2BCD(tmp); | ||
180 | |||
181 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" | ||
182 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
183 | "write", buf[0], buf[1], buf[2], buf[3], | ||
184 | buf[4], buf[5], buf[6], buf[7], | ||
185 | buf[8], buf[9], buf[0xa], buf[0xb], | ||
186 | buf[0xc], buf[0xd], buf[0xe]); | ||
187 | |||
188 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); | ||
189 | |||
190 | /* Writing time registers, we don't support multibyte transfers */ | ||
191 | for (i = 0; i < FM3130_CLOCK_REGS; i++) { | ||
192 | i2c_smbus_write_byte_data(fm3130->client, | ||
193 | FM3130_RTC_SECONDS + i, | ||
194 | fm3130->regs[FM3130_RTC_SECONDS + i]); | ||
195 | } | ||
196 | |||
197 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | ||
198 | |||
199 | /* We assume here that data are valid once written */ | ||
200 | if (!fm3130->data_valid) | ||
201 | fm3130->data_valid = 1; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
206 | { | ||
207 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
208 | int tmp; | ||
209 | struct rtc_time *tm = &alrm->time; | ||
210 | /* read the RTC alarm registers all at once */ | ||
211 | tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), | ||
212 | &fm3130->msg[2], 2); | ||
213 | if (tmp != 2) { | ||
214 | dev_err(dev, "%s error %d\n", "read", tmp); | ||
215 | return -EIO; | ||
216 | } | ||
217 | dev_dbg(dev, "alarm read %02x %02x %02x %02x %02x\n", | ||
218 | fm3130->regs[FM3130_ALARM_SECONDS], | ||
219 | fm3130->regs[FM3130_ALARM_MINUTES], | ||
220 | fm3130->regs[FM3130_ALARM_HOURS], | ||
221 | fm3130->regs[FM3130_ALARM_DATE], | ||
222 | fm3130->regs[FM3130_ALARM_MONTHS]); | ||
223 | |||
224 | |||
225 | tm->tm_sec = BCD2BIN(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F); | ||
226 | tm->tm_min = BCD2BIN(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F); | ||
227 | tm->tm_hour = BCD2BIN(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F); | ||
228 | tm->tm_mday = BCD2BIN(fm3130->regs[FM3130_ALARM_DATE] & 0x3F); | ||
229 | tm->tm_mon = BCD2BIN(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F); | ||
230 | if (tm->tm_mon > 0) | ||
231 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ | ||
232 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
233 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
234 | "read alarm", tm->tm_sec, tm->tm_min, | ||
235 | tm->tm_hour, tm->tm_mday, | ||
236 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
242 | { | ||
243 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
244 | struct rtc_time *tm = &alrm->time; | ||
245 | int i; | ||
246 | |||
247 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
248 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
249 | "write alarm", tm->tm_sec, tm->tm_min, | ||
250 | tm->tm_hour, tm->tm_mday, | ||
251 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
252 | |||
253 | if (tm->tm_sec != -1) | ||
254 | fm3130->regs[FM3130_ALARM_SECONDS] = | ||
255 | BIN2BCD(tm->tm_sec) | 0x80; | ||
256 | |||
257 | if (tm->tm_min != -1) | ||
258 | fm3130->regs[FM3130_ALARM_MINUTES] = | ||
259 | BIN2BCD(tm->tm_min) | 0x80; | ||
260 | |||
261 | if (tm->tm_hour != -1) | ||
262 | fm3130->regs[FM3130_ALARM_HOURS] = | ||
263 | BIN2BCD(tm->tm_hour) | 0x80; | ||
264 | |||
265 | if (tm->tm_mday != -1) | ||
266 | fm3130->regs[FM3130_ALARM_DATE] = | ||
267 | BIN2BCD(tm->tm_mday) | 0x80; | ||
268 | |||
269 | if (tm->tm_mon != -1) | ||
270 | fm3130->regs[FM3130_ALARM_MONTHS] = | ||
271 | BIN2BCD(tm->tm_mon + 1) | 0x80; | ||
272 | |||
273 | dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n", | ||
274 | fm3130->regs[FM3130_ALARM_SECONDS], | ||
275 | fm3130->regs[FM3130_ALARM_MINUTES], | ||
276 | fm3130->regs[FM3130_ALARM_HOURS], | ||
277 | fm3130->regs[FM3130_ALARM_DATE], | ||
278 | fm3130->regs[FM3130_ALARM_MONTHS]); | ||
279 | /* Writing time registers, we don't support multibyte transfers */ | ||
280 | for (i = 0; i < FM3130_ALARM_REGS; i++) { | ||
281 | i2c_smbus_write_byte_data(fm3130->client, | ||
282 | FM3130_ALARM_SECONDS + i, | ||
283 | fm3130->regs[FM3130_ALARM_SECONDS + i]); | ||
284 | } | ||
285 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
286 | i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); | ||
287 | /* Checking for alarm */ | ||
288 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
289 | fm3130->alarm = 1; | ||
290 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
291 | } | ||
292 | if (alrm->enabled) { | ||
293 | i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, | ||
294 | (fm3130->regs[FM3130_RTC_CONTROL] & | ||
295 | ~(FM3130_RTC_CONTROL_BIT_CAL)) | | ||
296 | FM3130_RTC_CONTROL_BIT_AEN); | ||
297 | } else { | ||
298 | i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, | ||
299 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
300 | ~(FM3130_RTC_CONTROL_BIT_AEN)); | ||
301 | } | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static const struct rtc_class_ops fm3130_rtc_ops = { | ||
306 | .read_time = fm3130_get_time, | ||
307 | .set_time = fm3130_set_time, | ||
308 | .read_alarm = fm3130_read_alarm, | ||
309 | .set_alarm = fm3130_set_alarm, | ||
310 | }; | ||
311 | |||
312 | static struct i2c_driver fm3130_driver; | ||
313 | |||
314 | static int __devinit fm3130_probe(struct i2c_client *client, | ||
315 | const struct i2c_device_id *id) | ||
316 | { | ||
317 | struct fm3130 *fm3130; | ||
318 | int err = -ENODEV; | ||
319 | int tmp; | ||
320 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
321 | |||
322 | if (!i2c_check_functionality(adapter, | ||
323 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
324 | return -EIO; | ||
325 | |||
326 | fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL); | ||
327 | |||
328 | if (!fm3130) | ||
329 | return -ENOMEM; | ||
330 | |||
331 | fm3130->client = client; | ||
332 | i2c_set_clientdata(client, fm3130); | ||
333 | fm3130->reg_addr_time = FM3130_RTC_SECONDS; | ||
334 | fm3130->reg_addr_alarm = FM3130_ALARM_SECONDS; | ||
335 | |||
336 | /* Messages to read time */ | ||
337 | fm3130->msg[0].addr = client->addr; | ||
338 | fm3130->msg[0].flags = 0; | ||
339 | fm3130->msg[0].len = 1; | ||
340 | fm3130->msg[0].buf = &fm3130->reg_addr_time; | ||
341 | |||
342 | fm3130->msg[1].addr = client->addr; | ||
343 | fm3130->msg[1].flags = I2C_M_RD; | ||
344 | fm3130->msg[1].len = FM3130_CLOCK_REGS; | ||
345 | fm3130->msg[1].buf = &fm3130->regs[FM3130_RTC_SECONDS]; | ||
346 | |||
347 | /* Messages to read alarm */ | ||
348 | fm3130->msg[2].addr = client->addr; | ||
349 | fm3130->msg[2].flags = 0; | ||
350 | fm3130->msg[2].len = 1; | ||
351 | fm3130->msg[2].buf = &fm3130->reg_addr_alarm; | ||
352 | |||
353 | fm3130->msg[3].addr = client->addr; | ||
354 | fm3130->msg[3].flags = I2C_M_RD; | ||
355 | fm3130->msg[3].len = FM3130_ALARM_REGS; | ||
356 | fm3130->msg[3].buf = &fm3130->regs[FM3130_ALARM_SECONDS]; | ||
357 | |||
358 | fm3130->data_valid = 0; | ||
359 | |||
360 | tmp = i2c_transfer(adapter, fm3130->msg, 4); | ||
361 | if (tmp != 4) { | ||
362 | pr_debug("read error %d\n", tmp); | ||
363 | err = -EIO; | ||
364 | goto exit_free; | ||
365 | } | ||
366 | |||
367 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
368 | i2c_smbus_read_byte_data(client, FM3130_RTC_CONTROL); | ||
369 | fm3130->regs[FM3130_CAL_CONTROL] = | ||
370 | i2c_smbus_read_byte_data(client, FM3130_CAL_CONTROL); | ||
371 | |||
372 | /* Checking for alarm */ | ||
373 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
374 | fm3130->alarm = 1; | ||
375 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
376 | } | ||
377 | |||
378 | /* Disabling calibration mode */ | ||
379 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) | ||
380 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
381 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
382 | ~(FM3130_RTC_CONTROL_BIT_CAL)); | ||
383 | dev_warn(&client->dev, "Disabling calibration mode!\n"); | ||
384 | |||
385 | /* Disabling read and write modes */ | ||
386 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE || | ||
387 | fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) | ||
388 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
389 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
390 | ~(FM3130_RTC_CONTROL_BIT_READ | | ||
391 | FM3130_RTC_CONTROL_BIT_WRITE)); | ||
392 | dev_warn(&client->dev, "Disabling READ or WRITE mode!\n"); | ||
393 | |||
394 | /* oscillator off? turn it on, so clock can tick. */ | ||
395 | if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN) | ||
396 | i2c_smbus_write_byte_data(client, FM3130_CAL_CONTROL, | ||
397 | fm3130->regs[FM3130_CAL_CONTROL] & | ||
398 | ~(FM3130_CAL_CONTROL_BIT_nOSCEN)); | ||
399 | |||
400 | /* oscillator fault? clear flag, and warn */ | ||
401 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_LB) | ||
402 | dev_warn(&client->dev, "Low battery!\n"); | ||
403 | |||
404 | /* oscillator fault? clear flag, and warn */ | ||
405 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_POR) { | ||
406 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
407 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
408 | ~FM3130_RTC_CONTROL_BIT_POR); | ||
409 | dev_warn(&client->dev, "SET TIME!\n"); | ||
410 | } | ||
411 | /* ACS is controlled by alarm */ | ||
412 | i2c_smbus_write_byte_data(client, FM3130_ALARM_WP_CONTROL, 0x80); | ||
413 | |||
414 | /* TODO */ | ||
415 | /* TODO need to sanity check alarm */ | ||
416 | tmp = fm3130->regs[FM3130_RTC_SECONDS]; | ||
417 | tmp = BCD2BIN(tmp & 0x7f); | ||
418 | if (tmp > 60) | ||
419 | goto exit_bad; | ||
420 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | ||
421 | if (tmp > 60) | ||
422 | goto exit_bad; | ||
423 | |||
424 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | ||
425 | if (tmp == 0 || tmp > 31) | ||
426 | goto exit_bad; | ||
427 | |||
428 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f); | ||
429 | if (tmp == 0 || tmp > 12) | ||
430 | goto exit_bad; | ||
431 | |||
432 | tmp = fm3130->regs[FM3130_RTC_HOURS]; | ||
433 | |||
434 | fm3130->data_valid = 1; | ||
435 | |||
436 | exit_bad: | ||
437 | if (!fm3130->data_valid) | ||
438 | dev_dbg(&client->dev, | ||
439 | "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | ||
440 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
441 | "bogus registers", | ||
442 | fm3130->regs[0], fm3130->regs[1], | ||
443 | fm3130->regs[2], fm3130->regs[3], | ||
444 | fm3130->regs[4], fm3130->regs[5], | ||
445 | fm3130->regs[6], fm3130->regs[7], | ||
446 | fm3130->regs[8], fm3130->regs[9], | ||
447 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
448 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
449 | fm3130->regs[0xe]); | ||
450 | |||
451 | /* We won't bail out here because we just got invalid data. | ||
452 | Time setting from u-boot doesn't work anyway */ | ||
453 | fm3130->rtc = rtc_device_register(client->name, &client->dev, | ||
454 | &fm3130_rtc_ops, THIS_MODULE); | ||
455 | if (IS_ERR(fm3130->rtc)) { | ||
456 | err = PTR_ERR(fm3130->rtc); | ||
457 | dev_err(&client->dev, | ||
458 | "unable to register the class device\n"); | ||
459 | goto exit_free; | ||
460 | } | ||
461 | return 0; | ||
462 | exit_free: | ||
463 | kfree(fm3130); | ||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int __devexit fm3130_remove(struct i2c_client *client) | ||
468 | { | ||
469 | struct fm3130 *fm3130 = i2c_get_clientdata(client); | ||
470 | |||
471 | rtc_device_unregister(fm3130->rtc); | ||
472 | kfree(fm3130); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static struct i2c_driver fm3130_driver = { | ||
477 | .driver = { | ||
478 | .name = "rtc-fm3130", | ||
479 | .owner = THIS_MODULE, | ||
480 | }, | ||
481 | .probe = fm3130_probe, | ||
482 | .remove = __devexit_p(fm3130_remove), | ||
483 | .id_table = fm3130_id, | ||
484 | }; | ||
485 | |||
486 | static int __init fm3130_init(void) | ||
487 | { | ||
488 | return i2c_add_driver(&fm3130_driver); | ||
489 | } | ||
490 | module_init(fm3130_init); | ||
491 | |||
492 | static void __exit fm3130_exit(void) | ||
493 | { | ||
494 | i2c_del_driver(&fm3130_driver); | ||
495 | } | ||
496 | module_exit(fm3130_exit); | ||
497 | |||
498 | MODULE_DESCRIPTION("RTC driver for FM3130"); | ||
499 | MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>"); | ||
500 | MODULE_LICENSE("GPL"); | ||
501 | |||
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 725b0c73c333..fbb90b1e4098 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -15,16 +15,15 @@ | |||
15 | #include <linux/bcd.h> | 15 | #include <linux/bcd.h> |
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | 17 | ||
18 | #define DRV_NAME "isl1208" | 18 | #define DRV_VERSION "0.3" |
19 | #define DRV_VERSION "0.2" | ||
20 | 19 | ||
21 | /* Register map */ | 20 | /* Register map */ |
22 | /* rtc section */ | 21 | /* rtc section */ |
23 | #define ISL1208_REG_SC 0x00 | 22 | #define ISL1208_REG_SC 0x00 |
24 | #define ISL1208_REG_MN 0x01 | 23 | #define ISL1208_REG_MN 0x01 |
25 | #define ISL1208_REG_HR 0x02 | 24 | #define ISL1208_REG_HR 0x02 |
26 | #define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */ | 25 | #define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */ |
27 | #define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */ | 26 | #define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */ |
28 | #define ISL1208_REG_DT 0x03 | 27 | #define ISL1208_REG_DT 0x03 |
29 | #define ISL1208_REG_MO 0x04 | 28 | #define ISL1208_REG_MO 0x04 |
30 | #define ISL1208_REG_YR 0x05 | 29 | #define ISL1208_REG_YR 0x05 |
@@ -33,14 +32,14 @@ | |||
33 | 32 | ||
34 | /* control/status section */ | 33 | /* control/status section */ |
35 | #define ISL1208_REG_SR 0x07 | 34 | #define ISL1208_REG_SR 0x07 |
36 | #define ISL1208_REG_SR_ARST (1<<7) /* auto reset */ | 35 | #define ISL1208_REG_SR_ARST (1<<7) /* auto reset */ |
37 | #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ | 36 | #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ |
38 | #define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */ | 37 | #define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */ |
39 | #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ | 38 | #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ |
40 | #define ISL1208_REG_SR_BAT (1<<1) /* battery */ | 39 | #define ISL1208_REG_SR_BAT (1<<1) /* battery */ |
41 | #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ | 40 | #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ |
42 | #define ISL1208_REG_INT 0x08 | 41 | #define ISL1208_REG_INT 0x08 |
43 | #define ISL1208_REG_09 0x09 /* reserved */ | 42 | #define ISL1208_REG_09 0x09 /* reserved */ |
44 | #define ISL1208_REG_ATR 0x0a | 43 | #define ISL1208_REG_ATR 0x0a |
45 | #define ISL1208_REG_DTR 0x0b | 44 | #define ISL1208_REG_DTR 0x0b |
46 | 45 | ||
@@ -58,39 +57,21 @@ | |||
58 | #define ISL1208_REG_USR2 0x13 | 57 | #define ISL1208_REG_USR2 0x13 |
59 | #define ISL1208_USR_SECTION_LEN 2 | 58 | #define ISL1208_USR_SECTION_LEN 2 |
60 | 59 | ||
61 | /* i2c configuration */ | 60 | static struct i2c_driver isl1208_driver; |
62 | #define ISL1208_I2C_ADDR 0xde | ||
63 | |||
64 | static const unsigned short normal_i2c[] = { | ||
65 | ISL1208_I2C_ADDR>>1, I2C_CLIENT_END | ||
66 | }; | ||
67 | I2C_CLIENT_INSMOD; /* defines addr_data */ | ||
68 | |||
69 | static int isl1208_attach_adapter(struct i2c_adapter *adapter); | ||
70 | static int isl1208_detach_client(struct i2c_client *client); | ||
71 | |||
72 | static struct i2c_driver isl1208_driver = { | ||
73 | .driver = { | ||
74 | .name = DRV_NAME, | ||
75 | }, | ||
76 | .id = I2C_DRIVERID_ISL1208, | ||
77 | .attach_adapter = &isl1208_attach_adapter, | ||
78 | .detach_client = &isl1208_detach_client, | ||
79 | }; | ||
80 | 61 | ||
81 | /* block read */ | 62 | /* block read */ |
82 | static int | 63 | static int |
83 | isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], | 64 | isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], |
84 | unsigned len) | 65 | unsigned len) |
85 | { | 66 | { |
86 | u8 reg_addr[1] = { reg }; | 67 | u8 reg_addr[1] = { reg }; |
87 | struct i2c_msg msgs[2] = { | 68 | struct i2c_msg msgs[2] = { |
88 | { client->addr, client->flags, sizeof(reg_addr), reg_addr }, | 69 | {client->addr, 0, sizeof(reg_addr), reg_addr} |
89 | { client->addr, client->flags | I2C_M_RD, len, buf } | 70 | , |
71 | {client->addr, I2C_M_RD, len, buf} | ||
90 | }; | 72 | }; |
91 | int ret; | 73 | int ret; |
92 | 74 | ||
93 | BUG_ON(len == 0); | ||
94 | BUG_ON(reg > ISL1208_REG_USR2); | 75 | BUG_ON(reg > ISL1208_REG_USR2); |
95 | BUG_ON(reg + len > ISL1208_REG_USR2 + 1); | 76 | BUG_ON(reg + len > ISL1208_REG_USR2 + 1); |
96 | 77 | ||
@@ -103,15 +84,14 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], | |||
103 | /* block write */ | 84 | /* block write */ |
104 | static int | 85 | static int |
105 | isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | 86 | isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], |
106 | unsigned len) | 87 | unsigned len) |
107 | { | 88 | { |
108 | u8 i2c_buf[ISL1208_REG_USR2 + 2]; | 89 | u8 i2c_buf[ISL1208_REG_USR2 + 2]; |
109 | struct i2c_msg msgs[1] = { | 90 | struct i2c_msg msgs[1] = { |
110 | { client->addr, client->flags, len + 1, i2c_buf } | 91 | {client->addr, 0, len + 1, i2c_buf} |
111 | }; | 92 | }; |
112 | int ret; | 93 | int ret; |
113 | 94 | ||
114 | BUG_ON(len == 0); | ||
115 | BUG_ON(reg > ISL1208_REG_USR2); | 95 | BUG_ON(reg > ISL1208_REG_USR2); |
116 | BUG_ON(reg + len > ISL1208_REG_USR2 + 1); | 96 | BUG_ON(reg + len > ISL1208_REG_USR2 + 1); |
117 | 97 | ||
@@ -125,7 +105,8 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | |||
125 | } | 105 | } |
126 | 106 | ||
127 | /* simple check to see wether we have a isl1208 */ | 107 | /* simple check to see wether we have a isl1208 */ |
128 | static int isl1208_i2c_validate_client(struct i2c_client *client) | 108 | static int |
109 | isl1208_i2c_validate_client(struct i2c_client *client) | ||
129 | { | 110 | { |
130 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; | 111 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; |
131 | u8 zero_mask[ISL1208_RTC_SECTION_LEN] = { | 112 | u8 zero_mask[ISL1208_RTC_SECTION_LEN] = { |
@@ -139,24 +120,29 @@ static int isl1208_i2c_validate_client(struct i2c_client *client) | |||
139 | return ret; | 120 | return ret; |
140 | 121 | ||
141 | for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) { | 122 | for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) { |
142 | if (regs[i] & zero_mask[i]) /* check if bits are cleared */ | 123 | if (regs[i] & zero_mask[i]) /* check if bits are cleared */ |
143 | return -ENODEV; | 124 | return -ENODEV; |
144 | } | 125 | } |
145 | 126 | ||
146 | return 0; | 127 | return 0; |
147 | } | 128 | } |
148 | 129 | ||
149 | static int isl1208_i2c_get_sr(struct i2c_client *client) | 130 | static int |
131 | isl1208_i2c_get_sr(struct i2c_client *client) | ||
150 | { | 132 | { |
151 | return i2c_smbus_read_byte_data(client, ISL1208_REG_SR) == -1 ? -EIO:0; | 133 | int sr = i2c_smbus_read_byte_data(client, ISL1208_REG_SR); |
134 | if (sr < 0) | ||
135 | return -EIO; | ||
136 | |||
137 | return sr; | ||
152 | } | 138 | } |
153 | 139 | ||
154 | static int isl1208_i2c_get_atr(struct i2c_client *client) | 140 | static int |
141 | isl1208_i2c_get_atr(struct i2c_client *client) | ||
155 | { | 142 | { |
156 | int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR); | 143 | int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR); |
157 | |||
158 | if (atr < 0) | 144 | if (atr < 0) |
159 | return -EIO; | 145 | return atr; |
160 | 146 | ||
161 | /* The 6bit value in the ATR register controls the load | 147 | /* The 6bit value in the ATR register controls the load |
162 | * capacitance C_load * in steps of 0.25pF | 148 | * capacitance C_load * in steps of 0.25pF |
@@ -169,51 +155,54 @@ static int isl1208_i2c_get_atr(struct i2c_client *client) | |||
169 | * | 155 | * |
170 | */ | 156 | */ |
171 | 157 | ||
172 | atr &= 0x3f; /* mask out lsb */ | 158 | atr &= 0x3f; /* mask out lsb */ |
173 | atr ^= 1<<5; /* invert 6th bit */ | 159 | atr ^= 1 << 5; /* invert 6th bit */ |
174 | atr += 2*9; /* add offset of 4.5pF; unit[atr] = 0.25pF */ | 160 | atr += 2 * 9; /* add offset of 4.5pF; unit[atr] = 0.25pF */ |
175 | 161 | ||
176 | return atr; | 162 | return atr; |
177 | } | 163 | } |
178 | 164 | ||
179 | static int isl1208_i2c_get_dtr(struct i2c_client *client) | 165 | static int |
166 | isl1208_i2c_get_dtr(struct i2c_client *client) | ||
180 | { | 167 | { |
181 | int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR); | 168 | int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR); |
182 | |||
183 | if (dtr < 0) | 169 | if (dtr < 0) |
184 | return -EIO; | 170 | return -EIO; |
185 | 171 | ||
186 | /* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */ | 172 | /* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */ |
187 | dtr = ((dtr & 0x3) * 20) * (dtr & (1<<2) ? -1 : 1); | 173 | dtr = ((dtr & 0x3) * 20) * (dtr & (1 << 2) ? -1 : 1); |
188 | 174 | ||
189 | return dtr; | 175 | return dtr; |
190 | } | 176 | } |
191 | 177 | ||
192 | static int isl1208_i2c_get_usr(struct i2c_client *client) | 178 | static int |
179 | isl1208_i2c_get_usr(struct i2c_client *client) | ||
193 | { | 180 | { |
194 | u8 buf[ISL1208_USR_SECTION_LEN] = { 0, }; | 181 | u8 buf[ISL1208_USR_SECTION_LEN] = { 0, }; |
195 | int ret; | 182 | int ret; |
196 | 183 | ||
197 | ret = isl1208_i2c_read_regs (client, ISL1208_REG_USR1, buf, | 184 | ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1, buf, |
198 | ISL1208_USR_SECTION_LEN); | 185 | ISL1208_USR_SECTION_LEN); |
199 | if (ret < 0) | 186 | if (ret < 0) |
200 | return ret; | 187 | return ret; |
201 | 188 | ||
202 | return (buf[1] << 8) | buf[0]; | 189 | return (buf[1] << 8) | buf[0]; |
203 | } | 190 | } |
204 | 191 | ||
205 | static int isl1208_i2c_set_usr(struct i2c_client *client, u16 usr) | 192 | static int |
193 | isl1208_i2c_set_usr(struct i2c_client *client, u16 usr) | ||
206 | { | 194 | { |
207 | u8 buf[ISL1208_USR_SECTION_LEN]; | 195 | u8 buf[ISL1208_USR_SECTION_LEN]; |
208 | 196 | ||
209 | buf[0] = usr & 0xff; | 197 | buf[0] = usr & 0xff; |
210 | buf[1] = (usr >> 8) & 0xff; | 198 | buf[1] = (usr >> 8) & 0xff; |
211 | 199 | ||
212 | return isl1208_i2c_set_regs (client, ISL1208_REG_USR1, buf, | 200 | return isl1208_i2c_set_regs(client, ISL1208_REG_USR1, buf, |
213 | ISL1208_USR_SECTION_LEN); | 201 | ISL1208_USR_SECTION_LEN); |
214 | } | 202 | } |
215 | 203 | ||
216 | static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq) | 204 | static int |
205 | isl1208_rtc_proc(struct device *dev, struct seq_file *seq) | ||
217 | { | 206 | { |
218 | struct i2c_client *const client = to_i2c_client(dev); | 207 | struct i2c_client *const client = to_i2c_client(dev); |
219 | int sr, dtr, atr, usr; | 208 | int sr, dtr, atr, usr; |
@@ -230,20 +219,19 @@ static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq) | |||
230 | (sr & ISL1208_REG_SR_ALM) ? " ALM" : "", | 219 | (sr & ISL1208_REG_SR_ALM) ? " ALM" : "", |
231 | (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "", | 220 | (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "", |
232 | (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "", | 221 | (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "", |
233 | (sr & ISL1208_REG_SR_ARST) ? " ARST" : "", | 222 | (sr & ISL1208_REG_SR_ARST) ? " ARST" : "", sr); |
234 | sr); | ||
235 | 223 | ||
236 | seq_printf(seq, "batt_status\t: %s\n", | 224 | seq_printf(seq, "batt_status\t: %s\n", |
237 | (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay"); | 225 | (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay"); |
238 | 226 | ||
239 | dtr = isl1208_i2c_get_dtr(client); | 227 | dtr = isl1208_i2c_get_dtr(client); |
240 | if (dtr >= 0 -1) | 228 | if (dtr >= 0 - 1) |
241 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtr); | 229 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtr); |
242 | 230 | ||
243 | atr = isl1208_i2c_get_atr(client); | 231 | atr = isl1208_i2c_get_atr(client); |
244 | if (atr >= 0) | 232 | if (atr >= 0) |
245 | seq_printf(seq, "analog_trim\t: %d.%.2d pF\n", | 233 | seq_printf(seq, "analog_trim\t: %d.%.2d pF\n", |
246 | atr>>2, (atr&0x3)*25); | 234 | atr >> 2, (atr & 0x3) * 25); |
247 | 235 | ||
248 | usr = isl1208_i2c_get_usr(client); | 236 | usr = isl1208_i2c_get_usr(client); |
249 | if (usr >= 0) | 237 | if (usr >= 0) |
@@ -252,9 +240,8 @@ static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq) | |||
252 | return 0; | 240 | return 0; |
253 | } | 241 | } |
254 | 242 | ||
255 | 243 | static int | |
256 | static int isl1208_i2c_read_time(struct i2c_client *client, | 244 | isl1208_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) |
257 | struct rtc_time *tm) | ||
258 | { | 245 | { |
259 | int sr; | 246 | int sr; |
260 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; | 247 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; |
@@ -274,27 +261,30 @@ static int isl1208_i2c_read_time(struct i2c_client *client, | |||
274 | 261 | ||
275 | tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]); | 262 | tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]); |
276 | tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]); | 263 | tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]); |
277 | { /* HR field has a more complex interpretation */ | 264 | |
265 | /* HR field has a more complex interpretation */ | ||
266 | { | ||
278 | const u8 _hr = regs[ISL1208_REG_HR]; | 267 | const u8 _hr = regs[ISL1208_REG_HR]; |
279 | if (_hr & ISL1208_REG_HR_MIL) /* 24h format */ | 268 | if (_hr & ISL1208_REG_HR_MIL) /* 24h format */ |
280 | tm->tm_hour = BCD2BIN(_hr & 0x3f); | 269 | tm->tm_hour = BCD2BIN(_hr & 0x3f); |
281 | else { // 12h format | 270 | else { |
271 | /* 12h format */ | ||
282 | tm->tm_hour = BCD2BIN(_hr & 0x1f); | 272 | tm->tm_hour = BCD2BIN(_hr & 0x1f); |
283 | if (_hr & ISL1208_REG_HR_PM) /* PM flag set */ | 273 | if (_hr & ISL1208_REG_HR_PM) /* PM flag set */ |
284 | tm->tm_hour += 12; | 274 | tm->tm_hour += 12; |
285 | } | 275 | } |
286 | } | 276 | } |
287 | 277 | ||
288 | tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]); | 278 | tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]); |
289 | tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */ | 279 | tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */ |
290 | tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100; | 280 | tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100; |
291 | tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]); | 281 | tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]); |
292 | 282 | ||
293 | return 0; | 283 | return 0; |
294 | } | 284 | } |
295 | 285 | ||
296 | static int isl1208_i2c_read_alarm(struct i2c_client *client, | 286 | static int |
297 | struct rtc_wkalrm *alarm) | 287 | isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) |
298 | { | 288 | { |
299 | struct rtc_time *const tm = &alarm->time; | 289 | struct rtc_time *const tm = &alarm->time; |
300 | u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; | 290 | u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; |
@@ -307,7 +297,7 @@ static int isl1208_i2c_read_alarm(struct i2c_client *client, | |||
307 | } | 297 | } |
308 | 298 | ||
309 | sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs, | 299 | sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs, |
310 | ISL1208_ALARM_SECTION_LEN); | 300 | ISL1208_ALARM_SECTION_LEN); |
311 | if (sr < 0) { | 301 | if (sr < 0) { |
312 | dev_err(&client->dev, "%s: reading alarm section failed\n", | 302 | dev_err(&client->dev, "%s: reading alarm section failed\n", |
313 | __func__); | 303 | __func__); |
@@ -315,23 +305,25 @@ static int isl1208_i2c_read_alarm(struct i2c_client *client, | |||
315 | } | 305 | } |
316 | 306 | ||
317 | /* MSB of each alarm register is an enable bit */ | 307 | /* MSB of each alarm register is an enable bit */ |
318 | tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA-ISL1208_REG_SCA] & 0x7f); | 308 | tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f); |
319 | tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA-ISL1208_REG_SCA] & 0x7f); | 309 | tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f); |
320 | tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA-ISL1208_REG_SCA] & 0x3f); | 310 | tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f); |
321 | tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA-ISL1208_REG_SCA] & 0x3f); | 311 | tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f); |
322 | tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MOA-ISL1208_REG_SCA] & 0x1f)-1; | 312 | tm->tm_mon = |
323 | tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA-ISL1208_REG_SCA] & 0x03); | 313 | BCD2BIN(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1; |
314 | tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03); | ||
324 | 315 | ||
325 | return 0; | 316 | return 0; |
326 | } | 317 | } |
327 | 318 | ||
328 | static int isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm) | 319 | static int |
320 | isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
329 | { | 321 | { |
330 | return isl1208_i2c_read_time(to_i2c_client(dev), tm); | 322 | return isl1208_i2c_read_time(to_i2c_client(dev), tm); |
331 | } | 323 | } |
332 | 324 | ||
333 | static int isl1208_i2c_set_time(struct i2c_client *client, | 325 | static int |
334 | struct rtc_time const *tm) | 326 | isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) |
335 | { | 327 | { |
336 | int sr; | 328 | int sr; |
337 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; | 329 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; |
@@ -353,7 +345,7 @@ static int isl1208_i2c_set_time(struct i2c_client *client, | |||
353 | } | 345 | } |
354 | 346 | ||
355 | /* set WRTC */ | 347 | /* set WRTC */ |
356 | sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR, | 348 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, |
357 | sr | ISL1208_REG_SR_WRTC); | 349 | sr | ISL1208_REG_SR_WRTC); |
358 | if (sr < 0) { | 350 | if (sr < 0) { |
359 | dev_err(&client->dev, "%s: writing SR failed\n", __func__); | 351 | dev_err(&client->dev, "%s: writing SR failed\n", __func__); |
@@ -369,7 +361,7 @@ static int isl1208_i2c_set_time(struct i2c_client *client, | |||
369 | } | 361 | } |
370 | 362 | ||
371 | /* clear WRTC again */ | 363 | /* clear WRTC again */ |
372 | sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR, | 364 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, |
373 | sr & ~ISL1208_REG_SR_WRTC); | 365 | sr & ~ISL1208_REG_SR_WRTC); |
374 | if (sr < 0) { | 366 | if (sr < 0) { |
375 | dev_err(&client->dev, "%s: writing SR failed\n", __func__); | 367 | dev_err(&client->dev, "%s: writing SR failed\n", __func__); |
@@ -380,70 +372,69 @@ static int isl1208_i2c_set_time(struct i2c_client *client, | |||
380 | } | 372 | } |
381 | 373 | ||
382 | 374 | ||
383 | static int isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm) | 375 | static int |
376 | isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
384 | { | 377 | { |
385 | return isl1208_i2c_set_time(to_i2c_client(dev), tm); | 378 | return isl1208_i2c_set_time(to_i2c_client(dev), tm); |
386 | } | 379 | } |
387 | 380 | ||
388 | static int isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 381 | static int |
382 | isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
389 | { | 383 | { |
390 | return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm); | 384 | return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm); |
391 | } | 385 | } |
392 | 386 | ||
393 | static const struct rtc_class_ops isl1208_rtc_ops = { | 387 | static const struct rtc_class_ops isl1208_rtc_ops = { |
394 | .proc = isl1208_rtc_proc, | 388 | .proc = isl1208_rtc_proc, |
395 | .read_time = isl1208_rtc_read_time, | 389 | .read_time = isl1208_rtc_read_time, |
396 | .set_time = isl1208_rtc_set_time, | 390 | .set_time = isl1208_rtc_set_time, |
397 | .read_alarm = isl1208_rtc_read_alarm, | 391 | .read_alarm = isl1208_rtc_read_alarm, |
398 | //.set_alarm = isl1208_rtc_set_alarm, | 392 | /*.set_alarm = isl1208_rtc_set_alarm, */ |
399 | }; | 393 | }; |
400 | 394 | ||
401 | /* sysfs interface */ | 395 | /* sysfs interface */ |
402 | 396 | ||
403 | static ssize_t isl1208_sysfs_show_atrim(struct device *dev, | 397 | static ssize_t |
404 | struct device_attribute *attr, | 398 | isl1208_sysfs_show_atrim(struct device *dev, |
405 | char *buf) | 399 | struct device_attribute *attr, char *buf) |
406 | { | 400 | { |
407 | int atr; | 401 | int atr = isl1208_i2c_get_atr(to_i2c_client(dev)); |
408 | |||
409 | atr = isl1208_i2c_get_atr(to_i2c_client(dev)); | ||
410 | if (atr < 0) | 402 | if (atr < 0) |
411 | return atr; | 403 | return atr; |
412 | 404 | ||
413 | return sprintf(buf, "%d.%.2d pF\n", atr>>2, (atr&0x3)*25); | 405 | return sprintf(buf, "%d.%.2d pF\n", atr >> 2, (atr & 0x3) * 25); |
414 | } | 406 | } |
407 | |||
415 | static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL); | 408 | static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL); |
416 | 409 | ||
417 | static ssize_t isl1208_sysfs_show_dtrim(struct device *dev, | 410 | static ssize_t |
418 | struct device_attribute *attr, | 411 | isl1208_sysfs_show_dtrim(struct device *dev, |
419 | char *buf) | 412 | struct device_attribute *attr, char *buf) |
420 | { | 413 | { |
421 | int dtr; | 414 | int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev)); |
422 | |||
423 | dtr = isl1208_i2c_get_dtr(to_i2c_client(dev)); | ||
424 | if (dtr < 0) | 415 | if (dtr < 0) |
425 | return dtr; | 416 | return dtr; |
426 | 417 | ||
427 | return sprintf(buf, "%d ppm\n", dtr); | 418 | return sprintf(buf, "%d ppm\n", dtr); |
428 | } | 419 | } |
420 | |||
429 | static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL); | 421 | static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL); |
430 | 422 | ||
431 | static ssize_t isl1208_sysfs_show_usr(struct device *dev, | 423 | static ssize_t |
432 | struct device_attribute *attr, | 424 | isl1208_sysfs_show_usr(struct device *dev, |
433 | char *buf) | 425 | struct device_attribute *attr, char *buf) |
434 | { | 426 | { |
435 | int usr; | 427 | int usr = isl1208_i2c_get_usr(to_i2c_client(dev)); |
436 | |||
437 | usr = isl1208_i2c_get_usr(to_i2c_client(dev)); | ||
438 | if (usr < 0) | 428 | if (usr < 0) |
439 | return usr; | 429 | return usr; |
440 | 430 | ||
441 | return sprintf(buf, "0x%.4x\n", usr); | 431 | return sprintf(buf, "0x%.4x\n", usr); |
442 | } | 432 | } |
443 | 433 | ||
444 | static ssize_t isl1208_sysfs_store_usr(struct device *dev, | 434 | static ssize_t |
445 | struct device_attribute *attr, | 435 | isl1208_sysfs_store_usr(struct device *dev, |
446 | const char *buf, size_t count) | 436 | struct device_attribute *attr, |
437 | const char *buf, size_t count) | ||
447 | { | 438 | { |
448 | int usr = -1; | 439 | int usr = -1; |
449 | 440 | ||
@@ -460,124 +451,123 @@ static ssize_t isl1208_sysfs_store_usr(struct device *dev, | |||
460 | 451 | ||
461 | return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count; | 452 | return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count; |
462 | } | 453 | } |
454 | |||
463 | static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, | 455 | static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, |
464 | isl1208_sysfs_store_usr); | 456 | isl1208_sysfs_store_usr); |
465 | 457 | ||
466 | static int | 458 | static int |
467 | isl1208_probe(struct i2c_adapter *adapter, int addr, int kind) | 459 | isl1208_sysfs_register(struct device *dev) |
468 | { | 460 | { |
469 | int rc = 0; | 461 | int err; |
470 | struct i2c_client *new_client = NULL; | ||
471 | struct rtc_device *rtc = NULL; | ||
472 | 462 | ||
473 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { | 463 | err = device_create_file(dev, &dev_attr_atrim); |
474 | rc = -ENODEV; | 464 | if (err) |
475 | goto failout; | 465 | return err; |
466 | |||
467 | err = device_create_file(dev, &dev_attr_dtrim); | ||
468 | if (err) { | ||
469 | device_remove_file(dev, &dev_attr_atrim); | ||
470 | return err; | ||
476 | } | 471 | } |
477 | 472 | ||
478 | new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 473 | err = device_create_file(dev, &dev_attr_usr); |
479 | if (new_client == NULL) { | 474 | if (err) { |
480 | rc = -ENOMEM; | 475 | device_remove_file(dev, &dev_attr_atrim); |
481 | goto failout; | 476 | device_remove_file(dev, &dev_attr_dtrim); |
482 | } | 477 | } |
483 | 478 | ||
484 | new_client->addr = addr; | 479 | return 0; |
485 | new_client->adapter = adapter; | 480 | } |
486 | new_client->driver = &isl1208_driver; | ||
487 | new_client->flags = 0; | ||
488 | strcpy(new_client->name, DRV_NAME); | ||
489 | 481 | ||
490 | if (kind < 0) { | 482 | static int |
491 | rc = isl1208_i2c_validate_client(new_client); | 483 | isl1208_sysfs_unregister(struct device *dev) |
492 | if (rc < 0) | 484 | { |
493 | goto failout; | 485 | device_remove_file(dev, &dev_attr_atrim); |
494 | } | 486 | device_remove_file(dev, &dev_attr_atrim); |
487 | device_remove_file(dev, &dev_attr_usr); | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int | ||
493 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
494 | { | ||
495 | int rc = 0; | ||
496 | struct rtc_device *rtc; | ||
497 | |||
498 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
499 | return -ENODEV; | ||
495 | 500 | ||
496 | rc = i2c_attach_client(new_client); | 501 | if (isl1208_i2c_validate_client(client) < 0) |
497 | if (rc < 0) | 502 | return -ENODEV; |
498 | goto failout; | ||
499 | 503 | ||
500 | dev_info(&new_client->dev, | 504 | dev_info(&client->dev, |
501 | "chip found, driver version " DRV_VERSION "\n"); | 505 | "chip found, driver version " DRV_VERSION "\n"); |
502 | 506 | ||
503 | rtc = rtc_device_register(isl1208_driver.driver.name, | 507 | rtc = rtc_device_register(isl1208_driver.driver.name, |
504 | &new_client->dev, | 508 | &client->dev, &isl1208_rtc_ops, |
505 | &isl1208_rtc_ops, THIS_MODULE); | 509 | THIS_MODULE); |
510 | if (IS_ERR(rtc)) | ||
511 | return PTR_ERR(rtc); | ||
506 | 512 | ||
507 | if (IS_ERR(rtc)) { | 513 | i2c_set_clientdata(client, rtc); |
508 | rc = PTR_ERR(rtc); | ||
509 | goto failout_detach; | ||
510 | } | ||
511 | |||
512 | i2c_set_clientdata(new_client, rtc); | ||
513 | 514 | ||
514 | rc = isl1208_i2c_get_sr(new_client); | 515 | rc = isl1208_i2c_get_sr(client); |
515 | if (rc < 0) { | 516 | if (rc < 0) { |
516 | dev_err(&new_client->dev, "reading status failed\n"); | 517 | dev_err(&client->dev, "reading status failed\n"); |
517 | goto failout_unregister; | 518 | goto exit_unregister; |
518 | } | 519 | } |
519 | 520 | ||
520 | if (rc & ISL1208_REG_SR_RTCF) | 521 | if (rc & ISL1208_REG_SR_RTCF) |
521 | dev_warn(&new_client->dev, "rtc power failure detected, " | 522 | dev_warn(&client->dev, "rtc power failure detected, " |
522 | "please set clock.\n"); | 523 | "please set clock.\n"); |
523 | 524 | ||
524 | rc = device_create_file(&new_client->dev, &dev_attr_atrim); | 525 | rc = isl1208_sysfs_register(&client->dev); |
525 | if (rc < 0) | 526 | if (rc) |
526 | goto failout_unregister; | 527 | goto exit_unregister; |
527 | rc = device_create_file(&new_client->dev, &dev_attr_dtrim); | ||
528 | if (rc < 0) | ||
529 | goto failout_atrim; | ||
530 | rc = device_create_file(&new_client->dev, &dev_attr_usr); | ||
531 | if (rc < 0) | ||
532 | goto failout_dtrim; | ||
533 | 528 | ||
534 | return 0; | 529 | return 0; |
535 | 530 | ||
536 | failout_dtrim: | 531 | exit_unregister: |
537 | device_remove_file(&new_client->dev, &dev_attr_dtrim); | ||
538 | failout_atrim: | ||
539 | device_remove_file(&new_client->dev, &dev_attr_atrim); | ||
540 | failout_unregister: | ||
541 | rtc_device_unregister(rtc); | 532 | rtc_device_unregister(rtc); |
542 | failout_detach: | ||
543 | i2c_detach_client(new_client); | ||
544 | failout: | ||
545 | kfree(new_client); | ||
546 | return rc; | ||
547 | } | ||
548 | 533 | ||
549 | static int | 534 | return rc; |
550 | isl1208_attach_adapter (struct i2c_adapter *adapter) | ||
551 | { | ||
552 | return i2c_probe(adapter, &addr_data, isl1208_probe); | ||
553 | } | 535 | } |
554 | 536 | ||
555 | static int | 537 | static int |
556 | isl1208_detach_client(struct i2c_client *client) | 538 | isl1208_remove(struct i2c_client *client) |
557 | { | 539 | { |
558 | int rc; | 540 | struct rtc_device *rtc = i2c_get_clientdata(client); |
559 | struct rtc_device *const rtc = i2c_get_clientdata(client); | ||
560 | 541 | ||
561 | if (rtc) | 542 | isl1208_sysfs_unregister(&client->dev); |
562 | rtc_device_unregister(rtc); /* do we need to kfree? */ | 543 | rtc_device_unregister(rtc); |
563 | |||
564 | rc = i2c_detach_client(client); | ||
565 | if (rc) | ||
566 | return rc; | ||
567 | |||
568 | kfree(client); | ||
569 | 544 | ||
570 | return 0; | 545 | return 0; |
571 | } | 546 | } |
572 | 547 | ||
573 | /* module management */ | 548 | static const struct i2c_device_id isl1208_id[] = { |
549 | { "isl1208", 0 }, | ||
550 | { } | ||
551 | }; | ||
552 | MODULE_DEVICE_TABLE(i2c, isl1208_id); | ||
553 | |||
554 | static struct i2c_driver isl1208_driver = { | ||
555 | .driver = { | ||
556 | .name = "rtc-isl1208", | ||
557 | }, | ||
558 | .probe = isl1208_probe, | ||
559 | .remove = isl1208_remove, | ||
560 | .id_table = isl1208_id, | ||
561 | }; | ||
574 | 562 | ||
575 | static int __init isl1208_init(void) | 563 | static int __init |
564 | isl1208_init(void) | ||
576 | { | 565 | { |
577 | return i2c_add_driver(&isl1208_driver); | 566 | return i2c_add_driver(&isl1208_driver); |
578 | } | 567 | } |
579 | 568 | ||
580 | static void __exit isl1208_exit(void) | 569 | static void __exit |
570 | isl1208_exit(void) | ||
581 | { | 571 | { |
582 | i2c_del_driver(&isl1208_driver); | 572 | i2c_del_driver(&isl1208_driver); |
583 | } | 573 | } |
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index ba795a4db1e9..9f996ec881ce 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c | |||
@@ -51,7 +51,7 @@ EXPORT_SYMBOL(rtc_year_days); | |||
51 | */ | 51 | */ |
52 | void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) | 52 | void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) |
53 | { | 53 | { |
54 | register int days, month, year; | 54 | unsigned int days, month, year; |
55 | 55 | ||
56 | days = time / 86400; | 56 | days = time / 86400; |
57 | time -= days * 86400; | 57 | time -= days * 86400; |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 1cb33cac1237..a3e0880b38fb 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/kernel.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <linux/string.h> | 20 | #include <linux/string.h> |
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
@@ -60,48 +61,21 @@ | |||
60 | 61 | ||
61 | #define DRV_VERSION "0.05" | 62 | #define DRV_VERSION "0.05" |
62 | 63 | ||
63 | struct m41t80_chip_info { | 64 | static const struct i2c_device_id m41t80_id[] = { |
64 | const char *name; | 65 | { "m41t80", 0 }, |
65 | u8 features; | 66 | { "m41t81", M41T80_FEATURE_HT }, |
66 | }; | 67 | { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, |
67 | 68 | { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, | |
68 | static const struct m41t80_chip_info m41t80_chip_info_tbl[] = { | 69 | { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, |
69 | { | 70 | { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, |
70 | .name = "m41t80", | 71 | { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, |
71 | .features = 0, | 72 | { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL }, |
72 | }, | 73 | { } |
73 | { | ||
74 | .name = "m41t81", | ||
75 | .features = M41T80_FEATURE_HT, | ||
76 | }, | ||
77 | { | ||
78 | .name = "m41t81s", | ||
79 | .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL, | ||
80 | }, | ||
81 | { | ||
82 | .name = "m41t82", | ||
83 | .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL, | ||
84 | }, | ||
85 | { | ||
86 | .name = "m41t83", | ||
87 | .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL, | ||
88 | }, | ||
89 | { | ||
90 | .name = "m41st84", | ||
91 | .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL, | ||
92 | }, | ||
93 | { | ||
94 | .name = "m41st85", | ||
95 | .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL, | ||
96 | }, | ||
97 | { | ||
98 | .name = "m41st87", | ||
99 | .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL, | ||
100 | }, | ||
101 | }; | 74 | }; |
75 | MODULE_DEVICE_TABLE(i2c, m41t80_id); | ||
102 | 76 | ||
103 | struct m41t80_data { | 77 | struct m41t80_data { |
104 | const struct m41t80_chip_info *chip; | 78 | u8 features; |
105 | struct rtc_device *rtc; | 79 | struct rtc_device *rtc; |
106 | }; | 80 | }; |
107 | 81 | ||
@@ -208,7 +182,7 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) | |||
208 | struct m41t80_data *clientdata = i2c_get_clientdata(client); | 182 | struct m41t80_data *clientdata = i2c_get_clientdata(client); |
209 | u8 reg; | 183 | u8 reg; |
210 | 184 | ||
211 | if (clientdata->chip->features & M41T80_FEATURE_BL) { | 185 | if (clientdata->features & M41T80_FEATURE_BL) { |
212 | reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); | 186 | reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); |
213 | seq_printf(seq, "battery\t\t: %s\n", | 187 | seq_printf(seq, "battery\t\t: %s\n", |
214 | (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok"); | 188 | (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok"); |
@@ -756,12 +730,12 @@ static struct notifier_block wdt_notifier = { | |||
756 | * | 730 | * |
757 | ***************************************************************************** | 731 | ***************************************************************************** |
758 | */ | 732 | */ |
759 | static int m41t80_probe(struct i2c_client *client) | 733 | static int m41t80_probe(struct i2c_client *client, |
734 | const struct i2c_device_id *id) | ||
760 | { | 735 | { |
761 | int i, rc = 0; | 736 | int rc = 0; |
762 | struct rtc_device *rtc = NULL; | 737 | struct rtc_device *rtc = NULL; |
763 | struct rtc_time tm; | 738 | struct rtc_time tm; |
764 | const struct m41t80_chip_info *chip; | ||
765 | struct m41t80_data *clientdata = NULL; | 739 | struct m41t80_data *clientdata = NULL; |
766 | 740 | ||
767 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | 741 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
@@ -773,19 +747,6 @@ static int m41t80_probe(struct i2c_client *client) | |||
773 | dev_info(&client->dev, | 747 | dev_info(&client->dev, |
774 | "chip found, driver version " DRV_VERSION "\n"); | 748 | "chip found, driver version " DRV_VERSION "\n"); |
775 | 749 | ||
776 | chip = NULL; | ||
777 | for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) { | ||
778 | if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) { | ||
779 | chip = &m41t80_chip_info_tbl[i]; | ||
780 | break; | ||
781 | } | ||
782 | } | ||
783 | if (!chip) { | ||
784 | dev_err(&client->dev, "%s is not supported\n", client->name); | ||
785 | rc = -ENODEV; | ||
786 | goto exit; | ||
787 | } | ||
788 | |||
789 | clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL); | 750 | clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL); |
790 | if (!clientdata) { | 751 | if (!clientdata) { |
791 | rc = -ENOMEM; | 752 | rc = -ENOMEM; |
@@ -801,7 +762,7 @@ static int m41t80_probe(struct i2c_client *client) | |||
801 | } | 762 | } |
802 | 763 | ||
803 | clientdata->rtc = rtc; | 764 | clientdata->rtc = rtc; |
804 | clientdata->chip = chip; | 765 | clientdata->features = id->driver_data; |
805 | i2c_set_clientdata(client, clientdata); | 766 | i2c_set_clientdata(client, clientdata); |
806 | 767 | ||
807 | /* Make sure HT (Halt Update) bit is cleared */ | 768 | /* Make sure HT (Halt Update) bit is cleared */ |
@@ -810,7 +771,7 @@ static int m41t80_probe(struct i2c_client *client) | |||
810 | goto ht_err; | 771 | goto ht_err; |
811 | 772 | ||
812 | if (rc & M41T80_ALHOUR_HT) { | 773 | if (rc & M41T80_ALHOUR_HT) { |
813 | if (chip->features & M41T80_FEATURE_HT) { | 774 | if (clientdata->features & M41T80_FEATURE_HT) { |
814 | m41t80_get_datetime(client, &tm); | 775 | m41t80_get_datetime(client, &tm); |
815 | dev_info(&client->dev, "HT bit was set!\n"); | 776 | dev_info(&client->dev, "HT bit was set!\n"); |
816 | dev_info(&client->dev, | 777 | dev_info(&client->dev, |
@@ -842,7 +803,8 @@ static int m41t80_probe(struct i2c_client *client) | |||
842 | goto exit; | 803 | goto exit; |
843 | 804 | ||
844 | #ifdef CONFIG_RTC_DRV_M41T80_WDT | 805 | #ifdef CONFIG_RTC_DRV_M41T80_WDT |
845 | if (chip->features & M41T80_FEATURE_HT) { | 806 | if (clientdata->features & M41T80_FEATURE_HT) { |
807 | save_client = client; | ||
846 | rc = misc_register(&wdt_dev); | 808 | rc = misc_register(&wdt_dev); |
847 | if (rc) | 809 | if (rc) |
848 | goto exit; | 810 | goto exit; |
@@ -851,7 +813,6 @@ static int m41t80_probe(struct i2c_client *client) | |||
851 | misc_deregister(&wdt_dev); | 813 | misc_deregister(&wdt_dev); |
852 | goto exit; | 814 | goto exit; |
853 | } | 815 | } |
854 | save_client = client; | ||
855 | } | 816 | } |
856 | #endif | 817 | #endif |
857 | return 0; | 818 | return 0; |
@@ -878,7 +839,7 @@ static int m41t80_remove(struct i2c_client *client) | |||
878 | struct rtc_device *rtc = clientdata->rtc; | 839 | struct rtc_device *rtc = clientdata->rtc; |
879 | 840 | ||
880 | #ifdef CONFIG_RTC_DRV_M41T80_WDT | 841 | #ifdef CONFIG_RTC_DRV_M41T80_WDT |
881 | if (clientdata->chip->features & M41T80_FEATURE_HT) { | 842 | if (clientdata->features & M41T80_FEATURE_HT) { |
882 | misc_deregister(&wdt_dev); | 843 | misc_deregister(&wdt_dev); |
883 | unregister_reboot_notifier(&wdt_notifier); | 844 | unregister_reboot_notifier(&wdt_notifier); |
884 | } | 845 | } |
@@ -896,6 +857,7 @@ static struct i2c_driver m41t80_driver = { | |||
896 | }, | 857 | }, |
897 | .probe = m41t80_probe, | 858 | .probe = m41t80_probe, |
898 | .remove = m41t80_remove, | 859 | .remove = m41t80_remove, |
860 | .id_table = m41t80_id, | ||
899 | }; | 861 | }; |
900 | 862 | ||
901 | static int __init m41t80_rtc_init(void) | 863 | static int __init m41t80_rtc_init(void) |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index cd0bbc0e8038..013e6c103b9c 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -465,6 +465,9 @@ static int __devexit m48t59_rtc_remove(struct platform_device *pdev) | |||
465 | return 0; | 465 | return 0; |
466 | } | 466 | } |
467 | 467 | ||
468 | /* work with hotplug and coldplug */ | ||
469 | MODULE_ALIAS("platform:rtc-m48t59"); | ||
470 | |||
468 | static struct platform_driver m48t59_rtc_driver = { | 471 | static struct platform_driver m48t59_rtc_driver = { |
469 | .driver = { | 472 | .driver = { |
470 | .name = "rtc-m48t59", | 473 | .name = "rtc-m48t59", |
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 8ff4a1221f59..3f7f99a5d96a 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -199,6 +199,7 @@ MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | |||
199 | MODULE_DESCRIPTION("M48T86 RTC driver"); | 199 | MODULE_DESCRIPTION("M48T86 RTC driver"); |
200 | MODULE_LICENSE("GPL"); | 200 | MODULE_LICENSE("GPL"); |
201 | MODULE_VERSION(DRV_VERSION); | 201 | MODULE_VERSION(DRV_VERSION); |
202 | MODULE_ALIAS("platform:rtc-m48t86"); | ||
202 | 203 | ||
203 | module_init(m48t86_rtc_init); | 204 | module_init(m48t86_rtc_init); |
204 | module_exit(m48t86_rtc_exit); | 205 | module_exit(m48t86_rtc_exit); |
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 7683412970c4..ded3c0abad83 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c | |||
@@ -98,7 +98,7 @@ static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf) | |||
98 | rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | 98 | rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); |
99 | if (rc != ARRAY_SIZE(msgs)) { | 99 | if (rc != ARRAY_SIZE(msgs)) { |
100 | dev_err(&client->dev, "%s: register read failed\n", | 100 | dev_err(&client->dev, "%s: register read failed\n", |
101 | __FUNCTION__); | 101 | __func__); |
102 | return -EIO; | 102 | return -EIO; |
103 | } | 103 | } |
104 | return 0; | 104 | return 0; |
@@ -150,7 +150,7 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) | |||
150 | 150 | ||
151 | write_failed: | 151 | write_failed: |
152 | dev_err(&client->dev, "%s: register write failed\n", | 152 | dev_err(&client->dev, "%s: register write failed\n", |
153 | __FUNCTION__); | 153 | __func__); |
154 | return -EIO; | 154 | return -EIO; |
155 | } | 155 | } |
156 | 156 | ||
@@ -214,7 +214,7 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client) | |||
214 | rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0); | 214 | rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0); |
215 | if (rc < 0) { | 215 | if (rc < 0) { |
216 | dev_err(&client->dev, "%s: control register write failed\n", | 216 | dev_err(&client->dev, "%s: control register write failed\n", |
217 | __FUNCTION__); | 217 | __func__); |
218 | return -EIO; | 218 | return -EIO; |
219 | } | 219 | } |
220 | return 0; | 220 | return 0; |
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 1f956dc5d56e..12f0310ae89c 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -140,7 +140,7 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) | |||
140 | dt->tm_year -= 1900; | 140 | dt->tm_year -= 1900; |
141 | 141 | ||
142 | #ifdef MAX6902_DEBUG | 142 | #ifdef MAX6902_DEBUG |
143 | printk("\n%s : Read RTC values\n",__FUNCTION__); | 143 | printk("\n%s : Read RTC values\n",__func__); |
144 | printk("tm_hour: %i\n",dt->tm_hour); | 144 | printk("tm_hour: %i\n",dt->tm_hour); |
145 | printk("tm_min : %i\n",dt->tm_min); | 145 | printk("tm_min : %i\n",dt->tm_min); |
146 | printk("tm_sec : %i\n",dt->tm_sec); | 146 | printk("tm_sec : %i\n",dt->tm_sec); |
@@ -158,7 +158,7 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | |||
158 | dt->tm_year = dt->tm_year+1900; | 158 | dt->tm_year = dt->tm_year+1900; |
159 | 159 | ||
160 | #ifdef MAX6902_DEBUG | 160 | #ifdef MAX6902_DEBUG |
161 | printk("\n%s : Setting RTC values\n",__FUNCTION__); | 161 | printk("\n%s : Setting RTC values\n",__func__); |
162 | printk("tm_sec : %i\n",dt->tm_sec); | 162 | printk("tm_sec : %i\n",dt->tm_sec); |
163 | printk("tm_min : %i\n",dt->tm_min); | 163 | printk("tm_min : %i\n",dt->tm_min); |
164 | printk("tm_hour: %i\n",dt->tm_hour); | 164 | printk("tm_hour: %i\n",dt->tm_hour); |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index a2f84f169588..eb23d8423f42 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | 23 | ||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/mach/time.h> | ||
26 | 25 | ||
27 | 26 | ||
28 | /* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock | 27 | /* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock |
@@ -497,7 +496,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev) | |||
497 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 496 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); |
498 | } | 497 | } |
499 | 498 | ||
500 | MODULE_ALIAS("omap_rtc"); | 499 | MODULE_ALIAS("platform:omap_rtc"); |
501 | static struct platform_driver omap_rtc_driver = { | 500 | static struct platform_driver omap_rtc_driver = { |
502 | .probe = omap_rtc_probe, | 501 | .probe = omap_rtc_probe, |
503 | .remove = __devexit_p(omap_rtc_remove), | 502 | .remove = __devexit_p(omap_rtc_remove), |
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index b3317fcc16c3..0fc4c3630780 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -18,17 +18,7 @@ | |||
18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | 20 | ||
21 | #define DRV_VERSION "0.4.2" | 21 | #define DRV_VERSION "0.4.3" |
22 | |||
23 | /* Addresses to scan: none | ||
24 | * This chip cannot be reliably autodetected. An empty eeprom | ||
25 | * located at 0x51 will pass the validation routine due to | ||
26 | * the way the registers are implemented. | ||
27 | */ | ||
28 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
29 | |||
30 | /* Module parameters */ | ||
31 | I2C_CLIENT_INSMOD; | ||
32 | 22 | ||
33 | #define PCF8563_REG_ST1 0x00 /* status */ | 23 | #define PCF8563_REG_ST1 0x00 /* status */ |
34 | #define PCF8563_REG_ST2 0x01 | 24 | #define PCF8563_REG_ST2 0x01 |
@@ -53,8 +43,10 @@ I2C_CLIENT_INSMOD; | |||
53 | #define PCF8563_SC_LV 0x80 /* low voltage */ | 43 | #define PCF8563_SC_LV 0x80 /* low voltage */ |
54 | #define PCF8563_MO_C 0x80 /* century */ | 44 | #define PCF8563_MO_C 0x80 /* century */ |
55 | 45 | ||
46 | static struct i2c_driver pcf8563_driver; | ||
47 | |||
56 | struct pcf8563 { | 48 | struct pcf8563 { |
57 | struct i2c_client client; | 49 | struct rtc_device *rtc; |
58 | /* | 50 | /* |
59 | * The meaning of MO_C bit varies by the chip type. | 51 | * The meaning of MO_C bit varies by the chip type. |
60 | * From PCF8563 datasheet: this bit is toggled when the years | 52 | * From PCF8563 datasheet: this bit is toggled when the years |
@@ -72,16 +64,13 @@ struct pcf8563 { | |||
72 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ | 64 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ |
73 | }; | 65 | }; |
74 | 66 | ||
75 | static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind); | ||
76 | static int pcf8563_detach(struct i2c_client *client); | ||
77 | |||
78 | /* | 67 | /* |
79 | * In the routines that deal directly with the pcf8563 hardware, we use | 68 | * In the routines that deal directly with the pcf8563 hardware, we use |
80 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | 69 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. |
81 | */ | 70 | */ |
82 | static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | 71 | static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) |
83 | { | 72 | { |
84 | struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); | 73 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
85 | unsigned char buf[13] = { PCF8563_REG_ST1 }; | 74 | unsigned char buf[13] = { PCF8563_REG_ST1 }; |
86 | 75 | ||
87 | struct i2c_msg msgs[] = { | 76 | struct i2c_msg msgs[] = { |
@@ -91,7 +80,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
91 | 80 | ||
92 | /* read registers */ | 81 | /* read registers */ |
93 | if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { | 82 | if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { |
94 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 83 | dev_err(&client->dev, "%s: read error\n", __func__); |
95 | return -EIO; | 84 | return -EIO; |
96 | } | 85 | } |
97 | 86 | ||
@@ -102,7 +91,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
102 | dev_dbg(&client->dev, | 91 | dev_dbg(&client->dev, |
103 | "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " | 92 | "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " |
104 | "mday=%02x, wday=%02x, mon=%02x, year=%02x\n", | 93 | "mday=%02x, wday=%02x, mon=%02x, year=%02x\n", |
105 | __FUNCTION__, | 94 | __func__, |
106 | buf[0], buf[1], buf[2], buf[3], | 95 | buf[0], buf[1], buf[2], buf[3], |
107 | buf[4], buf[5], buf[6], buf[7], | 96 | buf[4], buf[5], buf[6], buf[7], |
108 | buf[8]); | 97 | buf[8]); |
@@ -123,7 +112,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
123 | 112 | ||
124 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 113 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
125 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 114 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
126 | __FUNCTION__, | 115 | __func__, |
127 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 116 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
128 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 117 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
129 | 118 | ||
@@ -138,13 +127,13 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
138 | 127 | ||
139 | static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 128 | static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
140 | { | 129 | { |
141 | struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); | 130 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
142 | int i, err; | 131 | int i, err; |
143 | unsigned char buf[9]; | 132 | unsigned char buf[9]; |
144 | 133 | ||
145 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " | 134 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " |
146 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 135 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
147 | __FUNCTION__, | 136 | __func__, |
148 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 137 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
149 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 138 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
150 | 139 | ||
@@ -174,7 +163,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
174 | if (err != sizeof(data)) { | 163 | if (err != sizeof(data)) { |
175 | dev_err(&client->dev, | 164 | dev_err(&client->dev, |
176 | "%s: err=%d addr=%02x, data=%02x\n", | 165 | "%s: err=%d addr=%02x, data=%02x\n", |
177 | __FUNCTION__, err, data[0], data[1]); | 166 | __func__, err, data[0], data[1]); |
178 | return -EIO; | 167 | return -EIO; |
179 | } | 168 | } |
180 | }; | 169 | }; |
@@ -219,7 +208,7 @@ static int pcf8563_validate_client(struct i2c_client *client) | |||
219 | if (xfer != ARRAY_SIZE(msgs)) { | 208 | if (xfer != ARRAY_SIZE(msgs)) { |
220 | dev_err(&client->dev, | 209 | dev_err(&client->dev, |
221 | "%s: could not read register 0x%02X\n", | 210 | "%s: could not read register 0x%02X\n", |
222 | __FUNCTION__, pattern[i].reg); | 211 | __func__, pattern[i].reg); |
223 | 212 | ||
224 | return -EIO; | 213 | return -EIO; |
225 | } | 214 | } |
@@ -231,7 +220,7 @@ static int pcf8563_validate_client(struct i2c_client *client) | |||
231 | dev_dbg(&client->dev, | 220 | dev_dbg(&client->dev, |
232 | "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, " | 221 | "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, " |
233 | "max=%d, value=%d, raw=0x%02X\n", | 222 | "max=%d, value=%d, raw=0x%02X\n", |
234 | __FUNCTION__, i, pattern[i].reg, pattern[i].mask, | 223 | __func__, i, pattern[i].reg, pattern[i].mask, |
235 | pattern[i].min, pattern[i].max, | 224 | pattern[i].min, pattern[i].max, |
236 | value, buf); | 225 | value, buf); |
237 | 226 | ||
@@ -257,100 +246,75 @@ static const struct rtc_class_ops pcf8563_rtc_ops = { | |||
257 | .set_time = pcf8563_rtc_set_time, | 246 | .set_time = pcf8563_rtc_set_time, |
258 | }; | 247 | }; |
259 | 248 | ||
260 | static int pcf8563_attach(struct i2c_adapter *adapter) | 249 | static int pcf8563_probe(struct i2c_client *client, |
261 | { | 250 | const struct i2c_device_id *id) |
262 | return i2c_probe(adapter, &addr_data, pcf8563_probe); | ||
263 | } | ||
264 | |||
265 | static struct i2c_driver pcf8563_driver = { | ||
266 | .driver = { | ||
267 | .name = "pcf8563", | ||
268 | }, | ||
269 | .id = I2C_DRIVERID_PCF8563, | ||
270 | .attach_adapter = &pcf8563_attach, | ||
271 | .detach_client = &pcf8563_detach, | ||
272 | }; | ||
273 | |||
274 | static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) | ||
275 | { | 251 | { |
276 | struct pcf8563 *pcf8563; | 252 | struct pcf8563 *pcf8563; |
277 | struct i2c_client *client; | ||
278 | struct rtc_device *rtc; | ||
279 | 253 | ||
280 | int err = 0; | 254 | int err = 0; |
281 | 255 | ||
282 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | 256 | dev_dbg(&client->dev, "%s\n", __func__); |
283 | 257 | ||
284 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { | 258 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
285 | err = -ENODEV; | 259 | return -ENODEV; |
286 | goto exit; | ||
287 | } | ||
288 | 260 | ||
289 | if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) { | 261 | pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL); |
290 | err = -ENOMEM; | 262 | if (!pcf8563) |
291 | goto exit; | 263 | return -ENOMEM; |
292 | } | ||
293 | |||
294 | client = &pcf8563->client; | ||
295 | client->addr = address; | ||
296 | client->driver = &pcf8563_driver; | ||
297 | client->adapter = adapter; | ||
298 | |||
299 | strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE); | ||
300 | 264 | ||
301 | /* Verify the chip is really an PCF8563 */ | 265 | /* Verify the chip is really an PCF8563 */ |
302 | if (kind < 0) { | 266 | if (pcf8563_validate_client(client) < 0) { |
303 | if (pcf8563_validate_client(client) < 0) { | 267 | err = -ENODEV; |
304 | err = -ENODEV; | ||
305 | goto exit_kfree; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | /* Inform the i2c layer */ | ||
310 | if ((err = i2c_attach_client(client))) | ||
311 | goto exit_kfree; | 268 | goto exit_kfree; |
269 | } | ||
312 | 270 | ||
313 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | 271 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); |
314 | 272 | ||
315 | rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev, | 273 | pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name, |
316 | &pcf8563_rtc_ops, THIS_MODULE); | 274 | &client->dev, &pcf8563_rtc_ops, THIS_MODULE); |
317 | 275 | ||
318 | if (IS_ERR(rtc)) { | 276 | if (IS_ERR(pcf8563->rtc)) { |
319 | err = PTR_ERR(rtc); | 277 | err = PTR_ERR(pcf8563->rtc); |
320 | goto exit_detach; | 278 | goto exit_kfree; |
321 | } | 279 | } |
322 | 280 | ||
323 | i2c_set_clientdata(client, rtc); | 281 | i2c_set_clientdata(client, pcf8563); |
324 | 282 | ||
325 | return 0; | 283 | return 0; |
326 | 284 | ||
327 | exit_detach: | ||
328 | i2c_detach_client(client); | ||
329 | |||
330 | exit_kfree: | 285 | exit_kfree: |
331 | kfree(pcf8563); | 286 | kfree(pcf8563); |
332 | 287 | ||
333 | exit: | ||
334 | return err; | 288 | return err; |
335 | } | 289 | } |
336 | 290 | ||
337 | static int pcf8563_detach(struct i2c_client *client) | 291 | static int pcf8563_remove(struct i2c_client *client) |
338 | { | 292 | { |
339 | struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); | 293 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
340 | int err; | ||
341 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
342 | 294 | ||
343 | if (rtc) | 295 | if (pcf8563->rtc) |
344 | rtc_device_unregister(rtc); | 296 | rtc_device_unregister(pcf8563->rtc); |
345 | |||
346 | if ((err = i2c_detach_client(client))) | ||
347 | return err; | ||
348 | 297 | ||
349 | kfree(pcf8563); | 298 | kfree(pcf8563); |
350 | 299 | ||
351 | return 0; | 300 | return 0; |
352 | } | 301 | } |
353 | 302 | ||
303 | static const struct i2c_device_id pcf8563_id[] = { | ||
304 | { "pcf8563", 0 }, | ||
305 | { } | ||
306 | }; | ||
307 | MODULE_DEVICE_TABLE(i2c, pcf8563_id); | ||
308 | |||
309 | static struct i2c_driver pcf8563_driver = { | ||
310 | .driver = { | ||
311 | .name = "rtc-pcf8563", | ||
312 | }, | ||
313 | .probe = pcf8563_probe, | ||
314 | .remove = pcf8563_remove, | ||
315 | .id_table = pcf8563_id, | ||
316 | }; | ||
317 | |||
354 | static int __init pcf8563_init(void) | 318 | static int __init pcf8563_init(void) |
355 | { | 319 | { |
356 | return i2c_add_driver(&pcf8563_driver); | 320 | return i2c_add_driver(&pcf8563_driver); |
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 8b3997007506..3d09d8f0b1f0 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/mc146818rtc.h> | 18 | #include <linux/rtc.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c new file mode 100644 index 000000000000..8448eeb9d675 --- /dev/null +++ b/drivers/rtc/rtc-pl030.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * linux/drivers/rtc/rtc-pl030.c | ||
3 | * | ||
4 | * Copyright (C) 2000-2001 Deep Blue Solutions Ltd. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/rtc.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/amba/bus.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #define RTC_DR (0) | ||
18 | #define RTC_MR (4) | ||
19 | #define RTC_STAT (8) | ||
20 | #define RTC_EOI (8) | ||
21 | #define RTC_LR (12) | ||
22 | #define RTC_CR (16) | ||
23 | #define RTC_CR_MIE (1 << 0) | ||
24 | |||
25 | struct pl030_rtc { | ||
26 | struct rtc_device *rtc; | ||
27 | void __iomem *base; | ||
28 | }; | ||
29 | |||
30 | static irqreturn_t pl030_interrupt(int irq, void *dev_id) | ||
31 | { | ||
32 | struct pl030_rtc *rtc = dev_id; | ||
33 | writel(0, rtc->base + RTC_EOI); | ||
34 | return IRQ_HANDLED; | ||
35 | } | ||
36 | |||
37 | static int pl030_open(struct device *dev) | ||
38 | { | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static void pl030_release(struct device *dev) | ||
43 | { | ||
44 | } | ||
45 | |||
46 | static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
47 | { | ||
48 | return -ENOIOCTLCMD; | ||
49 | } | ||
50 | |||
51 | static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
52 | { | ||
53 | struct pl030_rtc *rtc = dev_get_drvdata(dev); | ||
54 | |||
55 | rtc_time_to_tm(readl(rtc->base + RTC_MR), &alrm->time); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
60 | { | ||
61 | struct pl030_rtc *rtc = dev_get_drvdata(dev); | ||
62 | unsigned long time; | ||
63 | int ret; | ||
64 | |||
65 | /* | ||
66 | * At the moment, we can only deal with non-wildcarded alarm times. | ||
67 | */ | ||
68 | ret = rtc_valid_tm(&alrm->time); | ||
69 | if (ret == 0) | ||
70 | ret = rtc_tm_to_time(&alrm->time, &time); | ||
71 | if (ret == 0) | ||
72 | writel(time, rtc->base + RTC_MR); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | static int pl030_read_time(struct device *dev, struct rtc_time *tm) | ||
77 | { | ||
78 | struct pl030_rtc *rtc = dev_get_drvdata(dev); | ||
79 | |||
80 | rtc_time_to_tm(readl(rtc->base + RTC_DR), tm); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Set the RTC time. Unfortunately, we can't accurately set | ||
87 | * the point at which the counter updates. | ||
88 | * | ||
89 | * Also, since RTC_LR is transferred to RTC_CR on next rising | ||
90 | * edge of the 1Hz clock, we must write the time one second | ||
91 | * in advance. | ||
92 | */ | ||
93 | static int pl030_set_time(struct device *dev, struct rtc_time *tm) | ||
94 | { | ||
95 | struct pl030_rtc *rtc = dev_get_drvdata(dev); | ||
96 | unsigned long time; | ||
97 | int ret; | ||
98 | |||
99 | ret = rtc_tm_to_time(tm, &time); | ||
100 | if (ret == 0) | ||
101 | writel(time + 1, rtc->base + RTC_LR); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | static const struct rtc_class_ops pl030_ops = { | ||
107 | .open = pl030_open, | ||
108 | .release = pl030_release, | ||
109 | .ioctl = pl030_ioctl, | ||
110 | .read_time = pl030_read_time, | ||
111 | .set_time = pl030_set_time, | ||
112 | .read_alarm = pl030_read_alarm, | ||
113 | .set_alarm = pl030_set_alarm, | ||
114 | }; | ||
115 | |||
116 | static int pl030_probe(struct amba_device *dev, void *id) | ||
117 | { | ||
118 | struct pl030_rtc *rtc; | ||
119 | int ret; | ||
120 | |||
121 | ret = amba_request_regions(dev, NULL); | ||
122 | if (ret) | ||
123 | goto err_req; | ||
124 | |||
125 | rtc = kmalloc(sizeof(*rtc), GFP_KERNEL); | ||
126 | if (!rtc) { | ||
127 | ret = -ENOMEM; | ||
128 | goto err_rtc; | ||
129 | } | ||
130 | |||
131 | rtc->base = ioremap(dev->res.start, SZ_4K); | ||
132 | if (!rtc->base) { | ||
133 | ret = -ENOMEM; | ||
134 | goto err_map; | ||
135 | } | ||
136 | |||
137 | __raw_writel(0, rtc->base + RTC_CR); | ||
138 | __raw_writel(0, rtc->base + RTC_EOI); | ||
139 | |||
140 | amba_set_drvdata(dev, rtc); | ||
141 | |||
142 | ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED, | ||
143 | "rtc-pl030", rtc); | ||
144 | if (ret) | ||
145 | goto err_irq; | ||
146 | |||
147 | rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops, | ||
148 | THIS_MODULE); | ||
149 | if (IS_ERR(rtc->rtc)) { | ||
150 | ret = PTR_ERR(rtc->rtc); | ||
151 | goto err_reg; | ||
152 | } | ||
153 | |||
154 | return 0; | ||
155 | |||
156 | err_reg: | ||
157 | free_irq(dev->irq[0], rtc); | ||
158 | err_irq: | ||
159 | iounmap(rtc->base); | ||
160 | err_map: | ||
161 | kfree(rtc); | ||
162 | err_rtc: | ||
163 | amba_release_regions(dev); | ||
164 | err_req: | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | static int pl030_remove(struct amba_device *dev) | ||
169 | { | ||
170 | struct pl030_rtc *rtc = amba_get_drvdata(dev); | ||
171 | |||
172 | amba_set_drvdata(dev, NULL); | ||
173 | |||
174 | writel(0, rtc->base + RTC_CR); | ||
175 | |||
176 | free_irq(dev->irq[0], rtc); | ||
177 | rtc_device_unregister(rtc->rtc); | ||
178 | iounmap(rtc->base); | ||
179 | kfree(rtc); | ||
180 | amba_release_regions(dev); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static struct amba_id pl030_ids[] = { | ||
186 | { | ||
187 | .id = 0x00041030, | ||
188 | .mask = 0x000fffff, | ||
189 | }, | ||
190 | { 0, 0 }, | ||
191 | }; | ||
192 | |||
193 | static struct amba_driver pl030_driver = { | ||
194 | .drv = { | ||
195 | .name = "rtc-pl030", | ||
196 | }, | ||
197 | .probe = pl030_probe, | ||
198 | .remove = pl030_remove, | ||
199 | .id_table = pl030_ids, | ||
200 | }; | ||
201 | |||
202 | static int __init pl030_init(void) | ||
203 | { | ||
204 | return amba_driver_register(&pl030_driver); | ||
205 | } | ||
206 | |||
207 | static void __exit pl030_exit(void) | ||
208 | { | ||
209 | amba_driver_unregister(&pl030_driver); | ||
210 | } | ||
211 | |||
212 | module_init(pl030_init); | ||
213 | module_exit(pl030_exit); | ||
214 | |||
215 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); | ||
216 | MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver"); | ||
217 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 2fd49edcc712..08b4610ec5a6 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -12,23 +12,12 @@ | |||
12 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
13 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
14 | */ | 14 | */ |
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/module.h> | 15 | #include <linux/module.h> |
18 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
19 | #include <linux/init.h> | 17 | #include <linux/init.h> |
20 | #include <linux/fs.h> | ||
21 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
22 | #include <linux/string.h> | ||
23 | #include <linux/pm.h> | ||
24 | #include <linux/bitops.h> | ||
25 | |||
26 | #include <linux/amba/bus.h> | 19 | #include <linux/amba/bus.h> |
27 | 20 | #include <linux/io.h> | |
28 | #include <asm/io.h> | ||
29 | #include <asm/hardware.h> | ||
30 | #include <asm/irq.h> | ||
31 | #include <asm/rtc.h> | ||
32 | 21 | ||
33 | /* | 22 | /* |
34 | * Register definitions | 23 | * Register definitions |
@@ -142,13 +131,12 @@ static int pl031_remove(struct amba_device *adev) | |||
142 | { | 131 | { |
143 | struct pl031_local *ldata = dev_get_drvdata(&adev->dev); | 132 | struct pl031_local *ldata = dev_get_drvdata(&adev->dev); |
144 | 133 | ||
145 | if (ldata) { | 134 | amba_set_drvdata(adev, NULL); |
146 | dev_set_drvdata(&adev->dev, NULL); | 135 | free_irq(adev->irq[0], ldata->rtc); |
147 | free_irq(adev->irq[0], ldata->rtc); | 136 | rtc_device_unregister(ldata->rtc); |
148 | rtc_device_unregister(ldata->rtc); | 137 | iounmap(ldata->base); |
149 | iounmap(ldata->base); | 138 | kfree(ldata); |
150 | kfree(ldata); | 139 | amba_release_regions(adev); |
151 | } | ||
152 | 140 | ||
153 | return 0; | 141 | return 0; |
154 | } | 142 | } |
@@ -158,13 +146,15 @@ static int pl031_probe(struct amba_device *adev, void *id) | |||
158 | int ret; | 146 | int ret; |
159 | struct pl031_local *ldata; | 147 | struct pl031_local *ldata; |
160 | 148 | ||
149 | ret = amba_request_regions(adev, NULL); | ||
150 | if (ret) | ||
151 | goto err_req; | ||
161 | 152 | ||
162 | ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL); | 153 | ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL); |
163 | if (!ldata) { | 154 | if (!ldata) { |
164 | ret = -ENOMEM; | 155 | ret = -ENOMEM; |
165 | goto out; | 156 | goto out; |
166 | } | 157 | } |
167 | dev_set_drvdata(&adev->dev, ldata); | ||
168 | 158 | ||
169 | ldata->base = ioremap(adev->res.start, | 159 | ldata->base = ioremap(adev->res.start, |
170 | adev->res.end - adev->res.start + 1); | 160 | adev->res.end - adev->res.start + 1); |
@@ -173,6 +163,8 @@ static int pl031_probe(struct amba_device *adev, void *id) | |||
173 | goto out_no_remap; | 163 | goto out_no_remap; |
174 | } | 164 | } |
175 | 165 | ||
166 | amba_set_drvdata(adev, ldata); | ||
167 | |||
176 | if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED, | 168 | if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED, |
177 | "rtc-pl031", ldata->rtc)) { | 169 | "rtc-pl031", ldata->rtc)) { |
178 | ret = -EIO; | 170 | ret = -EIO; |
@@ -192,10 +184,12 @@ out_no_rtc: | |||
192 | free_irq(adev->irq[0], ldata->rtc); | 184 | free_irq(adev->irq[0], ldata->rtc); |
193 | out_no_irq: | 185 | out_no_irq: |
194 | iounmap(ldata->base); | 186 | iounmap(ldata->base); |
187 | amba_set_drvdata(adev, NULL); | ||
195 | out_no_remap: | 188 | out_no_remap: |
196 | dev_set_drvdata(&adev->dev, NULL); | ||
197 | kfree(ldata); | 189 | kfree(ldata); |
198 | out: | 190 | out: |
191 | amba_release_regions(adev); | ||
192 | err_req: | ||
199 | return ret; | 193 | return ret; |
200 | } | 194 | } |
201 | 195 | ||
diff --git a/drivers/rtc/rtc-ppc.c b/drivers/rtc/rtc-ppc.c new file mode 100644 index 000000000000..c8e97e25ef7e --- /dev/null +++ b/drivers/rtc/rtc-ppc.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * RTC driver for ppc_md RTC functions | ||
3 | * | ||
4 | * © 2007 Red Hat, Inc. | ||
5 | * | ||
6 | * Author: David Woodhouse <dwmw2@infradead.org> | ||
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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <asm/machdep.h> | ||
19 | |||
20 | static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
21 | { | ||
22 | ppc_md.get_rtc_time(tm); | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
27 | { | ||
28 | return ppc_md.set_rtc_time(tm); | ||
29 | } | ||
30 | |||
31 | static const struct rtc_class_ops ppc_rtc_ops = { | ||
32 | .set_time = ppc_rtc_set_time, | ||
33 | .read_time = ppc_rtc_read_time, | ||
34 | }; | ||
35 | |||
36 | static struct rtc_device *rtc; | ||
37 | static struct platform_device *ppc_rtc_pdev; | ||
38 | |||
39 | static int __init ppc_rtc_init(void) | ||
40 | { | ||
41 | if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time) | ||
42 | return -ENODEV; | ||
43 | |||
44 | ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0); | ||
45 | if (IS_ERR(ppc_rtc_pdev)) | ||
46 | return PTR_ERR(ppc_rtc_pdev); | ||
47 | |||
48 | rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev, | ||
49 | &ppc_rtc_ops, THIS_MODULE); | ||
50 | if (IS_ERR(rtc)) { | ||
51 | platform_device_unregister(ppc_rtc_pdev); | ||
52 | return PTR_ERR(rtc); | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void __exit ppc_rtc_exit(void) | ||
59 | { | ||
60 | rtc_device_unregister(rtc); | ||
61 | platform_device_unregister(ppc_rtc_pdev); | ||
62 | } | ||
63 | |||
64 | module_init(ppc_rtc_init); | ||
65 | module_exit(ppc_rtc_exit); | ||
66 | |||
67 | MODULE_LICENSE("GPL"); | ||
68 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | ||
69 | MODULE_DESCRIPTION("Generic RTC class driver for PowerPC"); | ||
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 8d300e6d0d9e..0c6257a034ff 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -108,12 +108,10 @@ void rtc_proc_add_device(struct rtc_device *rtc) | |||
108 | if (rtc->id == 0) { | 108 | if (rtc->id == 0) { |
109 | struct proc_dir_entry *ent; | 109 | struct proc_dir_entry *ent; |
110 | 110 | ||
111 | ent = create_proc_entry("driver/rtc", 0, NULL); | 111 | ent = proc_create_data("driver/rtc", 0, NULL, |
112 | if (ent) { | 112 | &rtc_proc_fops, rtc); |
113 | ent->proc_fops = &rtc_proc_fops; | 113 | if (ent) |
114 | ent->owner = rtc->owner; | 114 | ent->owner = rtc->owner; |
115 | ent->data = rtc; | ||
116 | } | ||
117 | } | 115 | } |
118 | } | 116 | } |
119 | 117 | ||
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index 66eb133bf5fd..1c14d4497c4d 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c | |||
@@ -228,7 +228,7 @@ static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
228 | ndelay(700); /* CE:L */ | 228 | ndelay(700); /* CE:L */ |
229 | 229 | ||
230 | if (cnt++ > 100) { | 230 | if (cnt++ > 100) { |
231 | dev_err(dev, "%s: timeout error\n", __FUNCTION__); | 231 | dev_err(dev, "%s: timeout error\n", __func__); |
232 | return -EIO; | 232 | return -EIO; |
233 | } | 233 | } |
234 | } | 234 | } |
@@ -289,7 +289,7 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
289 | ndelay(700); /* CE:L */ | 289 | ndelay(700); /* CE:L */ |
290 | 290 | ||
291 | if (cnt++ > 100) { | 291 | if (cnt++ > 100) { |
292 | dev_err(dev, "%s: timeout error\n", __FUNCTION__); | 292 | dev_err(dev, "%s: timeout error\n", __func__); |
293 | return -EIO; | 293 | return -EIO; |
294 | } | 294 | } |
295 | } | 295 | } |
@@ -421,3 +421,4 @@ MODULE_VERSION(DRV_VERSION); | |||
421 | MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>"); | 421 | MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>"); |
422 | MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver"); | 422 | MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver"); |
423 | MODULE_LICENSE("GPL"); | 423 | MODULE_LICENSE("GPL"); |
424 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 6b67b5097927..56caf6b2c3e5 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -69,6 +69,15 @@ enum rtc_type { | |||
69 | rtc_rv5c387a, | 69 | rtc_rv5c387a, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static const struct i2c_device_id rs5c372_id[] = { | ||
73 | { "rs5c372a", rtc_rs5c372a }, | ||
74 | { "rs5c372b", rtc_rs5c372b }, | ||
75 | { "rv5c386", rtc_rv5c386 }, | ||
76 | { "rv5c387a", rtc_rv5c387a }, | ||
77 | { } | ||
78 | }; | ||
79 | MODULE_DEVICE_TABLE(i2c, rs5c372_id); | ||
80 | |||
72 | /* REVISIT: this assumes that: | 81 | /* REVISIT: this assumes that: |
73 | * - we're in the 21st century, so it's safe to ignore the century | 82 | * - we're in the 21st century, so it's safe to ignore the century |
74 | * bit for rv5c38[67] (REG_MONTH bit 7); | 83 | * bit for rv5c38[67] (REG_MONTH bit 7); |
@@ -99,7 +108,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) | |||
99 | * least 80219 chips; this works around that bug. | 108 | * least 80219 chips; this works around that bug. |
100 | */ | 109 | */ |
101 | if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { | 110 | if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { |
102 | pr_debug("%s: can't read registers\n", rs5c->rtc->name); | 111 | dev_warn(&client->dev, "can't read registers\n"); |
103 | return -EIO; | 112 | return -EIO; |
104 | } | 113 | } |
105 | 114 | ||
@@ -166,7 +175,7 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
166 | 175 | ||
167 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 176 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
168 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 177 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
169 | __FUNCTION__, | 178 | __func__, |
170 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 179 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
171 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 180 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
172 | 181 | ||
@@ -181,7 +190,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
181 | 190 | ||
182 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " | 191 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " |
183 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 192 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
184 | __FUNCTION__, | 193 | __func__, |
185 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 194 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
186 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 195 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
187 | 196 | ||
@@ -195,7 +204,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
195 | buf[7] = BIN2BCD(tm->tm_year - 100); | 204 | buf[7] = BIN2BCD(tm->tm_year - 100); |
196 | 205 | ||
197 | if ((i2c_master_send(client, buf, 8)) != 8) { | 206 | if ((i2c_master_send(client, buf, 8)) != 8) { |
198 | dev_err(&client->dev, "%s: write error\n", __FUNCTION__); | 207 | dev_err(&client->dev, "%s: write error\n", __func__); |
199 | return -EIO; | 208 | return -EIO; |
200 | } | 209 | } |
201 | 210 | ||
@@ -220,7 +229,7 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) | |||
220 | *osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768; | 229 | *osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768; |
221 | 230 | ||
222 | if (trim) { | 231 | if (trim) { |
223 | dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, tmp); | 232 | dev_dbg(&client->dev, "%s: raw trim=%x\n", __func__, tmp); |
224 | tmp &= RS5C372_TRIM_MASK; | 233 | tmp &= RS5C372_TRIM_MASK; |
225 | if (tmp & 0x3e) { | 234 | if (tmp & 0x3e) { |
226 | int t = tmp & 0x3f; | 235 | int t = tmp & 0x3f; |
@@ -494,13 +503,14 @@ static void rs5c_sysfs_unregister(struct device *dev) | |||
494 | 503 | ||
495 | static struct i2c_driver rs5c372_driver; | 504 | static struct i2c_driver rs5c372_driver; |
496 | 505 | ||
497 | static int rs5c372_probe(struct i2c_client *client) | 506 | static int rs5c372_probe(struct i2c_client *client, |
507 | const struct i2c_device_id *id) | ||
498 | { | 508 | { |
499 | int err = 0; | 509 | int err = 0; |
500 | struct rs5c372 *rs5c372; | 510 | struct rs5c372 *rs5c372; |
501 | struct rtc_time tm; | 511 | struct rtc_time tm; |
502 | 512 | ||
503 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | 513 | dev_dbg(&client->dev, "%s\n", __func__); |
504 | 514 | ||
505 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | 515 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { |
506 | err = -ENODEV; | 516 | err = -ENODEV; |
@@ -512,29 +522,17 @@ static int rs5c372_probe(struct i2c_client *client) | |||
512 | goto exit; | 522 | goto exit; |
513 | } | 523 | } |
514 | 524 | ||
515 | /* we read registers 0x0f then 0x00-0x0f; skip the first one */ | ||
516 | rs5c372->regs=&rs5c372->buf[1]; | ||
517 | |||
518 | rs5c372->client = client; | 525 | rs5c372->client = client; |
519 | i2c_set_clientdata(client, rs5c372); | 526 | i2c_set_clientdata(client, rs5c372); |
527 | rs5c372->type = id->driver_data; | ||
528 | |||
529 | /* we read registers 0x0f then 0x00-0x0f; skip the first one */ | ||
530 | rs5c372->regs = &rs5c372->buf[1]; | ||
520 | 531 | ||
521 | err = rs5c_get_regs(rs5c372); | 532 | err = rs5c_get_regs(rs5c372); |
522 | if (err < 0) | 533 | if (err < 0) |
523 | goto exit_kfree; | 534 | goto exit_kfree; |
524 | 535 | ||
525 | if (strcmp(client->name, "rs5c372a") == 0) | ||
526 | rs5c372->type = rtc_rs5c372a; | ||
527 | else if (strcmp(client->name, "rs5c372b") == 0) | ||
528 | rs5c372->type = rtc_rs5c372b; | ||
529 | else if (strcmp(client->name, "rv5c386") == 0) | ||
530 | rs5c372->type = rtc_rv5c386; | ||
531 | else if (strcmp(client->name, "rv5c387a") == 0) | ||
532 | rs5c372->type = rtc_rv5c387a; | ||
533 | else { | ||
534 | rs5c372->type = rtc_rs5c372b; | ||
535 | dev_warn(&client->dev, "assuming rs5c372b\n"); | ||
536 | } | ||
537 | |||
538 | /* clock may be set for am/pm or 24 hr time */ | 536 | /* clock may be set for am/pm or 24 hr time */ |
539 | switch (rs5c372->type) { | 537 | switch (rs5c372->type) { |
540 | case rtc_rs5c372a: | 538 | case rtc_rs5c372a: |
@@ -651,6 +649,7 @@ static struct i2c_driver rs5c372_driver = { | |||
651 | }, | 649 | }, |
652 | .probe = rs5c372_probe, | 650 | .probe = rs5c372_probe, |
653 | .remove = rs5c372_remove, | 651 | .remove = rs5c372_remove, |
652 | .id_table = rs5c372_id, | ||
654 | }; | 653 | }; |
655 | 654 | ||
656 | static __init int rs5c372_init(void) | 655 | static __init int rs5c372_init(void) |
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index e8abc90c32c5..a6fa1f2f2ca6 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
@@ -34,6 +34,12 @@ | |||
34 | #define S35390A_FLAG_RESET 0x80 | 34 | #define S35390A_FLAG_RESET 0x80 |
35 | #define S35390A_FLAG_TEST 0x01 | 35 | #define S35390A_FLAG_TEST 0x01 |
36 | 36 | ||
37 | static const struct i2c_device_id s35390a_id[] = { | ||
38 | { "s35390a", 0 }, | ||
39 | { } | ||
40 | }; | ||
41 | MODULE_DEVICE_TABLE(i2c, s35390a_id); | ||
42 | |||
37 | struct s35390a { | 43 | struct s35390a { |
38 | struct i2c_client *client[8]; | 44 | struct i2c_client *client[8]; |
39 | struct rtc_device *rtc; | 45 | struct rtc_device *rtc; |
@@ -195,7 +201,8 @@ static const struct rtc_class_ops s35390a_rtc_ops = { | |||
195 | 201 | ||
196 | static struct i2c_driver s35390a_driver; | 202 | static struct i2c_driver s35390a_driver; |
197 | 203 | ||
198 | static int s35390a_probe(struct i2c_client *client) | 204 | static int s35390a_probe(struct i2c_client *client, |
205 | const struct i2c_device_id *id) | ||
199 | { | 206 | { |
200 | int err; | 207 | int err; |
201 | unsigned int i; | 208 | unsigned int i; |
@@ -220,7 +227,7 @@ static int s35390a_probe(struct i2c_client *client) | |||
220 | /* This chip uses multiple addresses, use dummy devices for them */ | 227 | /* This chip uses multiple addresses, use dummy devices for them */ |
221 | for (i = 1; i < 8; ++i) { | 228 | for (i = 1; i < 8; ++i) { |
222 | s35390a->client[i] = i2c_new_dummy(client->adapter, | 229 | s35390a->client[i] = i2c_new_dummy(client->adapter, |
223 | client->addr + i, "rtc-s35390a"); | 230 | client->addr + i); |
224 | if (!s35390a->client[i]) { | 231 | if (!s35390a->client[i]) { |
225 | dev_err(&client->dev, "Address %02x unavailable\n", | 232 | dev_err(&client->dev, "Address %02x unavailable\n", |
226 | client->addr + i); | 233 | client->addr + i); |
@@ -296,6 +303,7 @@ static struct i2c_driver s35390a_driver = { | |||
296 | }, | 303 | }, |
297 | .probe = s35390a_probe, | 304 | .probe = s35390a_probe, |
298 | .remove = s35390a_remove, | 305 | .remove = s35390a_remove, |
306 | .id_table = s35390a_id, | ||
299 | }; | 307 | }; |
300 | 308 | ||
301 | static int __init s35390a_rtc_init(void) | 309 | static int __init s35390a_rtc_init(void) |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 86766f1f2496..fed86e507fdf 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -26,10 +26,6 @@ | |||
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/io.h> | 27 | #include <asm/io.h> |
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/rtc.h> | ||
30 | |||
31 | #include <asm/mach/time.h> | ||
32 | |||
33 | #include <asm/plat-s3c/regs-rtc.h> | 29 | #include <asm/plat-s3c/regs-rtc.h> |
34 | 30 | ||
35 | /* I have yet to find an S3C implementation with more than one | 31 | /* I have yet to find an S3C implementation with more than one |
@@ -68,7 +64,7 @@ static void s3c_rtc_setaie(int to) | |||
68 | { | 64 | { |
69 | unsigned int tmp; | 65 | unsigned int tmp; |
70 | 66 | ||
71 | pr_debug("%s: aie=%d\n", __FUNCTION__, to); | 67 | pr_debug("%s: aie=%d\n", __func__, to); |
72 | 68 | ||
73 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 69 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
74 | 70 | ||
@@ -82,7 +78,7 @@ static void s3c_rtc_setpie(int to) | |||
82 | { | 78 | { |
83 | unsigned int tmp; | 79 | unsigned int tmp; |
84 | 80 | ||
85 | pr_debug("%s: pie=%d\n", __FUNCTION__, to); | 81 | pr_debug("%s: pie=%d\n", __func__, to); |
86 | 82 | ||
87 | spin_lock_irq(&s3c_rtc_pie_lock); | 83 | spin_lock_irq(&s3c_rtc_pie_lock); |
88 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | 84 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; |
@@ -457,7 +453,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
457 | struct resource *res; | 453 | struct resource *res; |
458 | int ret; | 454 | int ret; |
459 | 455 | ||
460 | pr_debug("%s: probe=%p\n", __FUNCTION__, pdev); | 456 | pr_debug("%s: probe=%p\n", __func__, pdev); |
461 | 457 | ||
462 | /* find the IRQs */ | 458 | /* find the IRQs */ |
463 | 459 | ||
@@ -592,3 +588,4 @@ module_exit(s3c_rtc_exit); | |||
592 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); | 588 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); |
593 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 589 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
594 | MODULE_LICENSE("GPL"); | 590 | MODULE_LICENSE("GPL"); |
591 | MODULE_ALIAS("platform:s3c2410-rtc"); | ||
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index ee253cc45de1..f47294c60148 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -33,7 +33,6 @@ | |||
33 | 33 | ||
34 | #include <asm/hardware.h> | 34 | #include <asm/hardware.h> |
35 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
36 | #include <asm/rtc.h> | ||
37 | 36 | ||
38 | #ifdef CONFIG_ARCH_PXA | 37 | #ifdef CONFIG_ARCH_PXA |
39 | #include <asm/arch/pxa-regs.h> | 38 | #include <asm/arch/pxa-regs.h> |
@@ -47,6 +46,42 @@ static unsigned long rtc_freq = 1024; | |||
47 | static struct rtc_time rtc_alarm; | 46 | static struct rtc_time rtc_alarm; |
48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
49 | 48 | ||
49 | static inline int rtc_periodic_alarm(struct rtc_time *tm) | ||
50 | { | ||
51 | return (tm->tm_year == -1) || | ||
52 | ((unsigned)tm->tm_mon >= 12) || | ||
53 | ((unsigned)(tm->tm_mday - 1) >= 31) || | ||
54 | ((unsigned)tm->tm_hour > 23) || | ||
55 | ((unsigned)tm->tm_min > 59) || | ||
56 | ((unsigned)tm->tm_sec > 59); | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Calculate the next alarm time given the requested alarm time mask | ||
61 | * and the current time. | ||
62 | */ | ||
63 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) | ||
64 | { | ||
65 | unsigned long next_time; | ||
66 | unsigned long now_time; | ||
67 | |||
68 | next->tm_year = now->tm_year; | ||
69 | next->tm_mon = now->tm_mon; | ||
70 | next->tm_mday = now->tm_mday; | ||
71 | next->tm_hour = alrm->tm_hour; | ||
72 | next->tm_min = alrm->tm_min; | ||
73 | next->tm_sec = alrm->tm_sec; | ||
74 | |||
75 | rtc_tm_to_time(now, &now_time); | ||
76 | rtc_tm_to_time(next, &next_time); | ||
77 | |||
78 | if (next_time < now_time) { | ||
79 | /* Advance one day */ | ||
80 | next_time += 60 * 60 * 24; | ||
81 | rtc_time_to_tm(next_time, next); | ||
82 | } | ||
83 | } | ||
84 | |||
50 | static int rtc_update_alarm(struct rtc_time *alrm) | 85 | static int rtc_update_alarm(struct rtc_time *alrm) |
51 | { | 86 | { |
52 | struct rtc_time alarm_tm, now_tm; | 87 | struct rtc_time alarm_tm, now_tm; |
@@ -331,14 +366,14 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
331 | RCNR = 0; | 366 | RCNR = 0; |
332 | } | 367 | } |
333 | 368 | ||
369 | device_init_wakeup(&pdev->dev, 1); | ||
370 | |||
334 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 371 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
335 | THIS_MODULE); | 372 | THIS_MODULE); |
336 | 373 | ||
337 | if (IS_ERR(rtc)) | 374 | if (IS_ERR(rtc)) |
338 | return PTR_ERR(rtc); | 375 | return PTR_ERR(rtc); |
339 | 376 | ||
340 | device_init_wakeup(&pdev->dev, 1); | ||
341 | |||
342 | platform_set_drvdata(pdev, rtc); | 377 | platform_set_drvdata(pdev, rtc); |
343 | 378 | ||
344 | return 0; | 379 | return 0; |
@@ -399,3 +434,4 @@ module_exit(sa1100_rtc_exit); | |||
399 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 434 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
400 | MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); | 435 | MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); |
401 | MODULE_LICENSE("GPL"); | 436 | MODULE_LICENSE("GPL"); |
437 | MODULE_ALIAS("platform:sa1100-rtc"); | ||
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index c1d6a1880ccf..1f88e9e914ec 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * SuperH On-Chip RTC Support | 2 | * SuperH On-Chip RTC Support |
3 | * | 3 | * |
4 | * Copyright (C) 2006, 2007 Paul Mundt | 4 | * Copyright (C) 2006, 2007, 2008 Paul Mundt |
5 | * Copyright (C) 2006 Jamie Lenehan | 5 | * Copyright (C) 2006 Jamie Lenehan |
6 | * Copyright (C) 2008 Angelo Castello | ||
6 | * | 7 | * |
7 | * Based on the old arch/sh/kernel/cpu/rtc.c by: | 8 | * Based on the old arch/sh/kernel/cpu/rtc.c by: |
8 | * | 9 | * |
@@ -26,7 +27,7 @@ | |||
26 | #include <asm/rtc.h> | 27 | #include <asm/rtc.h> |
27 | 28 | ||
28 | #define DRV_NAME "sh-rtc" | 29 | #define DRV_NAME "sh-rtc" |
29 | #define DRV_VERSION "0.1.6" | 30 | #define DRV_VERSION "0.2.0" |
30 | 31 | ||
31 | #define RTC_REG(r) ((r) * rtc_reg_size) | 32 | #define RTC_REG(r) ((r) * rtc_reg_size) |
32 | 33 | ||
@@ -63,6 +64,13 @@ | |||
63 | /* ALARM Bits - or with BCD encoded value */ | 64 | /* ALARM Bits - or with BCD encoded value */ |
64 | #define AR_ENB 0x80 /* Enable for alarm cmp */ | 65 | #define AR_ENB 0x80 /* Enable for alarm cmp */ |
65 | 66 | ||
67 | /* Period Bits */ | ||
68 | #define PF_HP 0x100 /* Enable Half Period to support 8,32,128Hz */ | ||
69 | #define PF_COUNT 0x200 /* Half periodic counter */ | ||
70 | #define PF_OXS 0x400 /* Periodic One x Second */ | ||
71 | #define PF_KOU 0x800 /* Kernel or User periodic request 1=kernel */ | ||
72 | #define PF_MASK 0xf00 | ||
73 | |||
66 | /* RCR1 Bits */ | 74 | /* RCR1 Bits */ |
67 | #define RCR1_CF 0x80 /* Carry Flag */ | 75 | #define RCR1_CF 0x80 /* Carry Flag */ |
68 | #define RCR1_CIE 0x10 /* Carry Interrupt Enable */ | 76 | #define RCR1_CIE 0x10 /* Carry Interrupt Enable */ |
@@ -84,33 +92,24 @@ struct sh_rtc { | |||
84 | unsigned int alarm_irq, periodic_irq, carry_irq; | 92 | unsigned int alarm_irq, periodic_irq, carry_irq; |
85 | struct rtc_device *rtc_dev; | 93 | struct rtc_device *rtc_dev; |
86 | spinlock_t lock; | 94 | spinlock_t lock; |
87 | int rearm_aie; | ||
88 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ | 95 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ |
96 | unsigned short periodic_freq; | ||
89 | }; | 97 | }; |
90 | 98 | ||
91 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | 99 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) |
92 | { | 100 | { |
93 | struct platform_device *pdev = to_platform_device(dev_id); | 101 | struct sh_rtc *rtc = dev_id; |
94 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 102 | unsigned int tmp; |
95 | unsigned int tmp, events = 0; | ||
96 | 103 | ||
97 | spin_lock(&rtc->lock); | 104 | spin_lock(&rtc->lock); |
98 | 105 | ||
99 | tmp = readb(rtc->regbase + RCR1); | 106 | tmp = readb(rtc->regbase + RCR1); |
100 | tmp &= ~RCR1_CF; | 107 | tmp &= ~RCR1_CF; |
101 | |||
102 | if (rtc->rearm_aie) { | ||
103 | if (tmp & RCR1_AF) | ||
104 | tmp &= ~RCR1_AF; /* try to clear AF again */ | ||
105 | else { | ||
106 | tmp |= RCR1_AIE; /* AF has cleared, rearm IRQ */ | ||
107 | rtc->rearm_aie = 0; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | writeb(tmp, rtc->regbase + RCR1); | 108 | writeb(tmp, rtc->regbase + RCR1); |
112 | 109 | ||
113 | rtc_update_irq(rtc->rtc_dev, 1, events); | 110 | /* Users have requested One x Second IRQ */ |
111 | if (rtc->periodic_freq & PF_OXS) | ||
112 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | ||
114 | 113 | ||
115 | spin_unlock(&rtc->lock); | 114 | spin_unlock(&rtc->lock); |
116 | 115 | ||
@@ -119,47 +118,48 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | |||
119 | 118 | ||
120 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | 119 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) |
121 | { | 120 | { |
122 | struct platform_device *pdev = to_platform_device(dev_id); | 121 | struct sh_rtc *rtc = dev_id; |
123 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 122 | unsigned int tmp; |
124 | unsigned int tmp, events = 0; | ||
125 | 123 | ||
126 | spin_lock(&rtc->lock); | 124 | spin_lock(&rtc->lock); |
127 | 125 | ||
128 | tmp = readb(rtc->regbase + RCR1); | 126 | tmp = readb(rtc->regbase + RCR1); |
129 | 127 | tmp &= ~(RCR1_AF | RCR1_AIE); | |
130 | /* | ||
131 | * If AF is set then the alarm has triggered. If we clear AF while | ||
132 | * the alarm time still matches the RTC time then AF will | ||
133 | * immediately be set again, and if AIE is enabled then the alarm | ||
134 | * interrupt will immediately be retrigger. So we clear AIE here | ||
135 | * and use rtc->rearm_aie so that the carry interrupt will keep | ||
136 | * trying to clear AF and once it stays cleared it'll re-enable | ||
137 | * AIE. | ||
138 | */ | ||
139 | if (tmp & RCR1_AF) { | ||
140 | events |= RTC_AF | RTC_IRQF; | ||
141 | |||
142 | tmp &= ~(RCR1_AF|RCR1_AIE); | ||
143 | |||
144 | writeb(tmp, rtc->regbase + RCR1); | 128 | writeb(tmp, rtc->regbase + RCR1); |
145 | 129 | ||
146 | rtc->rearm_aie = 1; | 130 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); |
147 | |||
148 | rtc_update_irq(rtc->rtc_dev, 1, events); | ||
149 | } | ||
150 | 131 | ||
151 | spin_unlock(&rtc->lock); | 132 | spin_unlock(&rtc->lock); |
133 | |||
152 | return IRQ_HANDLED; | 134 | return IRQ_HANDLED; |
153 | } | 135 | } |
154 | 136 | ||
155 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | 137 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) |
156 | { | 138 | { |
157 | struct platform_device *pdev = to_platform_device(dev_id); | 139 | struct sh_rtc *rtc = dev_id; |
158 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 140 | struct rtc_device *rtc_dev = rtc->rtc_dev; |
141 | unsigned int tmp; | ||
159 | 142 | ||
160 | spin_lock(&rtc->lock); | 143 | spin_lock(&rtc->lock); |
161 | 144 | ||
162 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | 145 | tmp = readb(rtc->regbase + RCR2); |
146 | tmp &= ~RCR2_PEF; | ||
147 | writeb(tmp, rtc->regbase + RCR2); | ||
148 | |||
149 | /* Half period enabled than one skipped and the next notified */ | ||
150 | if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) | ||
151 | rtc->periodic_freq &= ~PF_COUNT; | ||
152 | else { | ||
153 | if (rtc->periodic_freq & PF_HP) | ||
154 | rtc->periodic_freq |= PF_COUNT; | ||
155 | if (rtc->periodic_freq & PF_KOU) { | ||
156 | spin_lock(&rtc_dev->irq_task_lock); | ||
157 | if (rtc_dev->irq_task) | ||
158 | rtc_dev->irq_task->func(rtc_dev->irq_task->private_data); | ||
159 | spin_unlock(&rtc_dev->irq_task_lock); | ||
160 | } else | ||
161 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | ||
162 | } | ||
163 | 163 | ||
164 | spin_unlock(&rtc->lock); | 164 | spin_unlock(&rtc->lock); |
165 | 165 | ||
@@ -176,8 +176,8 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) | |||
176 | tmp = readb(rtc->regbase + RCR2); | 176 | tmp = readb(rtc->regbase + RCR2); |
177 | 177 | ||
178 | if (enable) { | 178 | if (enable) { |
179 | tmp &= ~RCR2_PESMASK; | 179 | tmp &= ~RCR2_PEF; /* Clear PES bit */ |
180 | tmp |= RCR2_PEF | (2 << 4); | 180 | tmp |= (rtc->periodic_freq & ~PF_HP); /* Set PES2-0 */ |
181 | } else | 181 | } else |
182 | tmp &= ~(RCR2_PESMASK | RCR2_PEF); | 182 | tmp &= ~(RCR2_PESMASK | RCR2_PEF); |
183 | 183 | ||
@@ -186,82 +186,81 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) | |||
186 | spin_unlock_irq(&rtc->lock); | 186 | spin_unlock_irq(&rtc->lock); |
187 | } | 187 | } |
188 | 188 | ||
189 | static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) | 189 | static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq) |
190 | { | 190 | { |
191 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 191 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
192 | unsigned int tmp; | 192 | int tmp, ret = 0; |
193 | 193 | ||
194 | spin_lock_irq(&rtc->lock); | 194 | spin_lock_irq(&rtc->lock); |
195 | tmp = rtc->periodic_freq & PF_MASK; | ||
195 | 196 | ||
196 | tmp = readb(rtc->regbase + RCR1); | 197 | switch (freq) { |
197 | 198 | case 0: | |
198 | if (!enable) { | 199 | rtc->periodic_freq = 0x00; |
199 | tmp &= ~RCR1_AIE; | 200 | break; |
200 | rtc->rearm_aie = 0; | 201 | case 1: |
201 | } else if (rtc->rearm_aie == 0) | 202 | rtc->periodic_freq = 0x60; |
202 | tmp |= RCR1_AIE; | 203 | break; |
204 | case 2: | ||
205 | rtc->periodic_freq = 0x50; | ||
206 | break; | ||
207 | case 4: | ||
208 | rtc->periodic_freq = 0x40; | ||
209 | break; | ||
210 | case 8: | ||
211 | rtc->periodic_freq = 0x30 | PF_HP; | ||
212 | break; | ||
213 | case 16: | ||
214 | rtc->periodic_freq = 0x30; | ||
215 | break; | ||
216 | case 32: | ||
217 | rtc->periodic_freq = 0x20 | PF_HP; | ||
218 | break; | ||
219 | case 64: | ||
220 | rtc->periodic_freq = 0x20; | ||
221 | break; | ||
222 | case 128: | ||
223 | rtc->periodic_freq = 0x10 | PF_HP; | ||
224 | break; | ||
225 | case 256: | ||
226 | rtc->periodic_freq = 0x10; | ||
227 | break; | ||
228 | default: | ||
229 | ret = -ENOTSUPP; | ||
230 | } | ||
203 | 231 | ||
204 | writeb(tmp, rtc->regbase + RCR1); | 232 | if (ret == 0) { |
233 | rtc->periodic_freq |= tmp; | ||
234 | rtc->rtc_dev->irq_freq = freq; | ||
235 | } | ||
205 | 236 | ||
206 | spin_unlock_irq(&rtc->lock); | 237 | spin_unlock_irq(&rtc->lock); |
238 | return ret; | ||
207 | } | 239 | } |
208 | 240 | ||
209 | static int sh_rtc_open(struct device *dev) | 241 | static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) |
210 | { | 242 | { |
211 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 243 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
212 | unsigned int tmp; | 244 | unsigned int tmp; |
213 | int ret; | ||
214 | |||
215 | tmp = readb(rtc->regbase + RCR1); | ||
216 | tmp &= ~RCR1_CF; | ||
217 | tmp |= RCR1_CIE; | ||
218 | writeb(tmp, rtc->regbase + RCR1); | ||
219 | 245 | ||
220 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, | 246 | spin_lock_irq(&rtc->lock); |
221 | "sh-rtc period", dev); | ||
222 | if (unlikely(ret)) { | ||
223 | dev_err(dev, "request period IRQ failed with %d, IRQ %d\n", | ||
224 | ret, rtc->periodic_irq); | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, | ||
229 | "sh-rtc carry", dev); | ||
230 | if (unlikely(ret)) { | ||
231 | dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n", | ||
232 | ret, rtc->carry_irq); | ||
233 | free_irq(rtc->periodic_irq, dev); | ||
234 | goto err_bad_carry; | ||
235 | } | ||
236 | 247 | ||
237 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, | 248 | tmp = readb(rtc->regbase + RCR1); |
238 | "sh-rtc alarm", dev); | ||
239 | if (unlikely(ret)) { | ||
240 | dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n", | ||
241 | ret, rtc->alarm_irq); | ||
242 | goto err_bad_alarm; | ||
243 | } | ||
244 | 249 | ||
245 | return 0; | 250 | if (!enable) |
251 | tmp &= ~RCR1_AIE; | ||
252 | else | ||
253 | tmp |= RCR1_AIE; | ||
246 | 254 | ||
247 | err_bad_alarm: | 255 | writeb(tmp, rtc->regbase + RCR1); |
248 | free_irq(rtc->carry_irq, dev); | ||
249 | err_bad_carry: | ||
250 | free_irq(rtc->periodic_irq, dev); | ||
251 | 256 | ||
252 | return ret; | 257 | spin_unlock_irq(&rtc->lock); |
253 | } | 258 | } |
254 | 259 | ||
255 | static void sh_rtc_release(struct device *dev) | 260 | static void sh_rtc_release(struct device *dev) |
256 | { | 261 | { |
257 | struct sh_rtc *rtc = dev_get_drvdata(dev); | ||
258 | |||
259 | sh_rtc_setpie(dev, 0); | 262 | sh_rtc_setpie(dev, 0); |
260 | sh_rtc_setaie(dev, 0); | 263 | sh_rtc_setaie(dev, 0); |
261 | |||
262 | free_irq(rtc->periodic_irq, dev); | ||
263 | free_irq(rtc->carry_irq, dev); | ||
264 | free_irq(rtc->alarm_irq, dev); | ||
265 | } | 264 | } |
266 | 265 | ||
267 | static int sh_rtc_proc(struct device *dev, struct seq_file *seq) | 266 | static int sh_rtc_proc(struct device *dev, struct seq_file *seq) |
@@ -270,31 +269,44 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq) | |||
270 | unsigned int tmp; | 269 | unsigned int tmp; |
271 | 270 | ||
272 | tmp = readb(rtc->regbase + RCR1); | 271 | tmp = readb(rtc->regbase + RCR1); |
273 | seq_printf(seq, "carry_IRQ\t: %s\n", | 272 | seq_printf(seq, "carry_IRQ\t: %s\n", (tmp & RCR1_CIE) ? "yes" : "no"); |
274 | (tmp & RCR1_CIE) ? "yes" : "no"); | ||
275 | 273 | ||
276 | tmp = readb(rtc->regbase + RCR2); | 274 | tmp = readb(rtc->regbase + RCR2); |
277 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 275 | seq_printf(seq, "periodic_IRQ\t: %s\n", |
278 | (tmp & RCR2_PEF) ? "yes" : "no"); | 276 | (tmp & RCR2_PESMASK) ? "yes" : "no"); |
279 | 277 | ||
280 | return 0; | 278 | return 0; |
281 | } | 279 | } |
282 | 280 | ||
283 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 281 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
284 | { | 282 | { |
285 | unsigned int ret = -ENOIOCTLCMD; | 283 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
284 | unsigned int ret = 0; | ||
286 | 285 | ||
287 | switch (cmd) { | 286 | switch (cmd) { |
288 | case RTC_PIE_OFF: | 287 | case RTC_PIE_OFF: |
289 | case RTC_PIE_ON: | 288 | case RTC_PIE_ON: |
290 | sh_rtc_setpie(dev, cmd == RTC_PIE_ON); | 289 | sh_rtc_setpie(dev, cmd == RTC_PIE_ON); |
291 | ret = 0; | ||
292 | break; | 290 | break; |
293 | case RTC_AIE_OFF: | 291 | case RTC_AIE_OFF: |
294 | case RTC_AIE_ON: | 292 | case RTC_AIE_ON: |
295 | sh_rtc_setaie(dev, cmd == RTC_AIE_ON); | 293 | sh_rtc_setaie(dev, cmd == RTC_AIE_ON); |
296 | ret = 0; | ||
297 | break; | 294 | break; |
295 | case RTC_UIE_OFF: | ||
296 | rtc->periodic_freq &= ~PF_OXS; | ||
297 | break; | ||
298 | case RTC_UIE_ON: | ||
299 | rtc->periodic_freq |= PF_OXS; | ||
300 | break; | ||
301 | case RTC_IRQP_READ: | ||
302 | ret = put_user(rtc->rtc_dev->irq_freq, | ||
303 | (unsigned long __user *)arg); | ||
304 | break; | ||
305 | case RTC_IRQP_SET: | ||
306 | ret = sh_rtc_setfreq(dev, arg); | ||
307 | break; | ||
308 | default: | ||
309 | ret = -ENOIOCTLCMD; | ||
298 | } | 310 | } |
299 | 311 | ||
300 | return ret; | 312 | return ret; |
@@ -349,7 +361,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
349 | 361 | ||
350 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 362 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
351 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 363 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
352 | __FUNCTION__, | 364 | __func__, |
353 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 365 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
354 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); | 366 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); |
355 | 367 | ||
@@ -421,7 +433,7 @@ static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
421 | { | 433 | { |
422 | struct platform_device *pdev = to_platform_device(dev); | 434 | struct platform_device *pdev = to_platform_device(dev); |
423 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 435 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
424 | struct rtc_time* tm = &wkalrm->time; | 436 | struct rtc_time *tm = &wkalrm->time; |
425 | 437 | ||
426 | spin_lock_irq(&rtc->lock); | 438 | spin_lock_irq(&rtc->lock); |
427 | 439 | ||
@@ -452,7 +464,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, | |||
452 | writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off); | 464 | writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off); |
453 | } | 465 | } |
454 | 466 | ||
455 | static int sh_rtc_check_alarm(struct rtc_time* tm) | 467 | static int sh_rtc_check_alarm(struct rtc_time *tm) |
456 | { | 468 | { |
457 | /* | 469 | /* |
458 | * The original rtc says anything > 0xc0 is "don't care" or "match | 470 | * The original rtc says anything > 0xc0 is "don't care" or "match |
@@ -503,11 +515,9 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
503 | 515 | ||
504 | /* disable alarm interrupt and clear the alarm flag */ | 516 | /* disable alarm interrupt and clear the alarm flag */ |
505 | rcr1 = readb(rtc->regbase + RCR1); | 517 | rcr1 = readb(rtc->regbase + RCR1); |
506 | rcr1 &= ~(RCR1_AF|RCR1_AIE); | 518 | rcr1 &= ~(RCR1_AF | RCR1_AIE); |
507 | writeb(rcr1, rtc->regbase + RCR1); | 519 | writeb(rcr1, rtc->regbase + RCR1); |
508 | 520 | ||
509 | rtc->rearm_aie = 0; | ||
510 | |||
511 | /* set alarm time */ | 521 | /* set alarm time */ |
512 | sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); | 522 | sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); |
513 | sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); | 523 | sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); |
@@ -529,14 +539,34 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
529 | return 0; | 539 | return 0; |
530 | } | 540 | } |
531 | 541 | ||
542 | static int sh_rtc_irq_set_state(struct device *dev, int enabled) | ||
543 | { | ||
544 | struct platform_device *pdev = to_platform_device(dev); | ||
545 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | ||
546 | |||
547 | if (enabled) { | ||
548 | rtc->periodic_freq |= PF_KOU; | ||
549 | return sh_rtc_ioctl(dev, RTC_PIE_ON, 0); | ||
550 | } else { | ||
551 | rtc->periodic_freq &= ~PF_KOU; | ||
552 | return sh_rtc_ioctl(dev, RTC_PIE_OFF, 0); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) | ||
557 | { | ||
558 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); | ||
559 | } | ||
560 | |||
532 | static struct rtc_class_ops sh_rtc_ops = { | 561 | static struct rtc_class_ops sh_rtc_ops = { |
533 | .open = sh_rtc_open, | ||
534 | .release = sh_rtc_release, | 562 | .release = sh_rtc_release, |
535 | .ioctl = sh_rtc_ioctl, | 563 | .ioctl = sh_rtc_ioctl, |
536 | .read_time = sh_rtc_read_time, | 564 | .read_time = sh_rtc_read_time, |
537 | .set_time = sh_rtc_set_time, | 565 | .set_time = sh_rtc_set_time, |
538 | .read_alarm = sh_rtc_read_alarm, | 566 | .read_alarm = sh_rtc_read_alarm, |
539 | .set_alarm = sh_rtc_set_alarm, | 567 | .set_alarm = sh_rtc_set_alarm, |
568 | .irq_set_state = sh_rtc_irq_set_state, | ||
569 | .irq_set_freq = sh_rtc_irq_set_freq, | ||
540 | .proc = sh_rtc_proc, | 570 | .proc = sh_rtc_proc, |
541 | }; | 571 | }; |
542 | 572 | ||
@@ -544,6 +574,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
544 | { | 574 | { |
545 | struct sh_rtc *rtc; | 575 | struct sh_rtc *rtc; |
546 | struct resource *res; | 576 | struct resource *res; |
577 | unsigned int tmp; | ||
547 | int ret = -ENOENT; | 578 | int ret = -ENOENT; |
548 | 579 | ||
549 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 580 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
@@ -552,6 +583,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
552 | 583 | ||
553 | spin_lock_init(&rtc->lock); | 584 | spin_lock_init(&rtc->lock); |
554 | 585 | ||
586 | /* get periodic/carry/alarm irqs */ | ||
555 | rtc->periodic_irq = platform_get_irq(pdev, 0); | 587 | rtc->periodic_irq = platform_get_irq(pdev, 0); |
556 | if (unlikely(rtc->periodic_irq < 0)) { | 588 | if (unlikely(rtc->periodic_irq < 0)) { |
557 | dev_err(&pdev->dev, "No IRQ for period\n"); | 589 | dev_err(&pdev->dev, "No IRQ for period\n"); |
@@ -584,7 +616,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
584 | goto err_badres; | 616 | goto err_badres; |
585 | } | 617 | } |
586 | 618 | ||
587 | rtc->regbase = (void __iomem *)rtc->res->start; | 619 | rtc->regbase = ioremap_nocache(rtc->res->start, rtc->regsize); |
588 | if (unlikely(!rtc->regbase)) { | 620 | if (unlikely(!rtc->regbase)) { |
589 | ret = -EINVAL; | 621 | ret = -EINVAL; |
590 | goto err_badmap; | 622 | goto err_badmap; |
@@ -594,7 +626,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
594 | &sh_rtc_ops, THIS_MODULE); | 626 | &sh_rtc_ops, THIS_MODULE); |
595 | if (IS_ERR(rtc->rtc_dev)) { | 627 | if (IS_ERR(rtc->rtc_dev)) { |
596 | ret = PTR_ERR(rtc->rtc_dev); | 628 | ret = PTR_ERR(rtc->rtc_dev); |
597 | goto err_badmap; | 629 | goto err_unmap; |
598 | } | 630 | } |
599 | 631 | ||
600 | rtc->capabilities = RTC_DEF_CAPABILITIES; | 632 | rtc->capabilities = RTC_DEF_CAPABILITIES; |
@@ -608,10 +640,52 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
608 | rtc->capabilities |= pinfo->capabilities; | 640 | rtc->capabilities |= pinfo->capabilities; |
609 | } | 641 | } |
610 | 642 | ||
643 | rtc->rtc_dev->max_user_freq = 256; | ||
644 | rtc->rtc_dev->irq_freq = 1; | ||
645 | rtc->periodic_freq = 0x60; | ||
646 | |||
611 | platform_set_drvdata(pdev, rtc); | 647 | platform_set_drvdata(pdev, rtc); |
612 | 648 | ||
649 | /* register periodic/carry/alarm irqs */ | ||
650 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, | ||
651 | "sh-rtc period", rtc); | ||
652 | if (unlikely(ret)) { | ||
653 | dev_err(&pdev->dev, | ||
654 | "request period IRQ failed with %d, IRQ %d\n", ret, | ||
655 | rtc->periodic_irq); | ||
656 | goto err_unmap; | ||
657 | } | ||
658 | |||
659 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, | ||
660 | "sh-rtc carry", rtc); | ||
661 | if (unlikely(ret)) { | ||
662 | dev_err(&pdev->dev, | ||
663 | "request carry IRQ failed with %d, IRQ %d\n", ret, | ||
664 | rtc->carry_irq); | ||
665 | free_irq(rtc->periodic_irq, rtc); | ||
666 | goto err_unmap; | ||
667 | } | ||
668 | |||
669 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, | ||
670 | "sh-rtc alarm", rtc); | ||
671 | if (unlikely(ret)) { | ||
672 | dev_err(&pdev->dev, | ||
673 | "request alarm IRQ failed with %d, IRQ %d\n", ret, | ||
674 | rtc->alarm_irq); | ||
675 | free_irq(rtc->carry_irq, rtc); | ||
676 | free_irq(rtc->periodic_irq, rtc); | ||
677 | goto err_unmap; | ||
678 | } | ||
679 | |||
680 | tmp = readb(rtc->regbase + RCR1); | ||
681 | tmp &= ~RCR1_CF; | ||
682 | tmp |= RCR1_CIE; | ||
683 | writeb(tmp, rtc->regbase + RCR1); | ||
684 | |||
613 | return 0; | 685 | return 0; |
614 | 686 | ||
687 | err_unmap: | ||
688 | iounmap(rtc->regbase); | ||
615 | err_badmap: | 689 | err_badmap: |
616 | release_resource(rtc->res); | 690 | release_resource(rtc->res); |
617 | err_badres: | 691 | err_badres: |
@@ -630,8 +704,14 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) | |||
630 | sh_rtc_setpie(&pdev->dev, 0); | 704 | sh_rtc_setpie(&pdev->dev, 0); |
631 | sh_rtc_setaie(&pdev->dev, 0); | 705 | sh_rtc_setaie(&pdev->dev, 0); |
632 | 706 | ||
707 | free_irq(rtc->carry_irq, rtc); | ||
708 | free_irq(rtc->periodic_irq, rtc); | ||
709 | free_irq(rtc->alarm_irq, rtc); | ||
710 | |||
633 | release_resource(rtc->res); | 711 | release_resource(rtc->res); |
634 | 712 | ||
713 | iounmap(rtc->regbase); | ||
714 | |||
635 | platform_set_drvdata(pdev, NULL); | 715 | platform_set_drvdata(pdev, NULL); |
636 | 716 | ||
637 | kfree(rtc); | 717 | kfree(rtc); |
@@ -662,5 +742,8 @@ module_exit(sh_rtc_exit); | |||
662 | 742 | ||
663 | MODULE_DESCRIPTION("SuperH on-chip RTC driver"); | 743 | MODULE_DESCRIPTION("SuperH on-chip RTC driver"); |
664 | MODULE_VERSION(DRV_VERSION); | 744 | MODULE_VERSION(DRV_VERSION); |
665 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, Jamie Lenehan <lenehan@twibble.org>"); | 745 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, " |
746 | "Jamie Lenehan <lenehan@twibble.org>, " | ||
747 | "Angelo Castello <angelo.castello@st.com>"); | ||
666 | MODULE_LICENSE("GPL"); | 748 | MODULE_LICENSE("GPL"); |
749 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index a265da7c6ff8..31d3c8c28588 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c | |||
@@ -394,6 +394,9 @@ static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev) | |||
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
396 | 396 | ||
397 | /* work with hotplug and coldplug */ | ||
398 | MODULE_ALIAS("platform:stk17ta8"); | ||
399 | |||
397 | static struct platform_driver stk17ta8_rtc_driver = { | 400 | static struct platform_driver stk17ta8_rtc_driver = { |
398 | .probe = stk17ta8_rtc_probe, | 401 | .probe = stk17ta8_rtc_probe, |
399 | .remove = __devexit_p(stk17ta8_rtc_remove), | 402 | .remove = __devexit_p(stk17ta8_rtc_remove), |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 4d27ccc4fc06..2531ce4c9db0 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -145,6 +145,8 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, | |||
145 | unsigned long now, alarm; | 145 | unsigned long now, alarm; |
146 | struct rtc_wkalrm alm; | 146 | struct rtc_wkalrm alm; |
147 | struct rtc_device *rtc = to_rtc_device(dev); | 147 | struct rtc_device *rtc = to_rtc_device(dev); |
148 | char *buf_ptr; | ||
149 | int adjust = 0; | ||
148 | 150 | ||
149 | /* Only request alarms that trigger in the future. Disable them | 151 | /* Only request alarms that trigger in the future. Disable them |
150 | * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. | 152 | * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. |
@@ -154,7 +156,15 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, | |||
154 | return retval; | 156 | return retval; |
155 | rtc_tm_to_time(&alm.time, &now); | 157 | rtc_tm_to_time(&alm.time, &now); |
156 | 158 | ||
157 | alarm = simple_strtoul(buf, NULL, 0); | 159 | buf_ptr = (char *)buf; |
160 | if (*buf_ptr == '+') { | ||
161 | buf_ptr++; | ||
162 | adjust = 1; | ||
163 | } | ||
164 | alarm = simple_strtoul(buf_ptr, NULL, 0); | ||
165 | if (adjust) { | ||
166 | alarm += now; | ||
167 | } | ||
158 | if (alarm > now) { | 168 | if (alarm > now) { |
159 | /* Avoid accidentally clobbering active alarms; we can't | 169 | /* Avoid accidentally clobbering active alarms; we can't |
160 | * entirely prevent that here, without even the minimal | 170 | * entirely prevent that here, without even the minimal |
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 254c9fce27da..bc930022004a 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -147,7 +147,7 @@ static int __devexit test_remove(struct platform_device *plat_dev) | |||
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | static struct platform_driver test_drv = { | 150 | static struct platform_driver test_driver = { |
151 | .probe = test_probe, | 151 | .probe = test_probe, |
152 | .remove = __devexit_p(test_remove), | 152 | .remove = __devexit_p(test_remove), |
153 | .driver = { | 153 | .driver = { |
@@ -160,7 +160,7 @@ static int __init test_init(void) | |||
160 | { | 160 | { |
161 | int err; | 161 | int err; |
162 | 162 | ||
163 | if ((err = platform_driver_register(&test_drv))) | 163 | if ((err = platform_driver_register(&test_driver))) |
164 | return err; | 164 | return err; |
165 | 165 | ||
166 | if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) { | 166 | if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) { |
@@ -191,7 +191,7 @@ exit_free_test0: | |||
191 | platform_device_put(test0); | 191 | platform_device_put(test0); |
192 | 192 | ||
193 | exit_driver_unregister: | 193 | exit_driver_unregister: |
194 | platform_driver_unregister(&test_drv); | 194 | platform_driver_unregister(&test_driver); |
195 | return err; | 195 | return err; |
196 | } | 196 | } |
197 | 197 | ||
@@ -199,7 +199,7 @@ static void __exit test_exit(void) | |||
199 | { | 199 | { |
200 | platform_device_unregister(test0); | 200 | platform_device_unregister(test0); |
201 | platform_device_unregister(test1); | 201 | platform_device_unregister(test1); |
202 | platform_driver_unregister(&test_drv); | 202 | platform_driver_unregister(&test_driver); |
203 | } | 203 | } |
204 | 204 | ||
205 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | 205 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index a6b572978dc0..10025d840268 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -107,7 +107,7 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt) | |||
107 | dt->tm_year = BCD2BIN(tmp)+100; | 107 | dt->tm_year = BCD2BIN(tmp)+100; |
108 | 108 | ||
109 | #ifdef DEBUG | 109 | #ifdef DEBUG |
110 | printk("\n%s : Read RTC values\n",__FUNCTION__); | 110 | printk("\n%s : Read RTC values\n",__func__); |
111 | printk("tm_hour: %i\n",dt->tm_hour); | 111 | printk("tm_hour: %i\n",dt->tm_hour); |
112 | printk("tm_min : %i\n",dt->tm_min); | 112 | printk("tm_min : %i\n",dt->tm_min); |
113 | printk("tm_sec : %i\n",dt->tm_sec); | 113 | printk("tm_sec : %i\n",dt->tm_sec); |
@@ -126,7 +126,7 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt) | |||
126 | struct v3020 *chip = dev_get_drvdata(dev); | 126 | struct v3020 *chip = dev_get_drvdata(dev); |
127 | 127 | ||
128 | #ifdef DEBUG | 128 | #ifdef DEBUG |
129 | printk("\n%s : Setting RTC values\n",__FUNCTION__); | 129 | printk("\n%s : Setting RTC values\n",__func__); |
130 | printk("tm_sec : %i\n",dt->tm_sec); | 130 | printk("tm_sec : %i\n",dt->tm_sec); |
131 | printk("tm_min : %i\n",dt->tm_min); | 131 | printk("tm_min : %i\n",dt->tm_min); |
132 | printk("tm_hour: %i\n",dt->tm_hour); | 132 | printk("tm_hour: %i\n",dt->tm_hour); |
@@ -264,3 +264,4 @@ module_exit(v3020_exit); | |||
264 | MODULE_DESCRIPTION("V3020 RTC"); | 264 | MODULE_DESCRIPTION("V3020 RTC"); |
265 | MODULE_AUTHOR("Raphael Assenat"); | 265 | MODULE_AUTHOR("Raphael Assenat"); |
266 | MODULE_LICENSE("GPL"); | 266 | MODULE_LICENSE("GPL"); |
267 | MODULE_ALIAS("platform:v3020"); | ||
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index ce2f78de7a80..be9c70d0b193 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -422,6 +422,9 @@ static int __devexit rtc_remove(struct platform_device *pdev) | |||
422 | return 0; | 422 | return 0; |
423 | } | 423 | } |
424 | 424 | ||
425 | /* work with hotplug and coldplug */ | ||
426 | MODULE_ALIAS("platform:RTC"); | ||
427 | |||
425 | static struct platform_driver rtc_platform_driver = { | 428 | static struct platform_driver rtc_platform_driver = { |
426 | .probe = rtc_probe, | 429 | .probe = rtc_probe, |
427 | .remove = __devexit_p(rtc_remove), | 430 | .remove = __devexit_p(rtc_remove), |
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index b90fb1866ce9..eaf55945f21b 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -22,20 +22,7 @@ | |||
22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | 24 | ||
25 | #define DRV_VERSION "1.0.7" | 25 | #define DRV_VERSION "1.0.8" |
26 | |||
27 | /* Addresses to scan: none. This chip is located at | ||
28 | * 0x6f and uses a two bytes register addressing. | ||
29 | * Two bytes need to be written to read a single register, | ||
30 | * while most other chips just require one and take the second | ||
31 | * one as the data to be written. To prevent corrupting | ||
32 | * unknown chips, the user must explicitly set the probe parameter. | ||
33 | */ | ||
34 | |||
35 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
36 | |||
37 | /* Insmod parameters */ | ||
38 | I2C_CLIENT_INSMOD; | ||
39 | 26 | ||
40 | /* offsets into CCR area */ | 27 | /* offsets into CCR area */ |
41 | 28 | ||
@@ -91,19 +78,7 @@ I2C_CLIENT_INSMOD; | |||
91 | 78 | ||
92 | #define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */ | 79 | #define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */ |
93 | 80 | ||
94 | /* Prototypes */ | 81 | static struct i2c_driver x1205_driver; |
95 | static int x1205_attach(struct i2c_adapter *adapter); | ||
96 | static int x1205_detach(struct i2c_client *client); | ||
97 | static int x1205_probe(struct i2c_adapter *adapter, int address, int kind); | ||
98 | |||
99 | static struct i2c_driver x1205_driver = { | ||
100 | .driver = { | ||
101 | .name = "x1205", | ||
102 | }, | ||
103 | .id = I2C_DRIVERID_X1205, | ||
104 | .attach_adapter = &x1205_attach, | ||
105 | .detach_client = &x1205_detach, | ||
106 | }; | ||
107 | 82 | ||
108 | /* | 83 | /* |
109 | * In the routines that deal directly with the x1205 hardware, we use | 84 | * In the routines that deal directly with the x1205 hardware, we use |
@@ -124,14 +99,14 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
124 | 99 | ||
125 | /* read date registers */ | 100 | /* read date registers */ |
126 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 101 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
127 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 102 | dev_err(&client->dev, "%s: read error\n", __func__); |
128 | return -EIO; | 103 | return -EIO; |
129 | } | 104 | } |
130 | 105 | ||
131 | dev_dbg(&client->dev, | 106 | dev_dbg(&client->dev, |
132 | "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " | 107 | "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " |
133 | "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", | 108 | "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", |
134 | __FUNCTION__, | 109 | __func__, |
135 | buf[0], buf[1], buf[2], buf[3], | 110 | buf[0], buf[1], buf[2], buf[3], |
136 | buf[4], buf[5], buf[6], buf[7]); | 111 | buf[4], buf[5], buf[6], buf[7]); |
137 | 112 | ||
@@ -146,7 +121,7 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
146 | 121 | ||
147 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 122 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
148 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 123 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
149 | __FUNCTION__, | 124 | __func__, |
150 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 125 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
151 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 126 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
152 | 127 | ||
@@ -164,7 +139,7 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr) | |||
164 | 139 | ||
165 | /* read status register */ | 140 | /* read status register */ |
166 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 141 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
167 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 142 | dev_err(&client->dev, "%s: read error\n", __func__); |
168 | return -EIO; | 143 | return -EIO; |
169 | } | 144 | } |
170 | 145 | ||
@@ -187,7 +162,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
187 | 162 | ||
188 | dev_dbg(&client->dev, | 163 | dev_dbg(&client->dev, |
189 | "%s: secs=%d, mins=%d, hours=%d\n", | 164 | "%s: secs=%d, mins=%d, hours=%d\n", |
190 | __FUNCTION__, | 165 | __func__, |
191 | tm->tm_sec, tm->tm_min, tm->tm_hour); | 166 | tm->tm_sec, tm->tm_min, tm->tm_hour); |
192 | 167 | ||
193 | buf[CCR_SEC] = BIN2BCD(tm->tm_sec); | 168 | buf[CCR_SEC] = BIN2BCD(tm->tm_sec); |
@@ -200,7 +175,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
200 | if (datetoo) { | 175 | if (datetoo) { |
201 | dev_dbg(&client->dev, | 176 | dev_dbg(&client->dev, |
202 | "%s: mday=%d, mon=%d, year=%d, wday=%d\n", | 177 | "%s: mday=%d, mon=%d, year=%d, wday=%d\n", |
203 | __FUNCTION__, | 178 | __func__, |
204 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 179 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
205 | 180 | ||
206 | buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); | 181 | buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); |
@@ -216,12 +191,12 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
216 | 191 | ||
217 | /* this sequence is required to unlock the chip */ | 192 | /* this sequence is required to unlock the chip */ |
218 | if ((xfer = i2c_master_send(client, wel, 3)) != 3) { | 193 | if ((xfer = i2c_master_send(client, wel, 3)) != 3) { |
219 | dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer); | 194 | dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer); |
220 | return -EIO; | 195 | return -EIO; |
221 | } | 196 | } |
222 | 197 | ||
223 | if ((xfer = i2c_master_send(client, rwel, 3)) != 3) { | 198 | if ((xfer = i2c_master_send(client, rwel, 3)) != 3) { |
224 | dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer); | 199 | dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer); |
225 | return -EIO; | 200 | return -EIO; |
226 | } | 201 | } |
227 | 202 | ||
@@ -233,7 +208,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
233 | if (xfer != 3) { | 208 | if (xfer != 3) { |
234 | dev_err(&client->dev, | 209 | dev_err(&client->dev, |
235 | "%s: xfer=%d addr=%02x, data=%02x\n", | 210 | "%s: xfer=%d addr=%02x, data=%02x\n", |
236 | __FUNCTION__, | 211 | __func__, |
237 | xfer, rdata[1], rdata[2]); | 212 | xfer, rdata[1], rdata[2]); |
238 | return -EIO; | 213 | return -EIO; |
239 | } | 214 | } |
@@ -241,7 +216,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
241 | 216 | ||
242 | /* disable further writes */ | 217 | /* disable further writes */ |
243 | if ((xfer = i2c_master_send(client, diswe, 3)) != 3) { | 218 | if ((xfer = i2c_master_send(client, diswe, 3)) != 3) { |
244 | dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer); | 219 | dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer); |
245 | return -EIO; | 220 | return -EIO; |
246 | } | 221 | } |
247 | 222 | ||
@@ -274,11 +249,11 @@ static int x1205_get_dtrim(struct i2c_client *client, int *trim) | |||
274 | 249 | ||
275 | /* read dtr register */ | 250 | /* read dtr register */ |
276 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 251 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
277 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 252 | dev_err(&client->dev, "%s: read error\n", __func__); |
278 | return -EIO; | 253 | return -EIO; |
279 | } | 254 | } |
280 | 255 | ||
281 | dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr); | 256 | dev_dbg(&client->dev, "%s: raw dtr=%x\n", __func__, dtr); |
282 | 257 | ||
283 | *trim = 0; | 258 | *trim = 0; |
284 | 259 | ||
@@ -306,11 +281,11 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) | |||
306 | 281 | ||
307 | /* read atr register */ | 282 | /* read atr register */ |
308 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 283 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
309 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 284 | dev_err(&client->dev, "%s: read error\n", __func__); |
310 | return -EIO; | 285 | return -EIO; |
311 | } | 286 | } |
312 | 287 | ||
313 | dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr); | 288 | dev_dbg(&client->dev, "%s: raw atr=%x\n", __func__, atr); |
314 | 289 | ||
315 | /* atr is a two's complement value on 6 bits, | 290 | /* atr is a two's complement value on 6 bits, |
316 | * perform sign extension. The formula is | 291 | * perform sign extension. The formula is |
@@ -319,11 +294,11 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) | |||
319 | if (atr & 0x20) | 294 | if (atr & 0x20) |
320 | atr |= 0xC0; | 295 | atr |= 0xC0; |
321 | 296 | ||
322 | dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr); | 297 | dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr); |
323 | 298 | ||
324 | *trim = (atr * 250) + 11000; | 299 | *trim = (atr * 250) + 11000; |
325 | 300 | ||
326 | dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim); | 301 | dev_dbg(&client->dev, "%s: real=%d\n", __func__, *trim); |
327 | 302 | ||
328 | return 0; | 303 | return 0; |
329 | } | 304 | } |
@@ -377,7 +352,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
377 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 352 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
378 | dev_err(&client->dev, | 353 | dev_err(&client->dev, |
379 | "%s: could not read register %x\n", | 354 | "%s: could not read register %x\n", |
380 | __FUNCTION__, probe_zero_pattern[i]); | 355 | __func__, probe_zero_pattern[i]); |
381 | 356 | ||
382 | return -EIO; | 357 | return -EIO; |
383 | } | 358 | } |
@@ -385,7 +360,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
385 | if ((buf & probe_zero_pattern[i+1]) != 0) { | 360 | if ((buf & probe_zero_pattern[i+1]) != 0) { |
386 | dev_err(&client->dev, | 361 | dev_err(&client->dev, |
387 | "%s: register=%02x, zero pattern=%d, value=%x\n", | 362 | "%s: register=%02x, zero pattern=%d, value=%x\n", |
388 | __FUNCTION__, probe_zero_pattern[i], i, buf); | 363 | __func__, probe_zero_pattern[i], i, buf); |
389 | 364 | ||
390 | return -ENODEV; | 365 | return -ENODEV; |
391 | } | 366 | } |
@@ -405,7 +380,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
405 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 380 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
406 | dev_err(&client->dev, | 381 | dev_err(&client->dev, |
407 | "%s: could not read register %x\n", | 382 | "%s: could not read register %x\n", |
408 | __FUNCTION__, probe_limits_pattern[i].reg); | 383 | __func__, probe_limits_pattern[i].reg); |
409 | 384 | ||
410 | return -EIO; | 385 | return -EIO; |
411 | } | 386 | } |
@@ -416,7 +391,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
416 | value < probe_limits_pattern[i].min) { | 391 | value < probe_limits_pattern[i].min) { |
417 | dev_dbg(&client->dev, | 392 | dev_dbg(&client->dev, |
418 | "%s: register=%x, lim pattern=%d, value=%d\n", | 393 | "%s: register=%x, lim pattern=%d, value=%d\n", |
419 | __FUNCTION__, probe_limits_pattern[i].reg, | 394 | __func__, probe_limits_pattern[i].reg, |
420 | i, value); | 395 | i, value); |
421 | 396 | ||
422 | return -ENODEV; | 397 | return -ENODEV; |
@@ -497,58 +472,50 @@ static ssize_t x1205_sysfs_show_dtrim(struct device *dev, | |||
497 | } | 472 | } |
498 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); | 473 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); |
499 | 474 | ||
500 | static int x1205_attach(struct i2c_adapter *adapter) | 475 | static int x1205_sysfs_register(struct device *dev) |
501 | { | 476 | { |
502 | return i2c_probe(adapter, &addr_data, x1205_probe); | 477 | int err; |
478 | |||
479 | err = device_create_file(dev, &dev_attr_atrim); | ||
480 | if (err) | ||
481 | return err; | ||
482 | |||
483 | err = device_create_file(dev, &dev_attr_dtrim); | ||
484 | if (err) | ||
485 | device_remove_file(dev, &dev_attr_atrim); | ||
486 | |||
487 | return err; | ||
503 | } | 488 | } |
504 | 489 | ||
505 | static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | 490 | static void x1205_sysfs_unregister(struct device *dev) |
491 | { | ||
492 | device_remove_file(dev, &dev_attr_atrim); | ||
493 | device_remove_file(dev, &dev_attr_dtrim); | ||
494 | } | ||
495 | |||
496 | |||
497 | static int x1205_probe(struct i2c_client *client, | ||
498 | const struct i2c_device_id *id) | ||
506 | { | 499 | { |
507 | int err = 0; | 500 | int err = 0; |
508 | unsigned char sr; | 501 | unsigned char sr; |
509 | struct i2c_client *client; | ||
510 | struct rtc_device *rtc; | 502 | struct rtc_device *rtc; |
511 | 503 | ||
512 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | 504 | dev_dbg(&client->dev, "%s\n", __func__); |
513 | |||
514 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { | ||
515 | err = -ENODEV; | ||
516 | goto exit; | ||
517 | } | ||
518 | |||
519 | if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { | ||
520 | err = -ENOMEM; | ||
521 | goto exit; | ||
522 | } | ||
523 | |||
524 | /* I2C client */ | ||
525 | client->addr = address; | ||
526 | client->driver = &x1205_driver; | ||
527 | client->adapter = adapter; | ||
528 | |||
529 | strlcpy(client->name, x1205_driver.driver.name, I2C_NAME_SIZE); | ||
530 | 505 | ||
531 | /* Verify the chip is really an X1205 */ | 506 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
532 | if (kind < 0) { | 507 | return -ENODEV; |
533 | if (x1205_validate_client(client) < 0) { | ||
534 | err = -ENODEV; | ||
535 | goto exit_kfree; | ||
536 | } | ||
537 | } | ||
538 | 508 | ||
539 | /* Inform the i2c layer */ | 509 | if (x1205_validate_client(client) < 0) |
540 | if ((err = i2c_attach_client(client))) | 510 | return -ENODEV; |
541 | goto exit_kfree; | ||
542 | 511 | ||
543 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | 512 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); |
544 | 513 | ||
545 | rtc = rtc_device_register(x1205_driver.driver.name, &client->dev, | 514 | rtc = rtc_device_register(x1205_driver.driver.name, &client->dev, |
546 | &x1205_rtc_ops, THIS_MODULE); | 515 | &x1205_rtc_ops, THIS_MODULE); |
547 | 516 | ||
548 | if (IS_ERR(rtc)) { | 517 | if (IS_ERR(rtc)) |
549 | err = PTR_ERR(rtc); | 518 | return PTR_ERR(rtc); |
550 | goto exit_detach; | ||
551 | } | ||
552 | 519 | ||
553 | i2c_set_clientdata(client, rtc); | 520 | i2c_set_clientdata(client, rtc); |
554 | 521 | ||
@@ -565,45 +532,42 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | |||
565 | else | 532 | else |
566 | dev_err(&client->dev, "couldn't read status\n"); | 533 | dev_err(&client->dev, "couldn't read status\n"); |
567 | 534 | ||
568 | err = device_create_file(&client->dev, &dev_attr_atrim); | 535 | err = x1205_sysfs_register(&client->dev); |
569 | if (err) goto exit_devreg; | 536 | if (err) |
570 | err = device_create_file(&client->dev, &dev_attr_dtrim); | 537 | goto exit_devreg; |
571 | if (err) goto exit_atrim; | ||
572 | 538 | ||
573 | return 0; | 539 | return 0; |
574 | 540 | ||
575 | exit_atrim: | ||
576 | device_remove_file(&client->dev, &dev_attr_atrim); | ||
577 | |||
578 | exit_devreg: | 541 | exit_devreg: |
579 | rtc_device_unregister(rtc); | 542 | rtc_device_unregister(rtc); |
580 | 543 | ||
581 | exit_detach: | ||
582 | i2c_detach_client(client); | ||
583 | |||
584 | exit_kfree: | ||
585 | kfree(client); | ||
586 | |||
587 | exit: | ||
588 | return err; | 544 | return err; |
589 | } | 545 | } |
590 | 546 | ||
591 | static int x1205_detach(struct i2c_client *client) | 547 | static int x1205_remove(struct i2c_client *client) |
592 | { | 548 | { |
593 | int err; | ||
594 | struct rtc_device *rtc = i2c_get_clientdata(client); | 549 | struct rtc_device *rtc = i2c_get_clientdata(client); |
595 | 550 | ||
596 | if (rtc) | 551 | rtc_device_unregister(rtc); |
597 | rtc_device_unregister(rtc); | 552 | x1205_sysfs_unregister(&client->dev); |
598 | |||
599 | if ((err = i2c_detach_client(client))) | ||
600 | return err; | ||
601 | |||
602 | kfree(client); | ||
603 | |||
604 | return 0; | 553 | return 0; |
605 | } | 554 | } |
606 | 555 | ||
556 | static const struct i2c_device_id x1205_id[] = { | ||
557 | { "x1205", 0 }, | ||
558 | { } | ||
559 | }; | ||
560 | MODULE_DEVICE_TABLE(i2c, x1205_id); | ||
561 | |||
562 | static struct i2c_driver x1205_driver = { | ||
563 | .driver = { | ||
564 | .name = "rtc-x1205", | ||
565 | }, | ||
566 | .probe = x1205_probe, | ||
567 | .remove = x1205_remove, | ||
568 | .id_table = x1205_id, | ||
569 | }; | ||
570 | |||
607 | static int __init x1205_init(void) | 571 | static int __init x1205_init(void) |
608 | { | 572 | { |
609 | return i2c_add_driver(&x1205_driver); | 573 | return i2c_add_driver(&x1205_driver); |