diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-05 09:48:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-05 09:48:22 -0400 |
| commit | 6c84239d595dc6ffe39f0f03dae2f64ed200db95 (patch) | |
| tree | 3aea4368a644be16e44612c964aa26152854e1ae /drivers/rtc | |
| parent | d4c06c708123c652025d04fe77b7e39448077395 (diff) | |
| parent | 6f367788d6333a41fefd013975b0b160d5c0a1c8 (diff) | |
Merge tag 'rtc-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"RTC for 4.8
Cleanups:
- huge cleanup of rtc-generic and char/genrtc this allowed to cleanup
rtc-cmos, rtc-sh, rtc-m68k, rtc-powerpc and rtc-parisc
- move mn10300 to rtc-cmos
Subsystem:
- fix wakealarms after hibernate
- multiples fixes for rctest
- simplify implementations of .read_alarm
New drivers:
- Maxim MAX6916
Drivers:
- ds1307: fix weekday
- m41t80: add wakeup support
- pcf85063: add support for PCF85063A variant
- rv8803: extend i2c fix and other fixes
- s35390a: fix alarm reading, this fixes instant reboot after
shutdown for QNAP TS-41x
- s3c: clock fixes"
* tag 'rtc-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (65 commits)
rtc: rv8803: Clear V1F when setting the time
rtc: rv8803: Stop the clock while setting the time
rtc: rv8803: Always apply the I²C workaround
rtc: rv8803: Fix read day of week
rtc: rv8803: Remove the check for valid time
rtc: rv8803: Kconfig: Indicate rx8900 support
rtc: asm9260: remove .owner field for driver
rtc: at91sam9: Fix missing spin_lock_init()
rtc: m41t80: add suspend handlers for alarm IRQ
rtc: m41t80: make it a real error message
rtc: pcf85063: Add support for the PCF85063A device
rtc: pcf85063: fix year range
rtc: hym8563: in .read_alarm set .tm_sec to 0 to signal minute accuracy
rtc: explicitly set tm_sec = 0 for drivers with minute accurancy
rtc: s3c: Add s3c_rtc_{enable/disable}_clk in s3c_rtc_setfreq()
rtc: s3c: Remove unnecessary call to disable already disabled clock
rtc: abx80x: use devm_add_action_or_reset()
rtc: m41t80: use devm_add_action_or_reset()
rtc: fix a typo and reduce three empty lines to one
rtc: s35390a: improve two comments in .set_alarm
...
Diffstat (limited to 'drivers/rtc')
39 files changed, 835 insertions, 373 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 18639e0cb6e2..e215f50794b6 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -5,6 +5,10 @@ | |||
| 5 | config RTC_LIB | 5 | config RTC_LIB |
| 6 | bool | 6 | bool |
| 7 | 7 | ||
| 8 | config RTC_MC146818_LIB | ||
| 9 | bool | ||
| 10 | select RTC_LIB | ||
| 11 | |||
| 8 | menuconfig RTC_CLASS | 12 | menuconfig RTC_CLASS |
| 9 | bool "Real Time Clock" | 13 | bool "Real Time Clock" |
| 10 | default n | 14 | default n |
| @@ -574,10 +578,10 @@ config RTC_DRV_EM3027 | |||
| 574 | will be called rtc-em3027. | 578 | will be called rtc-em3027. |
| 575 | 579 | ||
| 576 | config RTC_DRV_RV8803 | 580 | config RTC_DRV_RV8803 |
| 577 | tristate "Micro Crystal RV8803" | 581 | tristate "Micro Crystal RV8803, Epson RX8900" |
| 578 | help | 582 | help |
| 579 | If you say yes here you get support for the Micro Crystal | 583 | If you say yes here you get support for the Micro Crystal RV8803 and |
| 580 | RV8803 RTC chips. | 584 | Epson RX8900 RTC chips. |
| 581 | 585 | ||
| 582 | This driver can also be built as a module. If so, the module | 586 | This driver can also be built as a module. If so, the module |
| 583 | will be called rtc-rv8803. | 587 | will be called rtc-rv8803. |
| @@ -670,6 +674,18 @@ config RTC_DRV_DS1390 | |||
| 670 | This driver can also be built as a module. If so, the module | 674 | This driver can also be built as a module. If so, the module |
| 671 | will be called rtc-ds1390. | 675 | will be called rtc-ds1390. |
| 672 | 676 | ||
| 677 | config RTC_DRV_MAX6916 | ||
| 678 | tristate "Maxim MAX6916" | ||
| 679 | help | ||
| 680 | If you say yes here you will get support for the | ||
| 681 | Maxim MAX6916 SPI RTC chip. | ||
| 682 | |||
| 683 | This driver only supports the RTC feature, and not other chip | ||
| 684 | features such as alarms. | ||
| 685 | |||
| 686 | This driver can also be built as a module. If so, the module | ||
| 687 | will be called rtc-max6916. | ||
| 688 | |||
| 673 | config RTC_DRV_R9701 | 689 | config RTC_DRV_R9701 |
| 674 | tristate "Epson RTC-9701JE" | 690 | tristate "Epson RTC-9701JE" |
| 675 | help | 691 | help |
| @@ -795,8 +811,9 @@ comment "Platform RTC drivers" | |||
| 795 | 811 | ||
| 796 | config RTC_DRV_CMOS | 812 | config RTC_DRV_CMOS |
| 797 | tristate "PC-style 'CMOS'" | 813 | tristate "PC-style 'CMOS'" |
| 798 | depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 | 814 | depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 || MN10300 |
| 799 | default y if X86 | 815 | default y if X86 |
| 816 | select RTC_MC146818_LIB | ||
| 800 | help | 817 | help |
| 801 | Say "yes" here to get direct support for the real time clock | 818 | Say "yes" here to get direct support for the real time clock |
| 802 | found in every PC or ACPI-based system, and some other boards. | 819 | found in every PC or ACPI-based system, and some other boards. |
| @@ -815,6 +832,7 @@ config RTC_DRV_CMOS | |||
| 815 | config RTC_DRV_ALPHA | 832 | config RTC_DRV_ALPHA |
| 816 | bool "Alpha PC-style CMOS" | 833 | bool "Alpha PC-style CMOS" |
| 817 | depends on ALPHA | 834 | depends on ALPHA |
| 835 | select RTC_MC146818_LIB | ||
| 818 | default y | 836 | default y |
| 819 | help | 837 | help |
| 820 | Direct support for the real-time clock found on every Alpha | 838 | Direct support for the real-time clock found on every Alpha |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ea2833723fa9..7cf7ad559c79 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -8,6 +8,7 @@ obj-$(CONFIG_RTC_LIB) += rtc-lib.o | |||
| 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o |
| 9 | obj-$(CONFIG_RTC_SYSTOHC) += systohc.o | 9 | obj-$(CONFIG_RTC_SYSTOHC) += systohc.o |
| 10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o |
| 11 | obj-$(CONFIG_RTC_MC146818_LIB) += rtc-mc146818-lib.o | ||
| 11 | rtc-core-y := class.o interface.o | 12 | rtc-core-y := class.o interface.o |
| 12 | 13 | ||
| 13 | ifdef CONFIG_RTC_DRV_EFI | 14 | ifdef CONFIG_RTC_DRV_EFI |
| @@ -85,6 +86,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | |||
| 85 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 86 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
| 86 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 87 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
| 87 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 88 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
| 89 | obj-$(CONFIG_RTC_DRV_MAX6916) += rtc-max6916.o | ||
| 88 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o | 90 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o |
| 89 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | 91 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o |
| 90 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 92 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9ef5f6f89f98..84a52db9b05f 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -104,7 +104,17 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al | |||
| 104 | else if (!rtc->ops->read_alarm) | 104 | else if (!rtc->ops->read_alarm) |
| 105 | err = -EINVAL; | 105 | err = -EINVAL; |
| 106 | else { | 106 | else { |
| 107 | memset(alarm, 0, sizeof(struct rtc_wkalrm)); | 107 | alarm->enabled = 0; |
| 108 | alarm->pending = 0; | ||
| 109 | alarm->time.tm_sec = -1; | ||
| 110 | alarm->time.tm_min = -1; | ||
| 111 | alarm->time.tm_hour = -1; | ||
| 112 | alarm->time.tm_mday = -1; | ||
| 113 | alarm->time.tm_mon = -1; | ||
| 114 | alarm->time.tm_year = -1; | ||
| 115 | alarm->time.tm_wday = -1; | ||
| 116 | alarm->time.tm_yday = -1; | ||
| 117 | alarm->time.tm_isdst = -1; | ||
| 108 | err = rtc->ops->read_alarm(rtc->dev.parent, alarm); | 118 | err = rtc->ops->read_alarm(rtc->dev.parent, alarm); |
| 109 | } | 119 | } |
| 110 | 120 | ||
| @@ -383,7 +393,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
| 383 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); | 393 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); |
| 384 | rtc->aie_timer.period = ktime_set(0, 0); | 394 | rtc->aie_timer.period = ktime_set(0, 0); |
| 385 | 395 | ||
| 386 | /* Alarm has to be enabled & in the futrure for us to enqueue it */ | 396 | /* Alarm has to be enabled & in the future for us to enqueue it */ |
| 387 | if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < | 397 | if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < |
| 388 | rtc->aie_timer.node.expires.tv64)) { | 398 | rtc->aie_timer.node.expires.tv64)) { |
| 389 | 399 | ||
| @@ -395,8 +405,6 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
| 395 | } | 405 | } |
| 396 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); | 406 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); |
| 397 | 407 | ||
| 398 | |||
| 399 | |||
| 400 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) | 408 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) |
| 401 | { | 409 | { |
| 402 | int err = mutex_lock_interruptible(&rtc->ops_lock); | 410 | int err = mutex_lock_interruptible(&rtc->ops_lock); |
| @@ -748,9 +756,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq); | |||
| 748 | */ | 756 | */ |
| 749 | static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | 757 | static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) |
| 750 | { | 758 | { |
| 759 | struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); | ||
| 760 | struct rtc_time tm; | ||
| 761 | ktime_t now; | ||
| 762 | |||
| 751 | timer->enabled = 1; | 763 | timer->enabled = 1; |
| 764 | __rtc_read_time(rtc, &tm); | ||
| 765 | now = rtc_tm_to_ktime(tm); | ||
| 766 | |||
| 767 | /* Skip over expired timers */ | ||
| 768 | while (next) { | ||
| 769 | if (next->expires.tv64 >= now.tv64) | ||
| 770 | break; | ||
| 771 | next = timerqueue_iterate_next(next); | ||
| 772 | } | ||
| 773 | |||
| 752 | timerqueue_add(&rtc->timerqueue, &timer->node); | 774 | timerqueue_add(&rtc->timerqueue, &timer->node); |
| 753 | if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { | 775 | if (!next) { |
| 754 | struct rtc_wkalrm alarm; | 776 | struct rtc_wkalrm alarm; |
| 755 | int err; | 777 | int err; |
| 756 | alarm.time = rtc_ktime_to_tm(timer->node.expires); | 778 | alarm.time = rtc_ktime_to_tm(timer->node.expires); |
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index ba0d61934d35..fea9a60b06cf 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c | |||
| @@ -643,17 +643,15 @@ static int abx80x_probe(struct i2c_client *client, | |||
| 643 | return err; | 643 | return err; |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | err = devm_add_action(&client->dev, rtc_calib_remove_sysfs_group, | 646 | err = devm_add_action_or_reset(&client->dev, |
| 647 | &client->dev); | 647 | rtc_calib_remove_sysfs_group, |
| 648 | if (err) { | 648 | &client->dev); |
| 649 | rtc_calib_remove_sysfs_group(&client->dev); | 649 | if (err) |
| 650 | dev_err(&client->dev, | 650 | dev_err(&client->dev, |
| 651 | "Failed to add sysfs cleanup action: %d\n", | 651 | "Failed to add sysfs cleanup action: %d\n", |
| 652 | err); | 652 | err); |
| 653 | return err; | ||
| 654 | } | ||
| 655 | 653 | ||
| 656 | return 0; | 654 | return err; |
| 657 | } | 655 | } |
| 658 | 656 | ||
| 659 | static int abx80x_remove(struct i2c_client *client) | 657 | static int abx80x_remove(struct i2c_client *client) |
diff --git a/drivers/rtc/rtc-asm9260.c b/drivers/rtc/rtc-asm9260.c index 355fdb97a006..5219916ce11d 100644 --- a/drivers/rtc/rtc-asm9260.c +++ b/drivers/rtc/rtc-asm9260.c | |||
| @@ -343,7 +343,6 @@ static struct platform_driver asm9260_rtc_driver = { | |||
| 343 | .remove = asm9260_rtc_remove, | 343 | .remove = asm9260_rtc_remove, |
| 344 | .driver = { | 344 | .driver = { |
| 345 | .name = "asm9260-rtc", | 345 | .name = "asm9260-rtc", |
| 346 | .owner = THIS_MODULE, | ||
| 347 | .of_match_table = asm9260_dt_ids, | 346 | .of_match_table = asm9260_dt_ids, |
| 348 | }, | 347 | }, |
| 349 | }; | 348 | }; |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 99732e6f8c3b..7418a763ce52 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
| @@ -375,6 +375,7 @@ static int at91_rtc_probe(struct platform_device *pdev) | |||
| 375 | if (!rtc) | 375 | if (!rtc) |
| 376 | return -ENOMEM; | 376 | return -ENOMEM; |
| 377 | 377 | ||
| 378 | spin_lock_init(&rtc->lock); | ||
| 378 | rtc->irq = irq; | 379 | rtc->irq = irq; |
| 379 | 380 | ||
| 380 | /* platform setup code should have handled this; sigh */ | 381 | /* platform setup code should have handled this; sigh */ |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index fbe9c72438e1..43745cac0141 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
| @@ -43,7 +43,7 @@ | |||
| 43 | #include <linux/of_platform.h> | 43 | #include <linux/of_platform.h> |
| 44 | 44 | ||
| 45 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 45 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
| 46 | #include <asm-generic/rtc.h> | 46 | #include <linux/mc146818rtc.h> |
| 47 | 47 | ||
| 48 | struct cmos_rtc { | 48 | struct cmos_rtc { |
| 49 | struct rtc_device *rtc; | 49 | struct rtc_device *rtc; |
| @@ -190,10 +190,10 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | |||
| 190 | static int cmos_read_time(struct device *dev, struct rtc_time *t) | 190 | static int cmos_read_time(struct device *dev, struct rtc_time *t) |
| 191 | { | 191 | { |
| 192 | /* REVISIT: if the clock has a "century" register, use | 192 | /* REVISIT: if the clock has a "century" register, use |
| 193 | * that instead of the heuristic in get_rtc_time(). | 193 | * that instead of the heuristic in mc146818_get_time(). |
| 194 | * That'll make Y3K compatility (year > 2070) easy! | 194 | * That'll make Y3K compatility (year > 2070) easy! |
| 195 | */ | 195 | */ |
| 196 | get_rtc_time(t); | 196 | mc146818_get_time(t); |
| 197 | return 0; | 197 | return 0; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| @@ -205,7 +205,7 @@ static int cmos_set_time(struct device *dev, struct rtc_time *t) | |||
| 205 | * takes effect exactly 500ms after we write the register. | 205 | * takes effect exactly 500ms after we write the register. |
| 206 | * (Also queueing and other delays before we get this far.) | 206 | * (Also queueing and other delays before we get this far.) |
| 207 | */ | 207 | */ |
| 208 | return set_rtc_time(t); | 208 | return mc146818_set_time(t); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | 211 | static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) |
| @@ -220,8 +220,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 220 | * Some also support day and month, for alarms up to a year in | 220 | * Some also support day and month, for alarms up to a year in |
| 221 | * the future. | 221 | * the future. |
| 222 | */ | 222 | */ |
| 223 | t->time.tm_mday = -1; | ||
| 224 | t->time.tm_mon = -1; | ||
| 225 | 223 | ||
| 226 | spin_lock_irq(&rtc_lock); | 224 | spin_lock_irq(&rtc_lock); |
| 227 | t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM); | 225 | t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM); |
| @@ -272,7 +270,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 272 | } | 270 | } |
| 273 | } | 271 | } |
| 274 | } | 272 | } |
| 275 | t->time.tm_year = -1; | ||
| 276 | 273 | ||
| 277 | t->enabled = !!(rtc_control & RTC_AIE); | 274 | t->enabled = !!(rtc_control & RTC_AIE); |
| 278 | t->pending = 0; | 275 | t->pending = 0; |
| @@ -630,7 +627,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 630 | address_space = 64; | 627 | address_space = 64; |
| 631 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ | 628 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ |
| 632 | || defined(__sparc__) || defined(__mips__) \ | 629 | || defined(__sparc__) || defined(__mips__) \ |
| 633 | || defined(__powerpc__) | 630 | || defined(__powerpc__) || defined(CONFIG_MN10300) |
| 634 | address_space = 128; | 631 | address_space = 128; |
| 635 | #else | 632 | #else |
| 636 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | 633 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. |
| @@ -1142,14 +1139,14 @@ static __init void cmos_of_init(struct platform_device *pdev) | |||
| 1142 | if (val) | 1139 | if (val) |
| 1143 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); | 1140 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); |
| 1144 | 1141 | ||
| 1145 | get_rtc_time(&time); | 1142 | cmos_read_time(&pdev->dev, &time); |
| 1146 | ret = rtc_valid_tm(&time); | 1143 | ret = rtc_valid_tm(&time); |
| 1147 | if (ret) { | 1144 | if (ret) { |
| 1148 | struct rtc_time def_time = { | 1145 | struct rtc_time def_time = { |
| 1149 | .tm_year = 1, | 1146 | .tm_year = 1, |
| 1150 | .tm_mday = 1, | 1147 | .tm_mday = 1, |
| 1151 | }; | 1148 | }; |
| 1152 | set_rtc_time(&def_time); | 1149 | cmos_set_time(&pdev->dev, &def_time); |
| 1153 | } | 1150 | } |
| 1154 | } | 1151 | } |
| 1155 | #else | 1152 | #else |
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index a20bcf0e33cd..4273377562ec 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c | |||
| @@ -85,6 +85,7 @@ static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) | |||
| 85 | rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; | 85 | rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; |
| 86 | rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; | 86 | rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; |
| 87 | rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; | 87 | rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; |
| 88 | rtc_tm->tm_sec = 0; | ||
| 88 | 89 | ||
| 89 | ret = rtc_valid_tm(rtc_tm); | 90 | ret = rtc_valid_tm(rtc_tm); |
| 90 | return ret; | 91 | return ret; |
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c index 7ec0872d5e3b..678af8648c45 100644 --- a/drivers/rtc/rtc-da9055.c +++ b/drivers/rtc/rtc-da9055.c | |||
| @@ -74,6 +74,7 @@ static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) | |||
| 74 | rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; | 74 | rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; |
| 75 | rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; | 75 | rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; |
| 76 | rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; | 76 | rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; |
| 77 | rtc_tm->tm_sec = 0; | ||
| 77 | 78 | ||
| 78 | return rtc_valid_tm(rtc_tm); | 79 | return rtc_valid_tm(rtc_tm); |
| 79 | } | 80 | } |
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index c5432bf64e1c..dba60c1dfce2 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
| @@ -388,6 +388,8 @@ static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 388 | u8 day0, day1; | 388 | u8 day0, day1; |
| 389 | unsigned long flags; | 389 | unsigned long flags; |
| 390 | 390 | ||
| 391 | alm->time.tm_sec = 0; | ||
| 392 | |||
| 391 | spin_lock_irqsave(&davinci_rtc_lock, flags); | 393 | spin_lock_irqsave(&davinci_rtc_lock, flags); |
| 392 | 394 | ||
| 393 | davinci_rtcss_calendar_wait(davinci_rtc); | 395 | davinci_rtcss_calendar_wait(davinci_rtc); |
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 756e509f6ed2..ef75c349dff9 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
| 19 | #include <linux/ds1286.h> | 19 | #include <linux/rtc/ds1286.h> |
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | 22 | ||
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 8e41c4613e51..72b22935eb62 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
| @@ -313,13 +313,6 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 313 | alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); | 313 | alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); |
| 314 | alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); | 314 | alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); |
| 315 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); | 315 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); |
| 316 | alm->time.tm_mday = -1; | ||
| 317 | alm->time.tm_mon = -1; | ||
| 318 | alm->time.tm_year = -1; | ||
| 319 | /* next three fields are unused by Linux */ | ||
| 320 | alm->time.tm_wday = -1; | ||
| 321 | alm->time.tm_mday = -1; | ||
| 322 | alm->time.tm_isdst = -1; | ||
| 323 | 316 | ||
| 324 | return 0; | 317 | return 0; |
| 325 | } | 318 | } |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 821d9c089cdb..8e1c5cb6ece6 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
| @@ -482,11 +482,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 482 | t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); | 482 | t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); |
| 483 | t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); | 483 | t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); |
| 484 | t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); | 484 | t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); |
| 485 | t->time.tm_mon = -1; | ||
| 486 | t->time.tm_year = -1; | ||
| 487 | t->time.tm_wday = -1; | ||
| 488 | t->time.tm_yday = -1; | ||
| 489 | t->time.tm_isdst = -1; | ||
| 490 | 485 | ||
| 491 | /* ... and status */ | 486 | /* ... and status */ |
| 492 | t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); | 487 | t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); |
| @@ -602,6 +597,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { | |||
| 602 | * Alarm support for mcp794xx devices. | 597 | * Alarm support for mcp794xx devices. |
| 603 | */ | 598 | */ |
| 604 | 599 | ||
| 600 | #define MCP794XX_REG_WEEKDAY 0x3 | ||
| 601 | #define MCP794XX_REG_WEEKDAY_WDAY_MASK 0x7 | ||
| 605 | #define MCP794XX_REG_CONTROL 0x07 | 602 | #define MCP794XX_REG_CONTROL 0x07 |
| 606 | # define MCP794XX_BIT_ALM0_EN 0x10 | 603 | # define MCP794XX_BIT_ALM0_EN 0x10 |
| 607 | # define MCP794XX_BIT_ALM1_EN 0x20 | 604 | # define MCP794XX_BIT_ALM1_EN 0x20 |
| @@ -1231,13 +1228,16 @@ static int ds1307_probe(struct i2c_client *client, | |||
| 1231 | { | 1228 | { |
| 1232 | struct ds1307 *ds1307; | 1229 | struct ds1307 *ds1307; |
| 1233 | int err = -ENODEV; | 1230 | int err = -ENODEV; |
| 1234 | int tmp; | 1231 | int tmp, wday; |
| 1235 | struct chip_desc *chip = &chips[id->driver_data]; | 1232 | struct chip_desc *chip = &chips[id->driver_data]; |
| 1236 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 1233 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 1237 | bool want_irq = false; | 1234 | bool want_irq = false; |
| 1238 | bool ds1307_can_wakeup_device = false; | 1235 | bool ds1307_can_wakeup_device = false; |
| 1239 | unsigned char *buf; | 1236 | unsigned char *buf; |
| 1240 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); | 1237 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); |
| 1238 | struct rtc_time tm; | ||
| 1239 | unsigned long timestamp; | ||
| 1240 | |||
| 1241 | irq_handler_t irq_handler = ds1307_irq; | 1241 | irq_handler_t irq_handler = ds1307_irq; |
| 1242 | 1242 | ||
| 1243 | static const int bbsqi_bitpos[] = { | 1243 | static const int bbsqi_bitpos[] = { |
| @@ -1526,6 +1526,27 @@ read_rtc: | |||
| 1526 | bin2bcd(tmp)); | 1526 | bin2bcd(tmp)); |
| 1527 | } | 1527 | } |
| 1528 | 1528 | ||
| 1529 | /* | ||
| 1530 | * Some IPs have weekday reset value = 0x1 which might not correct | ||
| 1531 | * hence compute the wday using the current date/month/year values | ||
| 1532 | */ | ||
| 1533 | ds1307_get_time(&client->dev, &tm); | ||
| 1534 | wday = tm.tm_wday; | ||
| 1535 | timestamp = rtc_tm_to_time64(&tm); | ||
| 1536 | rtc_time64_to_tm(timestamp, &tm); | ||
| 1537 | |||
| 1538 | /* | ||
| 1539 | * Check if reset wday is different from the computed wday | ||
| 1540 | * If different then set the wday which we computed using | ||
| 1541 | * timestamp | ||
| 1542 | */ | ||
| 1543 | if (wday != tm.tm_wday) { | ||
| 1544 | wday = i2c_smbus_read_byte_data(client, MCP794XX_REG_WEEKDAY); | ||
| 1545 | wday = wday & ~MCP794XX_REG_WEEKDAY_WDAY_MASK; | ||
| 1546 | wday = wday | (tm.tm_wday + 1); | ||
| 1547 | i2c_smbus_write_byte_data(client, MCP794XX_REG_WEEKDAY, wday); | ||
| 1548 | } | ||
| 1549 | |||
| 1529 | if (want_irq) { | 1550 | if (want_irq) { |
| 1530 | device_set_wakeup_capable(&client->dev, true); | 1551 | device_set_wakeup_capable(&client->dev, true); |
| 1531 | set_bit(HAS_ALARM, &ds1307->flags); | 1552 | set_bit(HAS_ALARM, &ds1307->flags); |
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 23fa9f0cb5e3..895fbeeb47fe 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c | |||
| @@ -504,12 +504,6 @@ static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
| 504 | alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour; | 504 | alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour; |
| 505 | alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday; | 505 | alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday; |
| 506 | 506 | ||
| 507 | alarm->time.tm_mon = -1; | ||
| 508 | alarm->time.tm_year = -1; | ||
| 509 | alarm->time.tm_wday = -1; | ||
| 510 | alarm->time.tm_yday = -1; | ||
| 511 | alarm->time.tm_isdst = -1; | ||
| 512 | |||
| 513 | out: | 507 | out: |
| 514 | mutex_unlock(&priv->mutex); | 508 | mutex_unlock(&priv->mutex); |
| 515 | return res; | 509 | return res; |
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index b3ce3c652fcd..ed43b4311660 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c | |||
| @@ -103,6 +103,26 @@ ds1685_rtc_bin2bcd(struct ds1685_priv *rtc, u8 val, u8 bin_mask, u8 bcd_mask) | |||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | /** | 105 | /** |
| 106 | * s1685_rtc_check_mday - check validity of the day of month. | ||
| 107 | * @rtc: pointer to the ds1685 rtc structure. | ||
| 108 | * @mday: day of month. | ||
| 109 | * | ||
| 110 | * Returns -EDOM if the day of month is not within 1..31 range. | ||
| 111 | */ | ||
| 112 | static inline int | ||
| 113 | ds1685_rtc_check_mday(struct ds1685_priv *rtc, u8 mday) | ||
| 114 | { | ||
| 115 | if (rtc->bcd_mode) { | ||
| 116 | if (mday < 0x01 || mday > 0x31 || (mday & 0x0f) > 0x09) | ||
| 117 | return -EDOM; | ||
| 118 | } else { | ||
| 119 | if (mday < 1 || mday > 31) | ||
| 120 | return -EDOM; | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 106 | * ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0. | 126 | * ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0. |
| 107 | * @rtc: pointer to the ds1685 rtc structure. | 127 | * @rtc: pointer to the ds1685 rtc structure. |
| 108 | */ | 128 | */ |
| @@ -377,6 +397,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 377 | struct platform_device *pdev = to_platform_device(dev); | 397 | struct platform_device *pdev = to_platform_device(dev); |
| 378 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); | 398 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); |
| 379 | u8 seconds, minutes, hours, mday, ctrlb, ctrlc; | 399 | u8 seconds, minutes, hours, mday, ctrlb, ctrlc; |
| 400 | int ret; | ||
| 380 | 401 | ||
| 381 | /* Fetch the alarm info from the RTC alarm registers. */ | 402 | /* Fetch the alarm info from the RTC alarm registers. */ |
| 382 | ds1685_rtc_begin_data_access(rtc); | 403 | ds1685_rtc_begin_data_access(rtc); |
| @@ -388,34 +409,29 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 388 | ctrlc = rtc->read(rtc, RTC_CTRL_C); | 409 | ctrlc = rtc->read(rtc, RTC_CTRL_C); |
| 389 | ds1685_rtc_end_data_access(rtc); | 410 | ds1685_rtc_end_data_access(rtc); |
| 390 | 411 | ||
| 391 | /* Check month date. */ | 412 | /* Check the month date for validity. */ |
| 392 | if (!(mday >= 1) && (mday <= 31)) | 413 | ret = ds1685_rtc_check_mday(rtc, mday); |
| 393 | return -EDOM; | 414 | if (ret) |
| 415 | return ret; | ||
| 394 | 416 | ||
| 395 | /* | 417 | /* |
| 396 | * Check the three alarm bytes. | 418 | * Check the three alarm bytes. |
| 397 | * | 419 | * |
| 398 | * The Linux RTC system doesn't support the "don't care" capability | 420 | * The Linux RTC system doesn't support the "don't care" capability |
| 399 | * of this RTC chip. We check for it anyways in case support is | 421 | * of this RTC chip. We check for it anyways in case support is |
| 400 | * added in the future. | 422 | * added in the future and only assign when we care. |
| 401 | */ | 423 | */ |
| 402 | if (unlikely(seconds >= 0xc0)) | 424 | if (likely(seconds < 0xc0)) |
| 403 | alrm->time.tm_sec = -1; | ||
| 404 | else | ||
| 405 | alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, | 425 | alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, |
| 406 | RTC_SECS_BCD_MASK, | 426 | RTC_SECS_BCD_MASK, |
| 407 | RTC_SECS_BIN_MASK); | 427 | RTC_SECS_BIN_MASK); |
| 408 | 428 | ||
| 409 | if (unlikely(minutes >= 0xc0)) | 429 | if (likely(minutes < 0xc0)) |
| 410 | alrm->time.tm_min = -1; | ||
| 411 | else | ||
| 412 | alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, | 430 | alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, |
| 413 | RTC_MINS_BCD_MASK, | 431 | RTC_MINS_BCD_MASK, |
| 414 | RTC_MINS_BIN_MASK); | 432 | RTC_MINS_BIN_MASK); |
| 415 | 433 | ||
| 416 | if (unlikely(hours >= 0xc0)) | 434 | if (likely(hours < 0xc0)) |
| 417 | alrm->time.tm_hour = -1; | ||
| 418 | else | ||
| 419 | alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, | 435 | alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, |
| 420 | RTC_HRS_24_BCD_MASK, | 436 | RTC_HRS_24_BCD_MASK, |
| 421 | RTC_HRS_24_BIN_MASK); | 437 | RTC_HRS_24_BIN_MASK); |
| @@ -423,11 +439,6 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 423 | /* Write the data to rtc_wkalrm. */ | 439 | /* Write the data to rtc_wkalrm. */ |
| 424 | alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK, | 440 | alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK, |
| 425 | RTC_MDAY_BIN_MASK); | 441 | RTC_MDAY_BIN_MASK); |
| 426 | alrm->time.tm_mon = -1; | ||
| 427 | alrm->time.tm_year = -1; | ||
| 428 | alrm->time.tm_wday = -1; | ||
| 429 | alrm->time.tm_yday = -1; | ||
| 430 | alrm->time.tm_isdst = -1; | ||
| 431 | alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE); | 442 | alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE); |
| 432 | alrm->pending = !!(ctrlc & RTC_CTRL_C_AF); | 443 | alrm->pending = !!(ctrlc & RTC_CTRL_C_AF); |
| 433 | 444 | ||
| @@ -445,6 +456,7 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 445 | struct platform_device *pdev = to_platform_device(dev); | 456 | struct platform_device *pdev = to_platform_device(dev); |
| 446 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); | 457 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); |
| 447 | u8 ctrlb, seconds, minutes, hours, mday; | 458 | u8 ctrlb, seconds, minutes, hours, mday; |
| 459 | int ret; | ||
| 448 | 460 | ||
| 449 | /* Fetch the alarm info and convert to BCD. */ | 461 | /* Fetch the alarm info and convert to BCD. */ |
| 450 | seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec, | 462 | seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec, |
| @@ -461,8 +473,9 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 461 | RTC_MDAY_BCD_MASK); | 473 | RTC_MDAY_BCD_MASK); |
| 462 | 474 | ||
| 463 | /* Check the month date for validity. */ | 475 | /* Check the month date for validity. */ |
| 464 | if (!(mday >= 1) && (mday <= 31)) | 476 | ret = ds1685_rtc_check_mday(rtc, mday); |
| 465 | return -EDOM; | 477 | if (ret) |
| 478 | return ret; | ||
| 466 | 479 | ||
| 467 | /* | 480 | /* |
| 468 | * Check the three alarm bytes. | 481 | * Check the three alarm bytes. |
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 16310fe79d76..9a1582ed7070 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/bcd.h> | 15 | #include <linux/bcd.h> |
| 16 | #include <linux/rtc-ds2404.h> | 16 | #include <linux/platform_data/rtc-ds2404.h> |
| 17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 04fbd7fffd0d..b1f20d8c358f 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
| @@ -197,12 +197,6 @@ static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
| 197 | alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); | 197 | alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); |
| 198 | alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); | 198 | alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); |
| 199 | 199 | ||
| 200 | alarm->time.tm_mon = -1; | ||
| 201 | alarm->time.tm_year = -1; | ||
| 202 | alarm->time.tm_wday = -1; | ||
| 203 | alarm->time.tm_yday = -1; | ||
| 204 | alarm->time.tm_isdst = -1; | ||
| 205 | |||
| 206 | alarm->enabled = !!(control & DS3232_REG_CR_A1IE); | 200 | alarm->enabled = !!(control & DS3232_REG_CR_A1IE); |
| 207 | alarm->pending = !!(stat & DS3232_REG_SR_A1F); | 201 | alarm->pending = !!(stat & DS3232_REG_SR_A1F); |
| 208 | 202 | ||
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index 96d38609d803..0130afd7fe88 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
| @@ -259,6 +259,12 @@ static const struct rtc_class_ops efi_rtc_ops = { | |||
| 259 | static int __init efi_rtc_probe(struct platform_device *dev) | 259 | static int __init efi_rtc_probe(struct platform_device *dev) |
| 260 | { | 260 | { |
| 261 | struct rtc_device *rtc; | 261 | struct rtc_device *rtc; |
| 262 | efi_time_t eft; | ||
| 263 | efi_time_cap_t cap; | ||
| 264 | |||
| 265 | /* First check if the RTC is usable */ | ||
| 266 | if (efi.get_time(&eft, &cap) != EFI_SUCCESS) | ||
| 267 | return -ENODEV; | ||
| 262 | 268 | ||
| 263 | rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops, | 269 | rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops, |
| 264 | THIS_MODULE); | 270 | THIS_MODULE); |
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c index d726c6aa96a8..1bf5d2347928 100644 --- a/drivers/rtc/rtc-generic.c +++ b/drivers/rtc/rtc-generic.c | |||
| @@ -9,44 +9,10 @@ | |||
| 9 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
| 10 | #include <linux/rtc.h> | 10 | #include <linux/rtc.h> |
| 11 | 11 | ||
| 12 | #if defined(CONFIG_M68K) || defined(CONFIG_PARISC) || \ | ||
| 13 | defined(CONFIG_PPC) || defined(CONFIG_SUPERH32) | ||
| 14 | #include <asm/rtc.h> | ||
| 15 | |||
| 16 | static int generic_get_time(struct device *dev, struct rtc_time *tm) | ||
| 17 | { | ||
| 18 | unsigned int ret = get_rtc_time(tm); | ||
| 19 | |||
| 20 | if (ret & RTC_BATT_BAD) | ||
| 21 | return -EOPNOTSUPP; | ||
| 22 | |||
| 23 | return rtc_valid_tm(tm); | ||
| 24 | } | ||
| 25 | |||
| 26 | static int generic_set_time(struct device *dev, struct rtc_time *tm) | ||
| 27 | { | ||
| 28 | if (set_rtc_time(tm) < 0) | ||
| 29 | return -EOPNOTSUPP; | ||
| 30 | |||
| 31 | return 0; | ||
| 32 | } | ||
| 33 | |||
| 34 | static const struct rtc_class_ops generic_rtc_ops = { | ||
| 35 | .read_time = generic_get_time, | ||
| 36 | .set_time = generic_set_time, | ||
| 37 | }; | ||
| 38 | #else | ||
| 39 | #define generic_rtc_ops *(struct rtc_class_ops*)NULL | ||
| 40 | #endif | ||
| 41 | |||
| 42 | static int __init generic_rtc_probe(struct platform_device *dev) | 12 | static int __init generic_rtc_probe(struct platform_device *dev) |
| 43 | { | 13 | { |
| 44 | struct rtc_device *rtc; | 14 | struct rtc_device *rtc; |
| 45 | const struct rtc_class_ops *ops; | 15 | const struct rtc_class_ops *ops = dev_get_platdata(&dev->dev); |
| 46 | |||
| 47 | ops = dev_get_platdata(&dev->dev); | ||
| 48 | if (!ops) | ||
| 49 | ops = &generic_rtc_ops; | ||
| 50 | 16 | ||
| 51 | rtc = devm_rtc_device_register(&dev->dev, "rtc-generic", | 17 | rtc = devm_rtc_device_register(&dev->dev, "rtc-generic", |
| 52 | ops, THIS_MODULE); | 18 | ops, THIS_MODULE); |
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 207270376b55..e5ad527cb75e 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c | |||
| @@ -198,7 +198,7 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 198 | return ret; | 198 | return ret; |
| 199 | 199 | ||
| 200 | /* The alarm only has a minute accuracy */ | 200 | /* The alarm only has a minute accuracy */ |
| 201 | alm_tm->tm_sec = -1; | 201 | alm_tm->tm_sec = 0; |
| 202 | 202 | ||
| 203 | alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ? | 203 | alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ? |
| 204 | -1 : | 204 | -1 : |
| @@ -213,9 +213,6 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 213 | -1 : | 213 | -1 : |
| 214 | bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK); | 214 | bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK); |
| 215 | 215 | ||
| 216 | alm_tm->tm_mon = -1; | ||
| 217 | alm_tm->tm_year = -1; | ||
| 218 | |||
| 219 | ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); | 216 | ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); |
| 220 | if (ret < 0) | 217 | if (ret < 0) |
| 221 | return ret; | 218 | return ret; |
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index 54328d4ac0d3..0e7f0f52bfe4 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c | |||
| @@ -245,8 +245,7 @@ static int isl12057_rtc_update_alarm(struct device *dev, int enable) | |||
| 245 | static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 245 | static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
| 246 | { | 246 | { |
| 247 | struct isl12057_rtc_data *data = dev_get_drvdata(dev); | 247 | struct isl12057_rtc_data *data = dev_get_drvdata(dev); |
| 248 | struct rtc_time rtc_tm, *alarm_tm = &alarm->time; | 248 | struct rtc_time *alarm_tm = &alarm->time; |
| 249 | unsigned long rtc_secs, alarm_secs; | ||
| 250 | u8 regs[ISL12057_A1_SEC_LEN]; | 249 | u8 regs[ISL12057_A1_SEC_LEN]; |
| 251 | unsigned int ir; | 250 | unsigned int ir; |
| 252 | int ret; | 251 | int ret; |
| @@ -264,36 +263,6 @@ static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
| 264 | alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f); | 263 | alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f); |
| 265 | alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f); | 264 | alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f); |
| 266 | alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f); | 265 | alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f); |
| 267 | alarm_tm->tm_wday = -1; | ||
| 268 | |||
| 269 | /* | ||
| 270 | * The alarm section does not store year/month. We use the ones in rtc | ||
| 271 | * section as a basis and increment month and then year if needed to get | ||
| 272 | * alarm after current time. | ||
| 273 | */ | ||
| 274 | ret = _isl12057_rtc_read_time(dev, &rtc_tm); | ||
| 275 | if (ret) | ||
| 276 | goto err_unlock; | ||
| 277 | |||
| 278 | alarm_tm->tm_year = rtc_tm.tm_year; | ||
| 279 | alarm_tm->tm_mon = rtc_tm.tm_mon; | ||
| 280 | |||
| 281 | ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); | ||
| 282 | if (ret) | ||
| 283 | goto err_unlock; | ||
| 284 | |||
| 285 | ret = rtc_tm_to_time(alarm_tm, &alarm_secs); | ||
| 286 | if (ret) | ||
| 287 | goto err_unlock; | ||
| 288 | |||
| 289 | if (alarm_secs < rtc_secs) { | ||
| 290 | if (alarm_tm->tm_mon == 11) { | ||
| 291 | alarm_tm->tm_mon = 0; | ||
| 292 | alarm_tm->tm_year += 1; | ||
| 293 | } else { | ||
| 294 | alarm_tm->tm_mon += 1; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | 266 | ||
| 298 | ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir); | 267 | ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir); |
| 299 | if (ret) { | 268 | if (ret) { |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index d1bf93a87200..58698d21c2c3 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
| @@ -244,7 +244,7 @@ static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
| 244 | 244 | ||
| 245 | retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags); | 245 | retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags); |
| 246 | if (retval < 0) { | 246 | if (retval < 0) { |
| 247 | dev_info(dev, "Unable to enable alarm IRQ %d\n", retval); | 247 | dev_err(dev, "Unable to enable alarm IRQ %d\n", retval); |
| 248 | return retval; | 248 | return retval; |
| 249 | } | 249 | } |
| 250 | return 0; | 250 | return 0; |
| @@ -320,10 +320,8 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 320 | alrm->time.tm_sec = bcd2bin(alarmvals[4] & 0x7f); | 320 | alrm->time.tm_sec = bcd2bin(alarmvals[4] & 0x7f); |
| 321 | alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f); | 321 | alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f); |
| 322 | alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); | 322 | alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); |
| 323 | alrm->time.tm_wday = -1; | ||
| 324 | alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f); | 323 | alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f); |
| 325 | alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f); | 324 | alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f); |
| 326 | alrm->time.tm_year = -1; | ||
| 327 | 325 | ||
| 328 | alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE); | 326 | alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE); |
| 329 | alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled; | 327 | alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled; |
| @@ -337,6 +335,30 @@ static struct rtc_class_ops m41t80_rtc_ops = { | |||
| 337 | .proc = m41t80_rtc_proc, | 335 | .proc = m41t80_rtc_proc, |
| 338 | }; | 336 | }; |
| 339 | 337 | ||
| 338 | #ifdef CONFIG_PM_SLEEP | ||
| 339 | static int m41t80_suspend(struct device *dev) | ||
| 340 | { | ||
| 341 | struct i2c_client *client = to_i2c_client(dev); | ||
| 342 | |||
| 343 | if (client->irq >= 0 && device_may_wakeup(dev)) | ||
| 344 | enable_irq_wake(client->irq); | ||
| 345 | |||
| 346 | return 0; | ||
| 347 | } | ||
| 348 | |||
| 349 | static int m41t80_resume(struct device *dev) | ||
| 350 | { | ||
| 351 | struct i2c_client *client = to_i2c_client(dev); | ||
| 352 | |||
| 353 | if (client->irq >= 0 && device_may_wakeup(dev)) | ||
| 354 | disable_irq_wake(client->irq); | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | #endif | ||
| 359 | |||
| 360 | static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume); | ||
| 361 | |||
| 340 | static ssize_t flags_show(struct device *dev, | 362 | static ssize_t flags_show(struct device *dev, |
| 341 | struct device_attribute *attr, char *buf) | 363 | struct device_attribute *attr, char *buf) |
| 342 | { | 364 | { |
| @@ -831,10 +853,9 @@ static int m41t80_probe(struct i2c_client *client, | |||
| 831 | return rc; | 853 | return rc; |
| 832 | } | 854 | } |
| 833 | 855 | ||
| 834 | rc = devm_add_action(&client->dev, m41t80_remove_sysfs_group, | 856 | rc = devm_add_action_or_reset(&client->dev, m41t80_remove_sysfs_group, |
| 835 | &client->dev); | 857 | &client->dev); |
| 836 | if (rc) { | 858 | if (rc) { |
| 837 | m41t80_remove_sysfs_group(&client->dev); | ||
| 838 | dev_err(&client->dev, | 859 | dev_err(&client->dev, |
| 839 | "Failed to add sysfs cleanup action: %d\n", rc); | 860 | "Failed to add sysfs cleanup action: %d\n", rc); |
| 840 | return rc; | 861 | return rc; |
| @@ -873,6 +894,7 @@ static int m41t80_remove(struct i2c_client *client) | |||
| 873 | static struct i2c_driver m41t80_driver = { | 894 | static struct i2c_driver m41t80_driver = { |
| 874 | .driver = { | 895 | .driver = { |
| 875 | .name = "rtc-m41t80", | 896 | .name = "rtc-m41t80", |
| 897 | .pm = &m41t80_pm, | ||
| 876 | }, | 898 | }, |
| 877 | .probe = m41t80_probe, | 899 | .probe = m41t80_probe, |
| 878 | .remove = m41t80_remove, | 900 | .remove = m41t80_remove, |
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index f72b91f2501f..0eeb5714c00f 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/rtc.h> | 17 | #include <linux/rtc.h> |
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/m48t86.h> | 19 | #include <linux/platform_data/rtc-m48t86.h> |
| 20 | #include <linux/bcd.h> | 20 | #include <linux/bcd.h> |
| 21 | 21 | ||
| 22 | #define M48T86_REG_SEC 0x00 | 22 | #define M48T86_REG_SEC 0x00 |
diff --git a/drivers/rtc/rtc-max6916.c b/drivers/rtc/rtc-max6916.c new file mode 100644 index 000000000000..623ab27b2757 --- /dev/null +++ b/drivers/rtc/rtc-max6916.c | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | /* rtc-max6916.c | ||
| 2 | * | ||
| 3 | * Driver for MAXIM max6916 Low Current, SPI Compatible | ||
| 4 | * Real Time Clock | ||
| 5 | * | ||
| 6 | * Author : Venkat Prashanth B U <venkat.prashanth2498@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/rtc.h> | ||
| 19 | #include <linux/spi/spi.h> | ||
| 20 | #include <linux/bcd.h> | ||
| 21 | |||
| 22 | /* Registers in max6916 rtc */ | ||
| 23 | |||
| 24 | #define MAX6916_SECONDS_REG 0x01 | ||
| 25 | #define MAX6916_MINUTES_REG 0x02 | ||
| 26 | #define MAX6916_HOURS_REG 0x03 | ||
| 27 | #define MAX6916_DATE_REG 0x04 | ||
| 28 | #define MAX6916_MONTH_REG 0x05 | ||
| 29 | #define MAX6916_DAY_REG 0x06 | ||
| 30 | #define MAX6916_YEAR_REG 0x07 | ||
| 31 | #define MAX6916_CONTROL_REG 0x08 | ||
| 32 | #define MAX6916_STATUS_REG 0x0C | ||
| 33 | #define MAX6916_CLOCK_BURST 0x3F | ||
| 34 | |||
| 35 | static int max6916_read_reg(struct device *dev, unsigned char address, | ||
| 36 | unsigned char *data) | ||
| 37 | { | ||
| 38 | struct spi_device *spi = to_spi_device(dev); | ||
| 39 | |||
| 40 | *data = address | 0x80; | ||
| 41 | |||
| 42 | return spi_write_then_read(spi, data, 1, data, 1); | ||
| 43 | } | ||
| 44 | |||
| 45 | static int max6916_write_reg(struct device *dev, unsigned char address, | ||
| 46 | unsigned char data) | ||
| 47 | { | ||
| 48 | struct spi_device *spi = to_spi_device(dev); | ||
| 49 | unsigned char buf[2]; | ||
| 50 | |||
| 51 | buf[0] = address & 0x7F; | ||
| 52 | buf[1] = data; | ||
| 53 | |||
| 54 | return spi_write_then_read(spi, buf, 2, NULL, 0); | ||
| 55 | } | ||
| 56 | |||
| 57 | static int max6916_read_time(struct device *dev, struct rtc_time *dt) | ||
| 58 | { | ||
| 59 | struct spi_device *spi = to_spi_device(dev); | ||
| 60 | int err; | ||
| 61 | unsigned char buf[8]; | ||
| 62 | |||
| 63 | buf[0] = MAX6916_CLOCK_BURST | 0x80; | ||
| 64 | |||
| 65 | err = spi_write_then_read(spi, buf, 1, buf, 8); | ||
| 66 | |||
| 67 | if (err) | ||
| 68 | return err; | ||
| 69 | |||
| 70 | dt->tm_sec = bcd2bin(buf[0]); | ||
| 71 | dt->tm_min = bcd2bin(buf[1]); | ||
| 72 | dt->tm_hour = bcd2bin(buf[2] & 0x3F); | ||
| 73 | dt->tm_mday = bcd2bin(buf[3]); | ||
| 74 | dt->tm_mon = bcd2bin(buf[4]) - 1; | ||
| 75 | dt->tm_wday = bcd2bin(buf[5]) - 1; | ||
| 76 | dt->tm_year = bcd2bin(buf[6]) + 100; | ||
| 77 | |||
| 78 | return rtc_valid_tm(dt); | ||
| 79 | } | ||
| 80 | |||
| 81 | static int max6916_set_time(struct device *dev, struct rtc_time *dt) | ||
| 82 | { | ||
| 83 | struct spi_device *spi = to_spi_device(dev); | ||
| 84 | unsigned char buf[9]; | ||
| 85 | |||
| 86 | if (dt->tm_year < 100 || dt->tm_year > 199) { | ||
| 87 | dev_err(&spi->dev, "Year must be between 2000 and 2099. It's %d.\n", | ||
| 88 | dt->tm_year + 1900); | ||
| 89 | return -EINVAL; | ||
| 90 | } | ||
| 91 | |||
| 92 | buf[0] = MAX6916_CLOCK_BURST & 0x7F; | ||
| 93 | buf[1] = bin2bcd(dt->tm_sec); | ||
| 94 | buf[2] = bin2bcd(dt->tm_min); | ||
| 95 | buf[3] = (bin2bcd(dt->tm_hour) & 0X3F); | ||
| 96 | buf[4] = bin2bcd(dt->tm_mday); | ||
| 97 | buf[5] = bin2bcd(dt->tm_mon + 1); | ||
| 98 | buf[6] = bin2bcd(dt->tm_wday + 1); | ||
| 99 | buf[7] = bin2bcd(dt->tm_year % 100); | ||
| 100 | buf[8] = bin2bcd(0x00); | ||
| 101 | |||
| 102 | /* write the rtc settings */ | ||
| 103 | return spi_write_then_read(spi, buf, 9, NULL, 0); | ||
| 104 | } | ||
| 105 | |||
| 106 | static const struct rtc_class_ops max6916_rtc_ops = { | ||
| 107 | .read_time = max6916_read_time, | ||
| 108 | .set_time = max6916_set_time, | ||
| 109 | }; | ||
| 110 | |||
| 111 | static int max6916_probe(struct spi_device *spi) | ||
| 112 | { | ||
| 113 | struct rtc_device *rtc; | ||
| 114 | unsigned char data; | ||
| 115 | int res; | ||
| 116 | |||
| 117 | /* spi setup with max6916 in mode 3 and bits per word as 8 */ | ||
| 118 | spi->mode = SPI_MODE_3; | ||
| 119 | spi->bits_per_word = 8; | ||
| 120 | spi_setup(spi); | ||
| 121 | |||
| 122 | /* RTC Settings */ | ||
| 123 | res = max6916_read_reg(&spi->dev, MAX6916_SECONDS_REG, &data); | ||
| 124 | if (res) | ||
| 125 | return res; | ||
| 126 | |||
| 127 | /* Disable the write protect of rtc */ | ||
| 128 | max6916_read_reg(&spi->dev, MAX6916_CONTROL_REG, &data); | ||
| 129 | data = data & ~(1 << 7); | ||
| 130 | max6916_write_reg(&spi->dev, MAX6916_CONTROL_REG, data); | ||
| 131 | |||
| 132 | /*Enable oscillator,disable oscillator stop flag, glitch filter*/ | ||
| 133 | max6916_read_reg(&spi->dev, MAX6916_STATUS_REG, &data); | ||
| 134 | data = data & 0x1B; | ||
| 135 | max6916_write_reg(&spi->dev, MAX6916_STATUS_REG, data); | ||
| 136 | |||
| 137 | /* display the settings */ | ||
| 138 | max6916_read_reg(&spi->dev, MAX6916_CONTROL_REG, &data); | ||
| 139 | dev_info(&spi->dev, "MAX6916 RTC CTRL Reg = 0x%02x\n", data); | ||
| 140 | |||
| 141 | max6916_read_reg(&spi->dev, MAX6916_STATUS_REG, &data); | ||
| 142 | dev_info(&spi->dev, "MAX6916 RTC Status Reg = 0x%02x\n", data); | ||
| 143 | |||
| 144 | rtc = devm_rtc_device_register(&spi->dev, "max6916", | ||
| 145 | &max6916_rtc_ops, THIS_MODULE); | ||
| 146 | if (IS_ERR(rtc)) | ||
| 147 | return PTR_ERR(rtc); | ||
| 148 | |||
| 149 | spi_set_drvdata(spi, rtc); | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | static struct spi_driver max6916_driver = { | ||
| 155 | .driver = { | ||
| 156 | .name = "max6916", | ||
| 157 | }, | ||
| 158 | .probe = max6916_probe, | ||
| 159 | }; | ||
| 160 | module_spi_driver(max6916_driver); | ||
| 161 | |||
| 162 | MODULE_DESCRIPTION("MAX6916 SPI RTC DRIVER"); | ||
| 163 | MODULE_AUTHOR("Venkat Prashanth B U <venkat.prashanth2498@gmail.com>"); | ||
| 164 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c new file mode 100644 index 000000000000..2f1772a358ca --- /dev/null +++ b/drivers/rtc/rtc-mc146818-lib.c | |||
| @@ -0,0 +1,198 @@ | |||
| 1 | #include <linux/bcd.h> | ||
| 2 | #include <linux/delay.h> | ||
| 3 | #include <linux/export.h> | ||
| 4 | #include <linux/mc146818rtc.h> | ||
| 5 | |||
| 6 | #ifdef CONFIG_ACPI | ||
| 7 | #include <linux/acpi.h> | ||
| 8 | #endif | ||
| 9 | |||
| 10 | /* | ||
| 11 | * Returns true if a clock update is in progress | ||
| 12 | */ | ||
| 13 | static inline unsigned char mc146818_is_updating(void) | ||
| 14 | { | ||
| 15 | unsigned char uip; | ||
| 16 | unsigned long flags; | ||
| 17 | |||
| 18 | spin_lock_irqsave(&rtc_lock, flags); | ||
| 19 | uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); | ||
| 20 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 21 | return uip; | ||
| 22 | } | ||
| 23 | |||
| 24 | unsigned int mc146818_get_time(struct rtc_time *time) | ||
| 25 | { | ||
| 26 | unsigned char ctrl; | ||
| 27 | unsigned long flags; | ||
| 28 | unsigned char century = 0; | ||
| 29 | |||
| 30 | #ifdef CONFIG_MACH_DECSTATION | ||
| 31 | unsigned int real_year; | ||
| 32 | #endif | ||
| 33 | |||
| 34 | /* | ||
| 35 | * read RTC once any update in progress is done. The update | ||
| 36 | * can take just over 2ms. We wait 20ms. There is no need to | ||
| 37 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. | ||
| 38 | * If you need to know *exactly* when a second has started, enable | ||
| 39 | * periodic update complete interrupts, (via ioctl) and then | ||
| 40 | * immediately read /dev/rtc which will block until you get the IRQ. | ||
| 41 | * Once the read clears, read the RTC time (again via ioctl). Easy. | ||
| 42 | */ | ||
| 43 | if (mc146818_is_updating()) | ||
| 44 | mdelay(20); | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Only the values that we read from the RTC are set. We leave | ||
| 48 | * tm_wday, tm_yday and tm_isdst untouched. Even though the | ||
| 49 | * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated | ||
| 50 | * by the RTC when initially set to a non-zero value. | ||
| 51 | */ | ||
| 52 | spin_lock_irqsave(&rtc_lock, flags); | ||
| 53 | time->tm_sec = CMOS_READ(RTC_SECONDS); | ||
| 54 | time->tm_min = CMOS_READ(RTC_MINUTES); | ||
| 55 | time->tm_hour = CMOS_READ(RTC_HOURS); | ||
| 56 | time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); | ||
| 57 | time->tm_mon = CMOS_READ(RTC_MONTH); | ||
| 58 | time->tm_year = CMOS_READ(RTC_YEAR); | ||
| 59 | #ifdef CONFIG_MACH_DECSTATION | ||
| 60 | real_year = CMOS_READ(RTC_DEC_YEAR); | ||
| 61 | #endif | ||
| 62 | #ifdef CONFIG_ACPI | ||
| 63 | if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | ||
| 64 | acpi_gbl_FADT.century) | ||
| 65 | century = CMOS_READ(acpi_gbl_FADT.century); | ||
| 66 | #endif | ||
| 67 | ctrl = CMOS_READ(RTC_CONTROL); | ||
| 68 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 69 | |||
| 70 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
| 71 | { | ||
| 72 | time->tm_sec = bcd2bin(time->tm_sec); | ||
| 73 | time->tm_min = bcd2bin(time->tm_min); | ||
| 74 | time->tm_hour = bcd2bin(time->tm_hour); | ||
| 75 | time->tm_mday = bcd2bin(time->tm_mday); | ||
| 76 | time->tm_mon = bcd2bin(time->tm_mon); | ||
| 77 | time->tm_year = bcd2bin(time->tm_year); | ||
| 78 | century = bcd2bin(century); | ||
| 79 | } | ||
| 80 | |||
| 81 | #ifdef CONFIG_MACH_DECSTATION | ||
| 82 | time->tm_year += real_year - 72; | ||
| 83 | #endif | ||
| 84 | |||
| 85 | if (century) | ||
| 86 | time->tm_year += (century - 19) * 100; | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Account for differences between how the RTC uses the values | ||
| 90 | * and how they are defined in a struct rtc_time; | ||
| 91 | */ | ||
| 92 | if (time->tm_year <= 69) | ||
| 93 | time->tm_year += 100; | ||
| 94 | |||
| 95 | time->tm_mon--; | ||
| 96 | |||
| 97 | return RTC_24H; | ||
| 98 | } | ||
| 99 | EXPORT_SYMBOL_GPL(mc146818_get_time); | ||
| 100 | |||
| 101 | /* Set the current date and time in the real time clock. */ | ||
| 102 | int mc146818_set_time(struct rtc_time *time) | ||
| 103 | { | ||
| 104 | unsigned long flags; | ||
| 105 | unsigned char mon, day, hrs, min, sec; | ||
| 106 | unsigned char save_control, save_freq_select; | ||
| 107 | unsigned int yrs; | ||
| 108 | #ifdef CONFIG_MACH_DECSTATION | ||
| 109 | unsigned int real_yrs, leap_yr; | ||
| 110 | #endif | ||
| 111 | unsigned char century = 0; | ||
| 112 | |||
| 113 | yrs = time->tm_year; | ||
| 114 | mon = time->tm_mon + 1; /* tm_mon starts at zero */ | ||
| 115 | day = time->tm_mday; | ||
| 116 | hrs = time->tm_hour; | ||
| 117 | min = time->tm_min; | ||
| 118 | sec = time->tm_sec; | ||
| 119 | |||
| 120 | if (yrs > 255) /* They are unsigned */ | ||
| 121 | return -EINVAL; | ||
| 122 | |||
| 123 | spin_lock_irqsave(&rtc_lock, flags); | ||
| 124 | #ifdef CONFIG_MACH_DECSTATION | ||
| 125 | real_yrs = yrs; | ||
| 126 | leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) || | ||
| 127 | !((yrs + 1900) % 400)); | ||
| 128 | yrs = 72; | ||
| 129 | |||
| 130 | /* | ||
| 131 | * We want to keep the year set to 73 until March | ||
| 132 | * for non-leap years, so that Feb, 29th is handled | ||
| 133 | * correctly. | ||
| 134 | */ | ||
| 135 | if (!leap_yr && mon < 3) { | ||
| 136 | real_yrs--; | ||
| 137 | yrs = 73; | ||
| 138 | } | ||
| 139 | #endif | ||
| 140 | |||
| 141 | #ifdef CONFIG_ACPI | ||
| 142 | if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | ||
| 143 | acpi_gbl_FADT.century) { | ||
| 144 | century = (yrs + 1900) / 100; | ||
| 145 | yrs %= 100; | ||
| 146 | } | ||
| 147 | #endif | ||
| 148 | |||
| 149 | /* These limits and adjustments are independent of | ||
| 150 | * whether the chip is in binary mode or not. | ||
| 151 | */ | ||
| 152 | if (yrs > 169) { | ||
| 153 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 154 | return -EINVAL; | ||
| 155 | } | ||
| 156 | |||
| 157 | if (yrs >= 100) | ||
| 158 | yrs -= 100; | ||
| 159 | |||
| 160 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) | ||
| 161 | || RTC_ALWAYS_BCD) { | ||
| 162 | sec = bin2bcd(sec); | ||
| 163 | min = bin2bcd(min); | ||
| 164 | hrs = bin2bcd(hrs); | ||
| 165 | day = bin2bcd(day); | ||
| 166 | mon = bin2bcd(mon); | ||
| 167 | yrs = bin2bcd(yrs); | ||
| 168 | century = bin2bcd(century); | ||
| 169 | } | ||
| 170 | |||
| 171 | save_control = CMOS_READ(RTC_CONTROL); | ||
| 172 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); | ||
| 173 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); | ||
| 174 | CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | ||
| 175 | |||
| 176 | #ifdef CONFIG_MACH_DECSTATION | ||
| 177 | CMOS_WRITE(real_yrs, RTC_DEC_YEAR); | ||
| 178 | #endif | ||
| 179 | CMOS_WRITE(yrs, RTC_YEAR); | ||
| 180 | CMOS_WRITE(mon, RTC_MONTH); | ||
| 181 | CMOS_WRITE(day, RTC_DAY_OF_MONTH); | ||
| 182 | CMOS_WRITE(hrs, RTC_HOURS); | ||
| 183 | CMOS_WRITE(min, RTC_MINUTES); | ||
| 184 | CMOS_WRITE(sec, RTC_SECONDS); | ||
| 185 | #ifdef CONFIG_ACPI | ||
| 186 | if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && | ||
| 187 | acpi_gbl_FADT.century) | ||
| 188 | CMOS_WRITE(century, acpi_gbl_FADT.century); | ||
| 189 | #endif | ||
| 190 | |||
| 191 | CMOS_WRITE(save_control, RTC_CONTROL); | ||
| 192 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); | ||
| 193 | |||
| 194 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 195 | |||
| 196 | return 0; | ||
| 197 | } | ||
| 198 | EXPORT_SYMBOL_GPL(mc146818_set_time); | ||
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 0094d9bdd1e6..7334c44fa7c3 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c | |||
| @@ -32,11 +32,11 @@ | |||
| 32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
| 33 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
| 34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
| 35 | #include <linux/mc146818rtc.h> | ||
| 35 | #include <linux/module.h> | 36 | #include <linux/module.h> |
| 36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 37 | #include <linux/sfi.h> | 38 | #include <linux/sfi.h> |
| 38 | 39 | ||
| 39 | #include <asm-generic/rtc.h> | ||
| 40 | #include <asm/intel_scu_ipc.h> | 40 | #include <asm/intel_scu_ipc.h> |
| 41 | #include <asm/intel-mid.h> | 41 | #include <asm/intel-mid.h> |
| 42 | #include <asm/intel_mid_vrtc.h> | 42 | #include <asm/intel_mid_vrtc.h> |
| @@ -149,14 +149,6 @@ static int mrst_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 149 | if (mrst->irq <= 0) | 149 | if (mrst->irq <= 0) |
| 150 | return -EIO; | 150 | return -EIO; |
| 151 | 151 | ||
| 152 | /* Basic alarms only support hour, minute, and seconds fields. | ||
| 153 | * Some also support day and month, for alarms up to a year in | ||
| 154 | * the future. | ||
| 155 | */ | ||
| 156 | t->time.tm_mday = -1; | ||
| 157 | t->time.tm_mon = -1; | ||
| 158 | t->time.tm_year = -1; | ||
| 159 | |||
| 160 | /* vRTC only supports binary mode */ | 152 | /* vRTC only supports binary mode */ |
| 161 | spin_lock_irq(&rtc_lock); | 153 | spin_lock_irq(&rtc_lock); |
| 162 | t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM); | 154 | t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM); |
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index f22e060709e5..b4478cc92b55 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c | |||
| @@ -96,7 +96,7 @@ | |||
| 96 | #define CD_TMR_TE BIT(3) /* Countdown timer enable */ | 96 | #define CD_TMR_TE BIT(3) /* Countdown timer enable */ |
| 97 | 97 | ||
| 98 | /* PCF2123_REG_OFFSET BITS */ | 98 | /* PCF2123_REG_OFFSET BITS */ |
| 99 | #define OFFSET_SIGN_BIT BIT(6) /* 2's complement sign bit */ | 99 | #define OFFSET_SIGN_BIT 6 /* 2's complement sign bit */ |
| 100 | #define OFFSET_COARSE BIT(7) /* Coarse mode offset */ | 100 | #define OFFSET_COARSE BIT(7) /* Coarse mode offset */ |
| 101 | #define OFFSET_STEP (2170) /* Offset step in parts per billion */ | 101 | #define OFFSET_STEP (2170) /* Offset step in parts per billion */ |
| 102 | 102 | ||
| @@ -217,7 +217,7 @@ static int pcf2123_read_offset(struct device *dev, long *offset) | |||
| 217 | if (reg & OFFSET_COARSE) | 217 | if (reg & OFFSET_COARSE) |
| 218 | reg <<= 1; /* multiply by 2 and sign extend */ | 218 | reg <<= 1; /* multiply by 2 and sign extend */ |
| 219 | else | 219 | else |
| 220 | reg |= (reg & OFFSET_SIGN_BIT) << 1; /* sign extend only */ | 220 | reg = sign_extend32(reg, OFFSET_SIGN_BIT); |
| 221 | 221 | ||
| 222 | *offset = ((long)reg) * OFFSET_STEP; | 222 | *offset = ((long)reg) * OFFSET_STEP; |
| 223 | 223 | ||
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index e8ddbb359d11..efb0a08ac117 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c | |||
| @@ -16,6 +16,16 @@ | |||
| 16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | 18 | ||
| 19 | /* | ||
| 20 | * Information for this driver was pulled from the following datasheets. | ||
| 21 | * | ||
| 22 | * http://www.nxp.com/documents/data_sheet/PCF85063A.pdf | ||
| 23 | * http://www.nxp.com/documents/data_sheet/PCF85063TP.pdf | ||
| 24 | * | ||
| 25 | * PCF85063A -- Rev. 6 — 18 November 2015 | ||
| 26 | * PCF85063TP -- Rev. 4 — 6 May 2015 | ||
| 27 | */ | ||
| 28 | |||
| 19 | #define PCF85063_REG_CTRL1 0x00 /* status */ | 29 | #define PCF85063_REG_CTRL1 0x00 /* status */ |
| 20 | #define PCF85063_REG_CTRL1_STOP BIT(5) | 30 | #define PCF85063_REG_CTRL1_STOP BIT(5) |
| 21 | #define PCF85063_REG_CTRL2 0x01 | 31 | #define PCF85063_REG_CTRL2 0x01 |
| @@ -55,10 +65,22 @@ static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1) | |||
| 55 | return 0; | 65 | return 0; |
| 56 | } | 66 | } |
| 57 | 67 | ||
| 58 | /* | 68 | static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) |
| 59 | * In the routines that deal directly with the pcf85063 hardware, we use | 69 | { |
| 60 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | 70 | s32 ret; |
| 61 | */ | 71 | |
| 72 | /* start the clock */ | ||
| 73 | ctrl1 &= PCF85063_REG_CTRL1_STOP; | ||
| 74 | |||
| 75 | ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1); | ||
| 76 | if (ret < 0) { | ||
| 77 | dev_err(&client->dev, "Failing to start the clock\n"); | ||
| 78 | return -EIO; | ||
| 79 | } | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 62 | static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | 84 | static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) |
| 63 | { | 85 | { |
| 64 | int rc; | 86 | int rc; |
| @@ -90,8 +112,7 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
| 90 | tm->tm_wday = regs[4] & 0x07; | 112 | tm->tm_wday = regs[4] & 0x07; |
| 91 | tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */ | 113 | tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */ |
| 92 | tm->tm_year = bcd2bin(regs[6]); | 114 | tm->tm_year = bcd2bin(regs[6]); |
| 93 | if (tm->tm_year < 70) | 115 | tm->tm_year += 100; |
| 94 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
| 95 | 116 | ||
| 96 | return rtc_valid_tm(tm); | 117 | return rtc_valid_tm(tm); |
| 97 | } | 118 | } |
| @@ -99,13 +120,17 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
| 99 | static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 120 | static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
| 100 | { | 121 | { |
| 101 | int rc; | 122 | int rc; |
| 102 | u8 regs[8]; | 123 | u8 regs[7]; |
| 124 | u8 ctrl1; | ||
| 125 | |||
| 126 | if ((tm->tm_year < 100) || (tm->tm_year > 199)) | ||
| 127 | return -EINVAL; | ||
| 103 | 128 | ||
| 104 | /* | 129 | /* |
| 105 | * to accurately set the time, reset the divider chain and keep it in | 130 | * to accurately set the time, reset the divider chain and keep it in |
| 106 | * reset state until all time/date registers are written | 131 | * reset state until all time/date registers are written |
| 107 | */ | 132 | */ |
| 108 | rc = pcf85063_stop_clock(client, ®s[7]); | 133 | rc = pcf85063_stop_clock(client, &ctrl1); |
| 109 | if (rc != 0) | 134 | if (rc != 0) |
| 110 | return rc; | 135 | return rc; |
| 111 | 136 | ||
| @@ -125,14 +150,7 @@ static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
| 125 | regs[5] = bin2bcd(tm->tm_mon + 1); | 150 | regs[5] = bin2bcd(tm->tm_mon + 1); |
| 126 | 151 | ||
| 127 | /* year and century */ | 152 | /* year and century */ |
| 128 | regs[6] = bin2bcd(tm->tm_year % 100); | 153 | regs[6] = bin2bcd(tm->tm_year - 100); |
| 129 | |||
| 130 | /* | ||
| 131 | * after all time/date registers are written, let the 'address auto | ||
| 132 | * increment' feature wrap around and write register CTRL1 to re-enable | ||
| 133 | * the clock divider chain again | ||
| 134 | */ | ||
| 135 | regs[7] &= ~PCF85063_REG_CTRL1_STOP; | ||
| 136 | 154 | ||
| 137 | /* write all registers at once */ | 155 | /* write all registers at once */ |
| 138 | rc = i2c_smbus_write_i2c_block_data(client, PCF85063_REG_SC, | 156 | rc = i2c_smbus_write_i2c_block_data(client, PCF85063_REG_SC, |
| @@ -142,6 +160,15 @@ static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
| 142 | return rc; | 160 | return rc; |
| 143 | } | 161 | } |
| 144 | 162 | ||
| 163 | /* | ||
| 164 | * Write the control register as a separate action since the size of | ||
| 165 | * the register space is different between the PCF85063TP and | ||
| 166 | * PCF85063A devices. The rollover point can not be used. | ||
| 167 | */ | ||
| 168 | rc = pcf85063_start_clock(client, ctrl1); | ||
| 169 | if (rc != 0) | ||
| 170 | return rc; | ||
| 171 | |||
| 145 | return 0; | 172 | return 0; |
| 146 | } | 173 | } |
| 147 | 174 | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index b9ddbb001283..1227ceab61ee 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
| @@ -341,14 +341,11 @@ static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) | |||
| 341 | "%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n", | 341 | "%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n", |
| 342 | __func__, buf[0], buf[1], buf[2], buf[3]); | 342 | __func__, buf[0], buf[1], buf[2], buf[3]); |
| 343 | 343 | ||
| 344 | tm->time.tm_sec = 0; | ||
| 344 | tm->time.tm_min = bcd2bin(buf[0] & 0x7F); | 345 | tm->time.tm_min = bcd2bin(buf[0] & 0x7F); |
| 345 | tm->time.tm_hour = bcd2bin(buf[1] & 0x3F); | 346 | tm->time.tm_hour = bcd2bin(buf[1] & 0x3F); |
| 346 | tm->time.tm_mday = bcd2bin(buf[2] & 0x3F); | 347 | tm->time.tm_mday = bcd2bin(buf[2] & 0x3F); |
| 347 | tm->time.tm_wday = bcd2bin(buf[3] & 0x7); | 348 | tm->time.tm_wday = bcd2bin(buf[3] & 0x7); |
| 348 | tm->time.tm_mon = -1; | ||
| 349 | tm->time.tm_year = -1; | ||
| 350 | tm->time.tm_yday = -1; | ||
| 351 | tm->time.tm_isdst = -1; | ||
| 352 | 349 | ||
| 353 | err = pcf8563_get_alarm_mode(client, &tm->enabled, &tm->pending); | 350 | err = pcf8563_get_alarm_mode(client, &tm->enabled, &tm->pending); |
| 354 | if (err < 0) | 351 | if (err < 0) |
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c index f28d57788951..68ce77414bdc 100644 --- a/drivers/rtc/rtc-rc5t583.c +++ b/drivers/rtc/rtc-rc5t583.c | |||
| @@ -128,6 +128,7 @@ static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
| 128 | return ret; | 128 | return ret; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | alm->time.tm_sec = 0; | ||
| 131 | alm->time.tm_min = bcd2bin(alarm_data[0]); | 132 | alm->time.tm_min = bcd2bin(alarm_data[0]); |
| 132 | alm->time.tm_hour = bcd2bin(alarm_data[1]); | 133 | alm->time.tm_hour = bcd2bin(alarm_data[1]); |
| 133 | alm->time.tm_mday = bcd2bin(alarm_data[2]); | 134 | alm->time.tm_mday = bcd2bin(alarm_data[2]); |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index ef86229428fc..c8c757466783 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
| @@ -341,12 +341,6 @@ static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 341 | t->time.tm_sec = 0; | 341 | t->time.tm_sec = 0; |
| 342 | t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); | 342 | t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); |
| 343 | t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); | 343 | t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); |
| 344 | t->time.tm_mday = -1; | ||
| 345 | t->time.tm_mon = -1; | ||
| 346 | t->time.tm_year = -1; | ||
| 347 | t->time.tm_wday = -1; | ||
| 348 | t->time.tm_yday = -1; | ||
| 349 | t->time.tm_isdst = -1; | ||
| 350 | 344 | ||
| 351 | /* ... and status */ | 345 | /* ... and status */ |
| 352 | t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); | 346 | t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); |
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index f623038e586e..9a2f6a95d5a7 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c | |||
| @@ -13,12 +13,15 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/bcd.h> | 14 | #include <linux/bcd.h> |
| 15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
| 16 | #include <linux/log2.h> | ||
| 16 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
| 17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/rtc.h> | 21 | #include <linux/rtc.h> |
| 21 | 22 | ||
| 23 | #define RV8803_I2C_TRY_COUNT 4 | ||
| 24 | |||
| 22 | #define RV8803_SEC 0x00 | 25 | #define RV8803_SEC 0x00 |
| 23 | #define RV8803_MIN 0x01 | 26 | #define RV8803_MIN 0x01 |
| 24 | #define RV8803_HOUR 0x02 | 27 | #define RV8803_HOUR 0x02 |
| @@ -56,19 +59,85 @@ struct rv8803_data { | |||
| 56 | u8 ctrl; | 59 | u8 ctrl; |
| 57 | }; | 60 | }; |
| 58 | 61 | ||
| 62 | static int rv8803_read_reg(const struct i2c_client *client, u8 reg) | ||
| 63 | { | ||
| 64 | int try = RV8803_I2C_TRY_COUNT; | ||
| 65 | s32 ret; | ||
| 66 | |||
| 67 | /* | ||
| 68 | * There is a 61µs window during which the RTC does not acknowledge I2C | ||
| 69 | * transfers. In that case, ensure that there are multiple attempts. | ||
| 70 | */ | ||
| 71 | do | ||
| 72 | ret = i2c_smbus_read_byte_data(client, reg); | ||
| 73 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
| 74 | if (ret < 0) | ||
| 75 | dev_err(&client->dev, "Unable to read register 0x%02x\n", reg); | ||
| 76 | |||
| 77 | return ret; | ||
| 78 | } | ||
| 79 | |||
| 80 | static int rv8803_read_regs(const struct i2c_client *client, | ||
| 81 | u8 reg, u8 count, u8 *values) | ||
| 82 | { | ||
| 83 | int try = RV8803_I2C_TRY_COUNT; | ||
| 84 | s32 ret; | ||
| 85 | |||
| 86 | do | ||
| 87 | ret = i2c_smbus_read_i2c_block_data(client, reg, count, values); | ||
| 88 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
| 89 | if (ret != count) { | ||
| 90 | dev_err(&client->dev, | ||
| 91 | "Unable to read registers 0x%02x..0x%02x\n", | ||
| 92 | reg, reg + count - 1); | ||
| 93 | return ret < 0 ? ret : -EIO; | ||
| 94 | } | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int rv8803_write_reg(const struct i2c_client *client, u8 reg, u8 value) | ||
| 100 | { | ||
| 101 | int try = RV8803_I2C_TRY_COUNT; | ||
| 102 | s32 ret; | ||
| 103 | |||
| 104 | do | ||
| 105 | ret = i2c_smbus_write_byte_data(client, reg, value); | ||
| 106 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
| 107 | if (ret) | ||
| 108 | dev_err(&client->dev, "Unable to write register 0x%02x\n", reg); | ||
| 109 | |||
| 110 | return ret; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int rv8803_write_regs(const struct i2c_client *client, | ||
| 114 | u8 reg, u8 count, const u8 *values) | ||
| 115 | { | ||
| 116 | int try = RV8803_I2C_TRY_COUNT; | ||
| 117 | s32 ret; | ||
| 118 | |||
| 119 | do | ||
| 120 | ret = i2c_smbus_write_i2c_block_data(client, reg, count, | ||
| 121 | values); | ||
| 122 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
| 123 | if (ret) | ||
| 124 | dev_err(&client->dev, | ||
| 125 | "Unable to write registers 0x%02x..0x%02x\n", | ||
| 126 | reg, reg + count - 1); | ||
| 127 | |||
| 128 | return ret; | ||
| 129 | } | ||
| 130 | |||
| 59 | static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) | 131 | static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) |
| 60 | { | 132 | { |
| 61 | struct i2c_client *client = dev_id; | 133 | struct i2c_client *client = dev_id; |
| 62 | struct rv8803_data *rv8803 = i2c_get_clientdata(client); | 134 | struct rv8803_data *rv8803 = i2c_get_clientdata(client); |
| 63 | unsigned long events = 0; | 135 | unsigned long events = 0; |
| 64 | int flags, try = 0; | 136 | int flags; |
| 65 | 137 | ||
| 66 | mutex_lock(&rv8803->flags_lock); | 138 | mutex_lock(&rv8803->flags_lock); |
| 67 | 139 | ||
| 68 | do { | 140 | flags = rv8803_read_reg(client, RV8803_FLAG); |
| 69 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | ||
| 70 | try++; | ||
| 71 | } while ((flags == -ENXIO) && (try < 3)); | ||
| 72 | if (flags <= 0) { | 141 | if (flags <= 0) { |
| 73 | mutex_unlock(&rv8803->flags_lock); | 142 | mutex_unlock(&rv8803->flags_lock); |
| 74 | return IRQ_NONE; | 143 | return IRQ_NONE; |
| @@ -100,9 +169,8 @@ static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) | |||
| 100 | 169 | ||
| 101 | if (events) { | 170 | if (events) { |
| 102 | rtc_update_irq(rv8803->rtc, 1, events); | 171 | rtc_update_irq(rv8803->rtc, 1, events); |
| 103 | i2c_smbus_write_byte_data(client, RV8803_FLAG, flags); | 172 | rv8803_write_reg(client, RV8803_FLAG, flags); |
| 104 | i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL, | 173 | rv8803_write_reg(rv8803->client, RV8803_CTRL, rv8803->ctrl); |
| 105 | rv8803->ctrl); | ||
| 106 | } | 174 | } |
| 107 | 175 | ||
| 108 | mutex_unlock(&rv8803->flags_lock); | 176 | mutex_unlock(&rv8803->flags_lock); |
| @@ -118,7 +186,7 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) | |||
| 118 | u8 *date = date1; | 186 | u8 *date = date1; |
| 119 | int ret, flags; | 187 | int ret, flags; |
| 120 | 188 | ||
| 121 | flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG); | 189 | flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); |
| 122 | if (flags < 0) | 190 | if (flags < 0) |
| 123 | return flags; | 191 | return flags; |
| 124 | 192 | ||
| @@ -127,16 +195,14 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) | |||
| 127 | return -EINVAL; | 195 | return -EINVAL; |
| 128 | } | 196 | } |
| 129 | 197 | ||
| 130 | ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC, | 198 | ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date); |
| 131 | 7, date); | 199 | if (ret) |
| 132 | if (ret != 7) | 200 | return ret; |
| 133 | return ret < 0 ? ret : -EIO; | ||
| 134 | 201 | ||
| 135 | if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) { | 202 | if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) { |
| 136 | ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC, | 203 | ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date2); |
| 137 | 7, date2); | 204 | if (ret) |
| 138 | if (ret != 7) | 205 | return ret; |
| 139 | return ret < 0 ? ret : -EIO; | ||
| 140 | 206 | ||
| 141 | if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59)) | 207 | if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59)) |
| 142 | date = date2; | 208 | date = date2; |
| @@ -145,23 +211,33 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) | |||
| 145 | tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f); | 211 | tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f); |
| 146 | tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f); | 212 | tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f); |
| 147 | tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f); | 213 | tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f); |
| 148 | tm->tm_wday = ffs(date[RV8803_WEEK] & 0x7f); | 214 | tm->tm_wday = ilog2(date[RV8803_WEEK] & 0x7f); |
| 149 | tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f); | 215 | tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f); |
| 150 | tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1; | 216 | tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1; |
| 151 | tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100; | 217 | tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100; |
| 152 | 218 | ||
| 153 | return rtc_valid_tm(tm); | 219 | return 0; |
| 154 | } | 220 | } |
| 155 | 221 | ||
| 156 | static int rv8803_set_time(struct device *dev, struct rtc_time *tm) | 222 | static int rv8803_set_time(struct device *dev, struct rtc_time *tm) |
| 157 | { | 223 | { |
| 158 | struct rv8803_data *rv8803 = dev_get_drvdata(dev); | 224 | struct rv8803_data *rv8803 = dev_get_drvdata(dev); |
| 159 | u8 date[7]; | 225 | u8 date[7]; |
| 160 | int flags, ret; | 226 | int ctrl, flags, ret; |
| 161 | 227 | ||
| 162 | if ((tm->tm_year < 100) || (tm->tm_year > 199)) | 228 | if ((tm->tm_year < 100) || (tm->tm_year > 199)) |
| 163 | return -EINVAL; | 229 | return -EINVAL; |
| 164 | 230 | ||
| 231 | ctrl = rv8803_read_reg(rv8803->client, RV8803_CTRL); | ||
| 232 | if (ctrl < 0) | ||
| 233 | return ctrl; | ||
| 234 | |||
| 235 | /* Stop the clock */ | ||
| 236 | ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, | ||
| 237 | ctrl | RV8803_CTRL_RESET); | ||
| 238 | if (ret) | ||
| 239 | return ret; | ||
| 240 | |||
| 165 | date[RV8803_SEC] = bin2bcd(tm->tm_sec); | 241 | date[RV8803_SEC] = bin2bcd(tm->tm_sec); |
| 166 | date[RV8803_MIN] = bin2bcd(tm->tm_min); | 242 | date[RV8803_MIN] = bin2bcd(tm->tm_min); |
| 167 | date[RV8803_HOUR] = bin2bcd(tm->tm_hour); | 243 | date[RV8803_HOUR] = bin2bcd(tm->tm_hour); |
| @@ -170,21 +246,26 @@ static int rv8803_set_time(struct device *dev, struct rtc_time *tm) | |||
| 170 | date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1); | 246 | date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1); |
| 171 | date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100); | 247 | date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100); |
| 172 | 248 | ||
| 173 | ret = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_SEC, | 249 | ret = rv8803_write_regs(rv8803->client, RV8803_SEC, 7, date); |
| 174 | 7, date); | 250 | if (ret) |
| 175 | if (ret < 0) | 251 | return ret; |
| 252 | |||
| 253 | /* Restart the clock */ | ||
| 254 | ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, | ||
| 255 | ctrl & ~RV8803_CTRL_RESET); | ||
| 256 | if (ret) | ||
| 176 | return ret; | 257 | return ret; |
| 177 | 258 | ||
| 178 | mutex_lock(&rv8803->flags_lock); | 259 | mutex_lock(&rv8803->flags_lock); |
| 179 | 260 | ||
| 180 | flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG); | 261 | flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); |
| 181 | if (flags < 0) { | 262 | if (flags < 0) { |
| 182 | mutex_unlock(&rv8803->flags_lock); | 263 | mutex_unlock(&rv8803->flags_lock); |
| 183 | return flags; | 264 | return flags; |
| 184 | } | 265 | } |
| 185 | 266 | ||
| 186 | ret = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG, | 267 | ret = rv8803_write_reg(rv8803->client, RV8803_FLAG, |
| 187 | flags & ~RV8803_FLAG_V2F); | 268 | flags & ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F)); |
| 188 | 269 | ||
| 189 | mutex_unlock(&rv8803->flags_lock); | 270 | mutex_unlock(&rv8803->flags_lock); |
| 190 | 271 | ||
| @@ -198,22 +279,18 @@ static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 198 | u8 alarmvals[3]; | 279 | u8 alarmvals[3]; |
| 199 | int flags, ret; | 280 | int flags, ret; |
| 200 | 281 | ||
| 201 | ret = i2c_smbus_read_i2c_block_data(client, RV8803_ALARM_MIN, | 282 | ret = rv8803_read_regs(client, RV8803_ALARM_MIN, 3, alarmvals); |
| 202 | 3, alarmvals); | 283 | if (ret) |
| 203 | if (ret != 3) | 284 | return ret; |
| 204 | return ret < 0 ? ret : -EIO; | ||
| 205 | 285 | ||
| 206 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 286 | flags = rv8803_read_reg(client, RV8803_FLAG); |
| 207 | if (flags < 0) | 287 | if (flags < 0) |
| 208 | return flags; | 288 | return flags; |
| 209 | 289 | ||
| 210 | alrm->time.tm_sec = 0; | 290 | alrm->time.tm_sec = 0; |
| 211 | alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); | 291 | alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); |
| 212 | alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); | 292 | alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); |
| 213 | alrm->time.tm_wday = -1; | ||
| 214 | alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); | 293 | alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); |
| 215 | alrm->time.tm_mon = -1; | ||
| 216 | alrm->time.tm_year = -1; | ||
| 217 | 294 | ||
| 218 | alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE); | 295 | alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE); |
| 219 | alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled; | 296 | alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled; |
| @@ -239,10 +316,10 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 239 | 316 | ||
| 240 | mutex_lock(&rv8803->flags_lock); | 317 | mutex_lock(&rv8803->flags_lock); |
| 241 | 318 | ||
| 242 | ret = i2c_smbus_read_i2c_block_data(client, RV8803_FLAG, 2, ctrl); | 319 | ret = rv8803_read_regs(client, RV8803_FLAG, 2, ctrl); |
| 243 | if (ret != 2) { | 320 | if (ret) { |
| 244 | mutex_unlock(&rv8803->flags_lock); | 321 | mutex_unlock(&rv8803->flags_lock); |
| 245 | return ret < 0 ? ret : -EIO; | 322 | return ret; |
| 246 | } | 323 | } |
| 247 | 324 | ||
| 248 | alarmvals[0] = bin2bcd(alrm->time.tm_min); | 325 | alarmvals[0] = bin2bcd(alrm->time.tm_min); |
| @@ -251,8 +328,8 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 251 | 328 | ||
| 252 | if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) { | 329 | if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) { |
| 253 | rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE); | 330 | rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE); |
| 254 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL, | 331 | err = rv8803_write_reg(rv8803->client, RV8803_CTRL, |
| 255 | rv8803->ctrl); | 332 | rv8803->ctrl); |
| 256 | if (err) { | 333 | if (err) { |
| 257 | mutex_unlock(&rv8803->flags_lock); | 334 | mutex_unlock(&rv8803->flags_lock); |
| 258 | return err; | 335 | return err; |
| @@ -260,13 +337,12 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 260 | } | 337 | } |
| 261 | 338 | ||
| 262 | ctrl[1] &= ~RV8803_FLAG_AF; | 339 | ctrl[1] &= ~RV8803_FLAG_AF; |
| 263 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG, ctrl[1]); | 340 | err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[1]); |
| 264 | mutex_unlock(&rv8803->flags_lock); | 341 | mutex_unlock(&rv8803->flags_lock); |
| 265 | if (err) | 342 | if (err) |
| 266 | return err; | 343 | return err; |
| 267 | 344 | ||
| 268 | err = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_ALARM_MIN, | 345 | err = rv8803_write_regs(rv8803->client, RV8803_ALARM_MIN, 3, alarmvals); |
| 269 | 3, alarmvals); | ||
| 270 | if (err) | 346 | if (err) |
| 271 | return err; | 347 | return err; |
| 272 | 348 | ||
| @@ -276,8 +352,8 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 276 | if (rv8803->rtc->aie_timer.enabled) | 352 | if (rv8803->rtc->aie_timer.enabled) |
| 277 | rv8803->ctrl |= RV8803_CTRL_AIE; | 353 | rv8803->ctrl |= RV8803_CTRL_AIE; |
| 278 | 354 | ||
| 279 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL, | 355 | err = rv8803_write_reg(rv8803->client, RV8803_CTRL, |
| 280 | rv8803->ctrl); | 356 | rv8803->ctrl); |
| 281 | if (err) | 357 | if (err) |
| 282 | return err; | 358 | return err; |
| 283 | } | 359 | } |
| @@ -306,21 +382,20 @@ static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
| 306 | } | 382 | } |
| 307 | 383 | ||
| 308 | mutex_lock(&rv8803->flags_lock); | 384 | mutex_lock(&rv8803->flags_lock); |
| 309 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 385 | flags = rv8803_read_reg(client, RV8803_FLAG); |
| 310 | if (flags < 0) { | 386 | if (flags < 0) { |
| 311 | mutex_unlock(&rv8803->flags_lock); | 387 | mutex_unlock(&rv8803->flags_lock); |
| 312 | return flags; | 388 | return flags; |
| 313 | } | 389 | } |
| 314 | flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF); | 390 | flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF); |
| 315 | err = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags); | 391 | err = rv8803_write_reg(client, RV8803_FLAG, flags); |
| 316 | mutex_unlock(&rv8803->flags_lock); | 392 | mutex_unlock(&rv8803->flags_lock); |
| 317 | if (err) | 393 | if (err) |
| 318 | return err; | 394 | return err; |
| 319 | 395 | ||
| 320 | if (ctrl != rv8803->ctrl) { | 396 | if (ctrl != rv8803->ctrl) { |
| 321 | rv8803->ctrl = ctrl; | 397 | rv8803->ctrl = ctrl; |
| 322 | err = i2c_smbus_write_byte_data(client, RV8803_CTRL, | 398 | err = rv8803_write_reg(client, RV8803_CTRL, rv8803->ctrl); |
| 323 | rv8803->ctrl); | ||
| 324 | if (err) | 399 | if (err) |
| 325 | return err; | 400 | return err; |
| 326 | } | 401 | } |
| @@ -336,7 +411,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
| 336 | 411 | ||
| 337 | switch (cmd) { | 412 | switch (cmd) { |
| 338 | case RTC_VL_READ: | 413 | case RTC_VL_READ: |
| 339 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 414 | flags = rv8803_read_reg(client, RV8803_FLAG); |
| 340 | if (flags < 0) | 415 | if (flags < 0) |
| 341 | return flags; | 416 | return flags; |
| 342 | 417 | ||
| @@ -355,16 +430,16 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
| 355 | 430 | ||
| 356 | case RTC_VL_CLR: | 431 | case RTC_VL_CLR: |
| 357 | mutex_lock(&rv8803->flags_lock); | 432 | mutex_lock(&rv8803->flags_lock); |
| 358 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 433 | flags = rv8803_read_reg(client, RV8803_FLAG); |
| 359 | if (flags < 0) { | 434 | if (flags < 0) { |
| 360 | mutex_unlock(&rv8803->flags_lock); | 435 | mutex_unlock(&rv8803->flags_lock); |
| 361 | return flags; | 436 | return flags; |
| 362 | } | 437 | } |
| 363 | 438 | ||
| 364 | flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F); | 439 | flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F); |
| 365 | ret = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags); | 440 | ret = rv8803_write_reg(client, RV8803_FLAG, flags); |
| 366 | mutex_unlock(&rv8803->flags_lock); | 441 | mutex_unlock(&rv8803->flags_lock); |
| 367 | if (ret < 0) | 442 | if (ret) |
| 368 | return ret; | 443 | return ret; |
| 369 | 444 | ||
| 370 | return 0; | 445 | return 0; |
| @@ -382,8 +457,8 @@ static ssize_t rv8803_nvram_write(struct file *filp, struct kobject *kobj, | |||
| 382 | struct i2c_client *client = to_i2c_client(dev); | 457 | struct i2c_client *client = to_i2c_client(dev); |
| 383 | int ret; | 458 | int ret; |
| 384 | 459 | ||
| 385 | ret = i2c_smbus_write_byte_data(client, RV8803_RAM, buf[0]); | 460 | ret = rv8803_write_reg(client, RV8803_RAM, buf[0]); |
| 386 | if (ret < 0) | 461 | if (ret) |
| 387 | return ret; | 462 | return ret; |
| 388 | 463 | ||
| 389 | return 1; | 464 | return 1; |
| @@ -397,7 +472,7 @@ static ssize_t rv8803_nvram_read(struct file *filp, struct kobject *kobj, | |||
| 397 | struct i2c_client *client = to_i2c_client(dev); | 472 | struct i2c_client *client = to_i2c_client(dev); |
| 398 | int ret; | 473 | int ret; |
| 399 | 474 | ||
| 400 | ret = i2c_smbus_read_byte_data(client, RV8803_RAM); | 475 | ret = rv8803_read_reg(client, RV8803_RAM); |
| 401 | if (ret < 0) | 476 | if (ret < 0) |
| 402 | return ret; | 477 | return ret; |
| 403 | 478 | ||
| @@ -427,7 +502,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
| 427 | { | 502 | { |
| 428 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 503 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 429 | struct rv8803_data *rv8803; | 504 | struct rv8803_data *rv8803; |
| 430 | int err, flags, try = 0; | 505 | int err, flags; |
| 431 | 506 | ||
| 432 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 507 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
| 433 | I2C_FUNC_SMBUS_I2C_BLOCK)) { | 508 | I2C_FUNC_SMBUS_I2C_BLOCK)) { |
| @@ -444,16 +519,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
| 444 | rv8803->client = client; | 519 | rv8803->client = client; |
| 445 | i2c_set_clientdata(client, rv8803); | 520 | i2c_set_clientdata(client, rv8803); |
| 446 | 521 | ||
| 447 | /* | 522 | flags = rv8803_read_reg(client, RV8803_FLAG); |
| 448 | * There is a 60µs window where the RTC may not reply on the i2c bus in | ||
| 449 | * that case, the transfer is not ACKed. In that case, ensure there are | ||
| 450 | * multiple attempts. | ||
| 451 | */ | ||
| 452 | do { | ||
| 453 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | ||
| 454 | try++; | ||
| 455 | } while ((flags == -ENXIO) && (try < 3)); | ||
| 456 | |||
| 457 | if (flags < 0) | 523 | if (flags < 0) |
| 458 | return flags; | 524 | return flags; |
| 459 | 525 | ||
| @@ -488,12 +554,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
| 488 | return PTR_ERR(rv8803->rtc); | 554 | return PTR_ERR(rv8803->rtc); |
| 489 | } | 555 | } |
| 490 | 556 | ||
| 491 | try = 0; | 557 | err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); |
| 492 | do { | ||
| 493 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT, | ||
| 494 | RV8803_EXT_WADA); | ||
| 495 | try++; | ||
| 496 | } while ((err == -ENXIO) && (try < 3)); | ||
| 497 | if (err) | 558 | if (err) |
| 498 | return err; | 559 | return err; |
| 499 | 560 | ||
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index 772d221ec2d9..7163b91bb773 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c | |||
| @@ -272,15 +272,9 @@ static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 272 | t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); | 272 | t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); |
| 273 | t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); | 273 | t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); |
| 274 | 274 | ||
| 275 | if (alarmvals[2] & RX8010_ALARM_AE) | 275 | if (!(alarmvals[2] & RX8010_ALARM_AE)) |
| 276 | t->time.tm_mday = -1; | ||
| 277 | else | ||
| 278 | t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f); | 276 | t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f); |
| 279 | 277 | ||
| 280 | t->time.tm_wday = -1; | ||
| 281 | t->time.tm_mon = -1; | ||
| 282 | t->time.tm_year = -1; | ||
| 283 | |||
| 284 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); | 278 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); |
| 285 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; | 279 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; |
| 286 | 280 | ||
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 9f105efbc546..2b85cc7a24e7 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
| @@ -319,11 +319,6 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
| 319 | t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 | 319 | t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 |
| 320 | + (ald[1] & 0x20 ? 12 : 0); | 320 | + (ald[1] & 0x20 ? 12 : 0); |
| 321 | 321 | ||
| 322 | t->time.tm_wday = -1; | ||
| 323 | t->time.tm_mday = -1; | ||
| 324 | t->time.tm_mon = -1; | ||
| 325 | t->time.tm_year = -1; | ||
| 326 | |||
| 327 | dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n", | 322 | dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n", |
| 328 | __func__, | 323 | __func__, |
| 329 | t->time.tm_sec, t->time.tm_min, t->time.tm_hour, | 324 | t->time.tm_sec, t->time.tm_min, t->time.tm_hour, |
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index f40afdd0e5f5..5dab4665ca3b 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/bitrev.h> | 15 | #include <linux/bitrev.h> |
| 16 | #include <linux/bcd.h> | 16 | #include <linux/bcd.h> |
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | #include <linux/delay.h> | ||
| 18 | 19 | ||
| 19 | #define S35390A_CMD_STATUS1 0 | 20 | #define S35390A_CMD_STATUS1 0 |
| 20 | #define S35390A_CMD_STATUS2 1 | 21 | #define S35390A_CMD_STATUS2 1 |
| @@ -34,10 +35,14 @@ | |||
| 34 | #define S35390A_ALRM_BYTE_HOURS 1 | 35 | #define S35390A_ALRM_BYTE_HOURS 1 |
| 35 | #define S35390A_ALRM_BYTE_MINS 2 | 36 | #define S35390A_ALRM_BYTE_MINS 2 |
| 36 | 37 | ||
| 38 | /* flags for STATUS1 */ | ||
| 37 | #define S35390A_FLAG_POC 0x01 | 39 | #define S35390A_FLAG_POC 0x01 |
| 38 | #define S35390A_FLAG_BLD 0x02 | 40 | #define S35390A_FLAG_BLD 0x02 |
| 41 | #define S35390A_FLAG_INT2 0x04 | ||
| 39 | #define S35390A_FLAG_24H 0x40 | 42 | #define S35390A_FLAG_24H 0x40 |
| 40 | #define S35390A_FLAG_RESET 0x80 | 43 | #define S35390A_FLAG_RESET 0x80 |
| 44 | |||
| 45 | /* flag for STATUS2 */ | ||
| 41 | #define S35390A_FLAG_TEST 0x01 | 46 | #define S35390A_FLAG_TEST 0x01 |
| 42 | 47 | ||
| 43 | #define S35390A_INT2_MODE_MASK 0xF0 | 48 | #define S35390A_INT2_MODE_MASK 0xF0 |
| @@ -94,19 +99,63 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) | |||
| 94 | return 0; | 99 | return 0; |
| 95 | } | 100 | } |
| 96 | 101 | ||
| 97 | static int s35390a_reset(struct s35390a *s35390a) | 102 | /* |
| 103 | * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset. | ||
| 104 | * To keep the information if an irq is pending, pass the value read from | ||
| 105 | * STATUS1 to the caller. | ||
| 106 | */ | ||
| 107 | static int s35390a_reset(struct s35390a *s35390a, char *status1) | ||
| 98 | { | 108 | { |
| 99 | char buf[1]; | 109 | char buf; |
| 100 | 110 | int ret; | |
| 101 | if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0) | 111 | unsigned initcount = 0; |
| 102 | return -EIO; | 112 | |
| 103 | 113 | ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1); | |
| 104 | if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD))) | 114 | if (ret < 0) |
| 115 | return ret; | ||
| 116 | |||
| 117 | if (*status1 & S35390A_FLAG_POC) | ||
| 118 | /* | ||
| 119 | * Do not communicate for 0.5 seconds since the power-on | ||
| 120 | * detection circuit is in operation. | ||
| 121 | */ | ||
| 122 | msleep(500); | ||
| 123 | else if (!(*status1 & S35390A_FLAG_BLD)) | ||
| 124 | /* | ||
| 125 | * If both POC and BLD are unset everything is fine. | ||
| 126 | */ | ||
| 105 | return 0; | 127 | return 0; |
| 106 | 128 | ||
| 107 | buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H); | 129 | /* |
| 108 | buf[0] &= 0xf0; | 130 | * At least one of POC and BLD are set, so reinitialise chip. Keeping |
| 109 | return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); | 131 | * this information in the hardware to know later that the time isn't |
| 132 | * valid is unfortunately not possible because POC and BLD are cleared | ||
| 133 | * on read. So the reset is best done now. | ||
| 134 | * | ||
| 135 | * The 24H bit is kept over reset, so set it already here. | ||
| 136 | */ | ||
| 137 | initialize: | ||
| 138 | *status1 = S35390A_FLAG_24H; | ||
| 139 | buf = S35390A_FLAG_RESET | S35390A_FLAG_24H; | ||
| 140 | ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); | ||
| 141 | |||
| 142 | if (ret < 0) | ||
| 143 | return ret; | ||
| 144 | |||
| 145 | ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); | ||
| 146 | if (ret < 0) | ||
| 147 | return ret; | ||
| 148 | |||
| 149 | if (buf & (S35390A_FLAG_POC | S35390A_FLAG_BLD)) { | ||
| 150 | /* Try up to five times to reset the chip */ | ||
| 151 | if (initcount < 5) { | ||
| 152 | ++initcount; | ||
| 153 | goto initialize; | ||
| 154 | } else | ||
| 155 | return -EIO; | ||
| 156 | } | ||
| 157 | |||
| 158 | return 1; | ||
| 110 | } | 159 | } |
| 111 | 160 | ||
| 112 | static int s35390a_disable_test_mode(struct s35390a *s35390a) | 161 | static int s35390a_disable_test_mode(struct s35390a *s35390a) |
| @@ -217,12 +266,12 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | |||
| 217 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, | 266 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, |
| 218 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); | 267 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); |
| 219 | 268 | ||
| 220 | /* disable interrupt */ | 269 | /* disable interrupt (which deasserts the irq line) */ |
| 221 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | 270 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); |
| 222 | if (err < 0) | 271 | if (err < 0) |
| 223 | return err; | 272 | return err; |
| 224 | 273 | ||
| 225 | /* clear pending interrupt, if any */ | 274 | /* clear pending interrupt (in STATUS1 only), if any */ |
| 226 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); | 275 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); |
| 227 | if (err < 0) | 276 | if (err < 0) |
| 228 | return err; | 277 | return err; |
| @@ -242,6 +291,8 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | |||
| 242 | 291 | ||
| 243 | if (alm->time.tm_wday != -1) | 292 | if (alm->time.tm_wday != -1) |
| 244 | buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; | 293 | buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; |
| 294 | else | ||
| 295 | buf[S35390A_ALRM_BYTE_WDAY] = 0; | ||
| 245 | 296 | ||
| 246 | buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, | 297 | buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, |
| 247 | alm->time.tm_hour) | 0x80; | 298 | alm->time.tm_hour) | 0x80; |
| @@ -269,23 +320,43 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | |||
| 269 | if (err < 0) | 320 | if (err < 0) |
| 270 | return err; | 321 | return err; |
| 271 | 322 | ||
| 272 | if (bitrev8(sts) != S35390A_INT2_MODE_ALARM) | 323 | if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { |
| 273 | return -EINVAL; | 324 | /* |
| 325 | * When the alarm isn't enabled, the register to configure | ||
| 326 | * the alarm time isn't accessible. | ||
| 327 | */ | ||
| 328 | alm->enabled = 0; | ||
| 329 | return 0; | ||
| 330 | } else { | ||
| 331 | alm->enabled = 1; | ||
| 332 | } | ||
| 274 | 333 | ||
| 275 | err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); | 334 | err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); |
| 276 | if (err < 0) | 335 | if (err < 0) |
| 277 | return err; | 336 | return err; |
| 278 | 337 | ||
| 279 | /* This chip returns the bits of each byte in reverse order */ | 338 | /* This chip returns the bits of each byte in reverse order */ |
| 280 | for (i = 0; i < 3; ++i) { | 339 | for (i = 0; i < 3; ++i) |
| 281 | buf[i] = bitrev8(buf[i]); | 340 | buf[i] = bitrev8(buf[i]); |
| 282 | buf[i] &= ~0x80; | ||
| 283 | } | ||
| 284 | 341 | ||
| 285 | alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]); | 342 | /* |
| 286 | alm->time.tm_hour = s35390a_reg2hr(s35390a, | 343 | * B0 of the three matching registers is an enable flag. Iff it is set |
| 287 | buf[S35390A_ALRM_BYTE_HOURS]); | 344 | * the configured value is used for matching. |
| 288 | alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]); | 345 | */ |
| 346 | if (buf[S35390A_ALRM_BYTE_WDAY] & 0x80) | ||
| 347 | alm->time.tm_wday = | ||
| 348 | bcd2bin(buf[S35390A_ALRM_BYTE_WDAY] & ~0x80); | ||
| 349 | |||
| 350 | if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80) | ||
| 351 | alm->time.tm_hour = | ||
| 352 | s35390a_reg2hr(s35390a, | ||
| 353 | buf[S35390A_ALRM_BYTE_HOURS] & ~0x80); | ||
| 354 | |||
| 355 | if (buf[S35390A_ALRM_BYTE_MINS] & 0x80) | ||
| 356 | alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80); | ||
| 357 | |||
| 358 | /* alarm triggers always at s=0 */ | ||
| 359 | alm->time.tm_sec = 0; | ||
| 289 | 360 | ||
| 290 | dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", | 361 | dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", |
| 291 | __func__, alm->time.tm_min, alm->time.tm_hour, | 362 | __func__, alm->time.tm_min, alm->time.tm_hour, |
| @@ -327,11 +398,11 @@ static struct i2c_driver s35390a_driver; | |||
| 327 | static int s35390a_probe(struct i2c_client *client, | 398 | static int s35390a_probe(struct i2c_client *client, |
| 328 | const struct i2c_device_id *id) | 399 | const struct i2c_device_id *id) |
| 329 | { | 400 | { |
| 330 | int err; | 401 | int err, err_reset; |
| 331 | unsigned int i; | 402 | unsigned int i; |
| 332 | struct s35390a *s35390a; | 403 | struct s35390a *s35390a; |
| 333 | struct rtc_time tm; | 404 | struct rtc_time tm; |
| 334 | char buf[1]; | 405 | char buf, status1; |
| 335 | 406 | ||
| 336 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | 407 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { |
| 337 | err = -ENODEV; | 408 | err = -ENODEV; |
| @@ -360,29 +431,35 @@ static int s35390a_probe(struct i2c_client *client, | |||
| 360 | } | 431 | } |
| 361 | } | 432 | } |
| 362 | 433 | ||
| 363 | err = s35390a_reset(s35390a); | 434 | err_reset = s35390a_reset(s35390a, &status1); |
| 364 | if (err < 0) { | 435 | if (err_reset < 0) { |
| 436 | err = err_reset; | ||
| 365 | dev_err(&client->dev, "error resetting chip\n"); | 437 | dev_err(&client->dev, "error resetting chip\n"); |
| 366 | goto exit_dummy; | 438 | goto exit_dummy; |
| 367 | } | 439 | } |
| 368 | 440 | ||
| 369 | err = s35390a_disable_test_mode(s35390a); | 441 | if (status1 & S35390A_FLAG_24H) |
| 370 | if (err < 0) { | ||
| 371 | dev_err(&client->dev, "error disabling test mode\n"); | ||
| 372 | goto exit_dummy; | ||
| 373 | } | ||
| 374 | |||
| 375 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); | ||
| 376 | if (err < 0) { | ||
| 377 | dev_err(&client->dev, "error checking 12/24 hour mode\n"); | ||
| 378 | goto exit_dummy; | ||
| 379 | } | ||
| 380 | if (buf[0] & S35390A_FLAG_24H) | ||
| 381 | s35390a->twentyfourhour = 1; | 442 | s35390a->twentyfourhour = 1; |
| 382 | else | 443 | else |
| 383 | s35390a->twentyfourhour = 0; | 444 | s35390a->twentyfourhour = 0; |
| 384 | 445 | ||
| 385 | if (s35390a_get_datetime(client, &tm) < 0) | 446 | if (status1 & S35390A_FLAG_INT2) { |
| 447 | /* disable alarm (and maybe test mode) */ | ||
| 448 | buf = 0; | ||
| 449 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1); | ||
| 450 | if (err < 0) { | ||
| 451 | dev_err(&client->dev, "error disabling alarm"); | ||
| 452 | goto exit_dummy; | ||
| 453 | } | ||
| 454 | } else { | ||
| 455 | err = s35390a_disable_test_mode(s35390a); | ||
| 456 | if (err < 0) { | ||
| 457 | dev_err(&client->dev, "error disabling test mode\n"); | ||
| 458 | goto exit_dummy; | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0) | ||
| 386 | dev_warn(&client->dev, "clock needs to be set\n"); | 463 | dev_warn(&client->dev, "clock needs to be set\n"); |
| 387 | 464 | ||
| 388 | device_set_wakeup_capable(&client->dev, 1); | 465 | device_set_wakeup_capable(&client->dev, 1); |
| @@ -395,6 +472,10 @@ static int s35390a_probe(struct i2c_client *client, | |||
| 395 | err = PTR_ERR(s35390a->rtc); | 472 | err = PTR_ERR(s35390a->rtc); |
| 396 | goto exit_dummy; | 473 | goto exit_dummy; |
| 397 | } | 474 | } |
| 475 | |||
| 476 | if (status1 & S35390A_FLAG_INT2) | ||
| 477 | rtc_update_irq(s35390a->rtc, 1, RTC_AF); | ||
| 478 | |||
| 398 | return 0; | 479 | return 0; |
| 399 | 480 | ||
| 400 | exit_dummy: | 481 | exit_dummy: |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index d01ad7e8078e..d44fb34df8fe 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
| @@ -149,12 +149,14 @@ static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) | |||
| 149 | if (!is_power_of_2(freq)) | 149 | if (!is_power_of_2(freq)) |
| 150 | return -EINVAL; | 150 | return -EINVAL; |
| 151 | 151 | ||
| 152 | s3c_rtc_enable_clk(info); | ||
| 152 | spin_lock_irq(&info->pie_lock); | 153 | spin_lock_irq(&info->pie_lock); |
| 153 | 154 | ||
| 154 | if (info->data->set_freq) | 155 | if (info->data->set_freq) |
| 155 | info->data->set_freq(info, freq); | 156 | info->data->set_freq(info, freq); |
| 156 | 157 | ||
| 157 | spin_unlock_irq(&info->pie_lock); | 158 | spin_unlock_irq(&info->pie_lock); |
| 159 | s3c_rtc_disable_clk(info); | ||
| 158 | 160 | ||
| 159 | return 0; | 161 | return 0; |
| 160 | } | 162 | } |
| @@ -264,35 +266,23 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 264 | /* decode the alarm enable field */ | 266 | /* decode the alarm enable field */ |
| 265 | if (alm_en & S3C2410_RTCALM_SECEN) | 267 | if (alm_en & S3C2410_RTCALM_SECEN) |
| 266 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); | 268 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
| 267 | else | ||
| 268 | alm_tm->tm_sec = -1; | ||
| 269 | 269 | ||
| 270 | if (alm_en & S3C2410_RTCALM_MINEN) | 270 | if (alm_en & S3C2410_RTCALM_MINEN) |
| 271 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); | 271 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
| 272 | else | ||
| 273 | alm_tm->tm_min = -1; | ||
| 274 | 272 | ||
| 275 | if (alm_en & S3C2410_RTCALM_HOUREN) | 273 | if (alm_en & S3C2410_RTCALM_HOUREN) |
| 276 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); | 274 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
| 277 | else | ||
| 278 | alm_tm->tm_hour = -1; | ||
| 279 | 275 | ||
| 280 | if (alm_en & S3C2410_RTCALM_DAYEN) | 276 | if (alm_en & S3C2410_RTCALM_DAYEN) |
| 281 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); | 277 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); |
| 282 | else | ||
| 283 | alm_tm->tm_mday = -1; | ||
| 284 | 278 | ||
| 285 | if (alm_en & S3C2410_RTCALM_MONEN) { | 279 | if (alm_en & S3C2410_RTCALM_MONEN) { |
| 286 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); | 280 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); |
| 287 | alm_tm->tm_mon -= 1; | 281 | alm_tm->tm_mon -= 1; |
| 288 | } else { | ||
| 289 | alm_tm->tm_mon = -1; | ||
| 290 | } | 282 | } |
| 291 | 283 | ||
| 292 | if (alm_en & S3C2410_RTCALM_YEAREN) | 284 | if (alm_en & S3C2410_RTCALM_YEAREN) |
| 293 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); | 285 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); |
| 294 | else | ||
| 295 | alm_tm->tm_year = -1; | ||
| 296 | 286 | ||
| 297 | return 0; | 287 | return 0; |
| 298 | } | 288 | } |
| @@ -577,8 +567,6 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
| 577 | 567 | ||
| 578 | s3c_rtc_setfreq(info, 1); | 568 | s3c_rtc_setfreq(info, 1); |
| 579 | 569 | ||
| 580 | s3c_rtc_disable_clk(info); | ||
| 581 | |||
| 582 | return 0; | 570 | return 0; |
| 583 | 571 | ||
| 584 | err_nortc: | 572 | err_nortc: |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index a45845a571e5..17b6235d67a5 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
| @@ -481,7 +481,6 @@ static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
| 481 | tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR); | 481 | tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR); |
| 482 | if (tm->tm_mon > 0) | 482 | if (tm->tm_mon > 0) |
| 483 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ | 483 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ |
| 484 | tm->tm_year = 0xffff; | ||
| 485 | 484 | ||
| 486 | wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0; | 485 | wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0; |
| 487 | 486 | ||
| @@ -500,52 +499,13 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, | |||
| 500 | writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); | 499 | writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); |
| 501 | } | 500 | } |
| 502 | 501 | ||
| 503 | static int sh_rtc_check_alarm(struct rtc_time *tm) | ||
| 504 | { | ||
| 505 | /* | ||
| 506 | * The original rtc says anything > 0xc0 is "don't care" or "match | ||
| 507 | * all" - most users use 0xff but rtc-dev uses -1 for the same thing. | ||
| 508 | * The original rtc doesn't support years - some things use -1 and | ||
| 509 | * some 0xffff. We use -1 to make out tests easier. | ||
| 510 | */ | ||
| 511 | if (tm->tm_year == 0xffff) | ||
| 512 | tm->tm_year = -1; | ||
| 513 | if (tm->tm_mon >= 0xff) | ||
| 514 | tm->tm_mon = -1; | ||
| 515 | if (tm->tm_mday >= 0xff) | ||
| 516 | tm->tm_mday = -1; | ||
| 517 | if (tm->tm_wday >= 0xff) | ||
| 518 | tm->tm_wday = -1; | ||
| 519 | if (tm->tm_hour >= 0xff) | ||
| 520 | tm->tm_hour = -1; | ||
| 521 | if (tm->tm_min >= 0xff) | ||
| 522 | tm->tm_min = -1; | ||
| 523 | if (tm->tm_sec >= 0xff) | ||
| 524 | tm->tm_sec = -1; | ||
| 525 | |||
| 526 | if (tm->tm_year > 9999 || | ||
| 527 | tm->tm_mon >= 12 || | ||
| 528 | tm->tm_mday == 0 || tm->tm_mday >= 32 || | ||
| 529 | tm->tm_wday >= 7 || | ||
| 530 | tm->tm_hour >= 24 || | ||
| 531 | tm->tm_min >= 60 || | ||
| 532 | tm->tm_sec >= 60) | ||
| 533 | return -EINVAL; | ||
| 534 | |||
| 535 | return 0; | ||
| 536 | } | ||
| 537 | |||
| 538 | static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | 502 | static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
| 539 | { | 503 | { |
| 540 | struct platform_device *pdev = to_platform_device(dev); | 504 | struct platform_device *pdev = to_platform_device(dev); |
| 541 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 505 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
| 542 | unsigned int rcr1; | 506 | unsigned int rcr1; |
| 543 | struct rtc_time *tm = &wkalrm->time; | 507 | struct rtc_time *tm = &wkalrm->time; |
| 544 | int mon, err; | 508 | int mon; |
| 545 | |||
| 546 | err = sh_rtc_check_alarm(tm); | ||
| 547 | if (unlikely(err < 0)) | ||
| 548 | return err; | ||
| 549 | 509 | ||
| 550 | spin_lock_irq(&rtc->lock); | 510 | spin_lock_irq(&rtc->lock); |
| 551 | 511 | ||
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 60232bd366ef..15ac597d54da 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c | |||
| @@ -179,12 +179,6 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
| 179 | if (sec == 0) { | 179 | if (sec == 0) { |
| 180 | /* alarm is disabled. */ | 180 | /* alarm is disabled. */ |
| 181 | alarm->enabled = 0; | 181 | alarm->enabled = 0; |
| 182 | alarm->time.tm_mon = -1; | ||
| 183 | alarm->time.tm_mday = -1; | ||
| 184 | alarm->time.tm_year = -1; | ||
| 185 | alarm->time.tm_hour = -1; | ||
| 186 | alarm->time.tm_min = -1; | ||
| 187 | alarm->time.tm_sec = -1; | ||
| 188 | } else { | 182 | } else { |
| 189 | /* alarm is enabled. */ | 183 | /* alarm is enabled. */ |
| 190 | alarm->enabled = 1; | 184 | alarm->enabled = 1; |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index 7a0436329d6c..1f3117b5a83c 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | #include <linux/rtc.h> | 25 | #include <linux/rtc.h> |
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
| 28 | #include <linux/rtc-v3020.h> | 28 | #include <linux/platform_data/rtc-v3020.h> |
| 29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 30 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
