| From 7dbfb315b2aaef0a115765946bf3026d074c33a7 Mon Sep 17 00:00:00 2001 |
| From: Atsushi Nemoto <anemo@mba.ocn.ne.jp> |
| Date: Tue, 21 Aug 2012 16:16:10 -0700 |
| Subject: drivers/rtc/rtc-rs5c348.c: fix hour decoding in 12-hour mode |
| |
| From: Atsushi Nemoto <anemo@mba.ocn.ne.jp> |
| |
| commit 7dbfb315b2aaef0a115765946bf3026d074c33a7 upstream. |
| |
| Correct the offset by subtracting 20 from tm_hour before taking the |
| modulo 12. |
| |
| [ "Why 20?" I hear you ask. Or at least I did. |
| |
| Here's the reason why: RS5C348_BIT_PM is 32, and is - stupidly - |
| included in the RS5C348_HOURS_MASK define. So it's really subtracting |
| out that bit to get "hour+12". But then because it does things modulo |
| 12, it needs to add the 12 in again afterwards anyway. |
| |
| This code is confused. It would be much clearer if RS5C348_HOURS_MASK |
| just didn't include the RS5C348_BIT_PM bit at all, then it wouldn't |
| need to do the silly subtract either. |
| |
| Whatever. It's all just math, the end result is the same. - Linus ] |
| |
| Reported-by: James Nute <newten82@gmail.com> |
| Tested-by: James Nute <newten82@gmail.com> |
| Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/rtc/rtc-rs5c348.c | 7 +++++-- |
| 1 file changed, 5 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/rtc/rtc-rs5c348.c |
| +++ b/drivers/rtc/rtc-rs5c348.c |
| @@ -121,9 +121,12 @@ rs5c348_rtc_read_time(struct device *dev |
| tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); |
| tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); |
| if (!pdata->rtc_24h) { |
| - tm->tm_hour %= 12; |
| - if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) |
| + if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { |
| + tm->tm_hour -= 20; |
| + tm->tm_hour %= 12; |
| tm->tm_hour += 12; |
| + } else |
| + tm->tm_hour %= 12; |
| } |
| tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); |
| tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); |