aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/sibyte/swarm
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2005-11-02 11:01:15 -0500
committerRalf Baechle <ralf@linux-mips.org>2005-11-07 13:05:38 -0500
commit53c2df2f4ebbc1d8231ca7cc13ac5381230888b1 (patch)
treea7446ec56dd877d77ef7318b4bcdc3d38555ff0a /arch/mips/sibyte/swarm
parente329331aedeca0f2a7e15bd26a829ee1619c05e0 (diff)
Use rtc_lock to protect RTC operations
Many RTC routines were not protected against each other, so there are potential races, for example, ntp-update against /dev/rtc. This patch fixes them using rtc_lock. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/sibyte/swarm')
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c7
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c6
2 files changed, 13 insertions, 0 deletions
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index 5b4fc26c1b36..c13914bdda59 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -144,6 +144,7 @@ static int m41t81_write(uint8_t addr, int b)
144int m41t81_set_time(unsigned long t) 144int m41t81_set_time(unsigned long t)
145{ 145{
146 struct rtc_time tm; 146 struct rtc_time tm;
147 unsigned long flags;
147 148
148 to_tm(t, &tm); 149 to_tm(t, &tm);
149 150
@@ -153,6 +154,7 @@ int m41t81_set_time(unsigned long t)
153 * believe we should finish writing min within a second. 154 * believe we should finish writing min within a second.
154 */ 155 */
155 156
157 spin_lock_irqsave(&rtc_lock, flags);
156 tm.tm_sec = BIN2BCD(tm.tm_sec); 158 tm.tm_sec = BIN2BCD(tm.tm_sec);
157 m41t81_write(M41T81REG_SC, tm.tm_sec); 159 m41t81_write(M41T81REG_SC, tm.tm_sec);
158 160
@@ -180,6 +182,7 @@ int m41t81_set_time(unsigned long t)
180 tm.tm_year %= 100; 182 tm.tm_year %= 100;
181 tm.tm_year = BIN2BCD(tm.tm_year); 183 tm.tm_year = BIN2BCD(tm.tm_year);
182 m41t81_write(M41T81REG_YR, tm.tm_year); 184 m41t81_write(M41T81REG_YR, tm.tm_year);
185 spin_unlock_irqrestore(&rtc_lock, flags);
183 186
184 return 0; 187 return 0;
185} 188}
@@ -187,19 +190,23 @@ int m41t81_set_time(unsigned long t)
187unsigned long m41t81_get_time(void) 190unsigned long m41t81_get_time(void)
188{ 191{
189 unsigned int year, mon, day, hour, min, sec; 192 unsigned int year, mon, day, hour, min, sec;
193 unsigned long flags;
190 194
191 /* 195 /*
192 * min is valid if two reads of sec are the same. 196 * min is valid if two reads of sec are the same.
193 */ 197 */
194 for (;;) { 198 for (;;) {
199 spin_lock_irqsave(&rtc_lock, flags);
195 sec = m41t81_read(M41T81REG_SC); 200 sec = m41t81_read(M41T81REG_SC);
196 min = m41t81_read(M41T81REG_MN); 201 min = m41t81_read(M41T81REG_MN);
197 if (sec == m41t81_read(M41T81REG_SC)) break; 202 if (sec == m41t81_read(M41T81REG_SC)) break;
203 spin_unlock_irqrestore(&rtc_lock, flags);
198 } 204 }
199 hour = m41t81_read(M41T81REG_HR) & 0x3f; 205 hour = m41t81_read(M41T81REG_HR) & 0x3f;
200 day = m41t81_read(M41T81REG_DT); 206 day = m41t81_read(M41T81REG_DT);
201 mon = m41t81_read(M41T81REG_MO); 207 mon = m41t81_read(M41T81REG_MO);
202 year = m41t81_read(M41T81REG_YR); 208 year = m41t81_read(M41T81REG_YR);
209 spin_unlock_irqrestore(&rtc_lock, flags);
203 210
204 sec = BCD2BIN(sec); 211 sec = BCD2BIN(sec);
205 min = BCD2BIN(min); 212 min = BCD2BIN(min);
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index d9ff9323f24e..f4a178836415 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -113,9 +113,11 @@ int xicor_set_time(unsigned long t)
113{ 113{
114 struct rtc_time tm; 114 struct rtc_time tm;
115 int tmp; 115 int tmp;
116 unsigned long flags;
116 117
117 to_tm(t, &tm); 118 to_tm(t, &tm);
118 119
120 spin_lock_irqsave(&rtc_lock, flags);
119 /* unlock writes to the CCR */ 121 /* unlock writes to the CCR */
120 xicor_write(X1241REG_SR, X1241REG_SR_WEL); 122 xicor_write(X1241REG_SR, X1241REG_SR_WEL);
121 xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); 123 xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
@@ -160,6 +162,7 @@ int xicor_set_time(unsigned long t)
160 xicor_write(X1241REG_HR, tmp); 162 xicor_write(X1241REG_HR, tmp);
161 163
162 xicor_write(X1241REG_SR, 0); 164 xicor_write(X1241REG_SR, 0);
165 spin_unlock_irqrestore(&rtc_lock, flags);
163 166
164 return 0; 167 return 0;
165} 168}
@@ -167,7 +170,9 @@ int xicor_set_time(unsigned long t)
167unsigned long xicor_get_time(void) 170unsigned long xicor_get_time(void)
168{ 171{
169 unsigned int year, mon, day, hour, min, sec, y2k; 172 unsigned int year, mon, day, hour, min, sec, y2k;
173 unsigned long flags;
170 174
175 spin_lock_irqsave(&rtc_lock, flags);
171 sec = xicor_read(X1241REG_SC); 176 sec = xicor_read(X1241REG_SC);
172 min = xicor_read(X1241REG_MN); 177 min = xicor_read(X1241REG_MN);
173 hour = xicor_read(X1241REG_HR); 178 hour = xicor_read(X1241REG_HR);
@@ -183,6 +188,7 @@ unsigned long xicor_get_time(void)
183 mon = xicor_read(X1241REG_MO); 188 mon = xicor_read(X1241REG_MO);
184 year = xicor_read(X1241REG_YR); 189 year = xicor_read(X1241REG_YR);
185 y2k = xicor_read(X1241REG_Y2K); 190 y2k = xicor_read(X1241REG_Y2K);
191 spin_unlock_irqrestore(&rtc_lock, flags);
186 192
187 sec = BCD2BIN(sec); 193 sec = BCD2BIN(sec);
188 min = BCD2BIN(min); 194 min = BCD2BIN(min);