aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2014-04-03 17:50:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-03 19:21:21 -0400
commit6a2b342228b98432a585c83d59ed6aa0620be7c4 (patch)
tree3f70e81e8757a79d192405ca5ae669510b1a3431
parent12de362108d5ec24cce1bbe520570dc8fdccca9c (diff)
rtc: mc13xxx: make rtc_read_time() more readable
Remove unnecessary locks when reading the time and make the read operation until the values of day matched between reading the seconds, it will make the mc13xxx_rtc_read_time() procedure more readable. Additionally, patch introduced a "seconds in a day" definition. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Cc: Sascha Hauer <kernel@pengutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/rtc/rtc-mc13xxx.c59
1 files changed, 23 insertions, 36 deletions
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 7b39852eb542..9b1a77eb91a9 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -23,6 +23,8 @@
23#define MC13XXX_RTCDAY 22 23#define MC13XXX_RTCDAY 22
24#define MC13XXX_RTCDAYA 23 24#define MC13XXX_RTCDAYA 23
25 25
26#define SEC_PER_DAY (24 * 60 * 60)
27
26struct mc13xxx_rtc { 28struct mc13xxx_rtc {
27 struct rtc_device *rtc; 29 struct rtc_device *rtc;
28 struct mc13xxx *mc13xxx; 30 struct mc13xxx *mc13xxx;
@@ -61,42 +63,27 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
61{ 63{
62 struct mc13xxx_rtc *priv = dev_get_drvdata(dev); 64 struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
63 unsigned int seconds, days1, days2; 65 unsigned int seconds, days1, days2;
64 unsigned long s1970;
65 int ret;
66 66
67 if (!priv->valid) 67 if (!priv->valid)
68 return -ENODATA; 68 return -ENODATA;
69 69
70 mc13xxx_lock(priv->mc13xxx); 70 do {
71 int ret;
71 72
72 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); 73 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1);
73 if (unlikely(ret)) 74 if (ret)
74 goto out; 75 return ret;
75
76 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds);
77 if (unlikely(ret))
78 goto out;
79
80 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2);
81out:
82 mc13xxx_unlock(priv->mc13xxx);
83
84 if (ret)
85 return ret;
86
87 if (days2 == days1 + 1) {
88 if (seconds >= 86400 / 2)
89 days2 = days1;
90 else
91 days1 = days2;
92 }
93 76
94 if (days1 != days2) 77 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds);
95 return -EIO; 78 if (ret)
79 return ret;
96 80
97 s1970 = days1 * 86400 + seconds; 81 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2);
82 if (ret)
83 return ret;
84 } while (days1 != days2);
98 85
99 rtc_time_to_tm(s1970, tm); 86 rtc_time_to_tm(days1 * SEC_PER_DAY + seconds, tm);
100 87
101 return rtc_valid_tm(tm); 88 return rtc_valid_tm(tm);
102} 89}
@@ -108,8 +95,8 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
108 unsigned int alarmseconds; 95 unsigned int alarmseconds;
109 int ret; 96 int ret;
110 97
111 seconds = secs % 86400; 98 seconds = secs % SEC_PER_DAY;
112 days = secs / 86400; 99 days = secs / SEC_PER_DAY;
113 100
114 mc13xxx_lock(priv->mc13xxx); 101 mc13xxx_lock(priv->mc13xxx);
115 102
@@ -121,7 +108,7 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
121 if (unlikely(ret)) 108 if (unlikely(ret))
122 goto out; 109 goto out;
123 110
124 if (alarmseconds < 86400) { 111 if (alarmseconds < SEC_PER_DAY) {
125 ret = mc13xxx_reg_write(priv->mc13xxx, 112 ret = mc13xxx_reg_write(priv->mc13xxx,
126 MC13XXX_RTCTODA, 0x1ffff); 113 MC13XXX_RTCTODA, 0x1ffff);
127 if (unlikely(ret)) 114 if (unlikely(ret))
@@ -145,7 +132,7 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
145 goto out; 132 goto out;
146 133
147 /* restore alarm */ 134 /* restore alarm */
148 if (alarmseconds < 86400) { 135 if (alarmseconds < SEC_PER_DAY) {
149 ret = mc13xxx_reg_write(priv->mc13xxx, 136 ret = mc13xxx_reg_write(priv->mc13xxx,
150 MC13XXX_RTCTODA, alarmseconds); 137 MC13XXX_RTCTODA, alarmseconds);
151 if (unlikely(ret)) 138 if (unlikely(ret))
@@ -181,7 +168,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
181 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); 168 ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds);
182 if (unlikely(ret)) 169 if (unlikely(ret))
183 goto out; 170 goto out;
184 if (seconds >= 86400) { 171 if (seconds >= SEC_PER_DAY) {
185 ret = -ENODATA; 172 ret = -ENODATA;
186 goto out; 173 goto out;
187 } 174 }
@@ -202,7 +189,7 @@ out:
202 alarm->enabled = enabled; 189 alarm->enabled = enabled;
203 alarm->pending = pending; 190 alarm->pending = pending;
204 191
205 s1970 = days * 86400 + seconds; 192 s1970 = days * SEC_PER_DAY + seconds;
206 193
207 rtc_time_to_tm(s1970, &alarm->time); 194 rtc_time_to_tm(s1970, &alarm->time);
208 dev_dbg(dev, "%s: %lu\n", __func__, s1970); 195 dev_dbg(dev, "%s: %lu\n", __func__, s1970);
@@ -240,8 +227,8 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
240 if (unlikely(ret)) 227 if (unlikely(ret))
241 goto out; 228 goto out;
242 229
243 seconds = s1970 % 86400; 230 seconds = s1970 % SEC_PER_DAY;
244 days = s1970 / 86400; 231 days = s1970 / SEC_PER_DAY;
245 232
246 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); 233 ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days);
247 if (unlikely(ret)) 234 if (unlikely(ret))