diff options
-rw-r--r-- | arch/mips/ddb5xxx/common/rtc_ds1386.c | 6 | ||||
-rw-r--r-- | arch/mips/dec/time.c | 24 | ||||
-rw-r--r-- | arch/mips/jmr3927/common/rtc_ds1742.c | 6 | ||||
-rw-r--r-- | arch/mips/lasat/ds1603.c | 9 | ||||
-rw-r--r-- | arch/mips/momentum/jaguar_atx/setup.c | 6 | ||||
-rw-r--r-- | arch/mips/momentum/ocelot_3/setup.c | 6 | ||||
-rw-r--r-- | arch/mips/momentum/ocelot_c/setup.c | 6 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/yosemite/setup.c | 6 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-time.c | 6 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/rtc_m41t81.c | 7 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/rtc_xicor1241.c | 6 | ||||
-rw-r--r-- | include/asm-mips/mc146818-time.h | 24 | ||||
-rw-r--r-- | include/asm-mips/time.h | 3 |
13 files changed, 111 insertions, 4 deletions
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c index f5b11508ff2f..995896ac0e39 100644 --- a/arch/mips/ddb5xxx/common/rtc_ds1386.c +++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c | |||
@@ -41,7 +41,9 @@ rtc_ds1386_get_time(void) | |||
41 | u8 byte; | 41 | u8 byte; |
42 | u8 temp; | 42 | u8 temp; |
43 | unsigned int year, month, day, hour, minute, second; | 43 | unsigned int year, month, day, hour, minute, second; |
44 | unsigned long flags; | ||
44 | 45 | ||
46 | spin_lock_irqsave(&rtc_lock, flags); | ||
45 | /* let us freeze external registers */ | 47 | /* let us freeze external registers */ |
46 | byte = READ_RTC(0xB); | 48 | byte = READ_RTC(0xB); |
47 | byte &= 0x3f; | 49 | byte &= 0x3f; |
@@ -60,6 +62,7 @@ rtc_ds1386_get_time(void) | |||
60 | /* enable time transfer */ | 62 | /* enable time transfer */ |
61 | byte |= 0x80; | 63 | byte |= 0x80; |
62 | WRITE_RTC(0xB, byte); | 64 | WRITE_RTC(0xB, byte); |
65 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
63 | 66 | ||
64 | /* calc hour */ | 67 | /* calc hour */ |
65 | if (temp & 0x40) { | 68 | if (temp & 0x40) { |
@@ -81,7 +84,9 @@ rtc_ds1386_set_time(unsigned long t) | |||
81 | u8 byte; | 84 | u8 byte; |
82 | u8 temp; | 85 | u8 temp; |
83 | u8 year, month, day, hour, minute, second; | 86 | u8 year, month, day, hour, minute, second; |
87 | unsigned long flags; | ||
84 | 88 | ||
89 | spin_lock_irqsave(&rtc_lock, flags); | ||
85 | /* let us freeze external registers */ | 90 | /* let us freeze external registers */ |
86 | byte = READ_RTC(0xB); | 91 | byte = READ_RTC(0xB); |
87 | byte &= 0x3f; | 92 | byte &= 0x3f; |
@@ -133,6 +138,7 @@ rtc_ds1386_set_time(unsigned long t) | |||
133 | if (second != READ_RTC(0x1)) { | 138 | if (second != READ_RTC(0x1)) { |
134 | WRITE_RTC(0x1, second); | 139 | WRITE_RTC(0x1, second); |
135 | } | 140 | } |
141 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
136 | 142 | ||
137 | return 0; | 143 | return 0; |
138 | } | 144 | } |
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index dc7091caa7aa..174822344131 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c | |||
@@ -37,10 +37,25 @@ | |||
37 | #include <asm/dec/machtype.h> | 37 | #include <asm/dec/machtype.h> |
38 | 38 | ||
39 | 39 | ||
40 | /* | ||
41 | * Returns true if a clock update is in progress | ||
42 | */ | ||
43 | static inline unsigned char dec_rtc_is_updating(void) | ||
44 | { | ||
45 | unsigned char uip; | ||
46 | unsigned long flags; | ||
47 | |||
48 | spin_lock_irqsave(&rtc_lock, flags); | ||
49 | uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); | ||
50 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
51 | return uip; | ||
52 | } | ||
53 | |||
40 | static unsigned long dec_rtc_get_time(void) | 54 | static unsigned long dec_rtc_get_time(void) |
41 | { | 55 | { |
42 | unsigned int year, mon, day, hour, min, sec, real_year; | 56 | unsigned int year, mon, day, hour, min, sec, real_year; |
43 | int i; | 57 | int i; |
58 | unsigned long flags; | ||
44 | 59 | ||
45 | /* The Linux interpretation of the DS1287 clock register contents: | 60 | /* The Linux interpretation of the DS1287 clock register contents: |
46 | * When the Update-In-Progress (UIP) flag goes from 1 to 0, the | 61 | * When the Update-In-Progress (UIP) flag goes from 1 to 0, the |
@@ -49,11 +64,12 @@ static unsigned long dec_rtc_get_time(void) | |||
49 | */ | 64 | */ |
50 | /* read RTC exactly on falling edge of update flag */ | 65 | /* read RTC exactly on falling edge of update flag */ |
51 | for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ | 66 | for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ |
52 | if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) | 67 | if (dec_rtc_is_updating()) |
53 | break; | 68 | break; |
54 | for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ | 69 | for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ |
55 | if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) | 70 | if (!dec_rtc_is_updating()) |
56 | break; | 71 | break; |
72 | spin_lock_irqsave(&rtc_lock, flags); | ||
57 | /* Isn't this overkill? UIP above should guarantee consistency */ | 73 | /* Isn't this overkill? UIP above should guarantee consistency */ |
58 | do { | 74 | do { |
59 | sec = CMOS_READ(RTC_SECONDS); | 75 | sec = CMOS_READ(RTC_SECONDS); |
@@ -77,6 +93,7 @@ static unsigned long dec_rtc_get_time(void) | |||
77 | * of unused BBU RAM locations. | 93 | * of unused BBU RAM locations. |
78 | */ | 94 | */ |
79 | real_year = CMOS_READ(RTC_DEC_YEAR); | 95 | real_year = CMOS_READ(RTC_DEC_YEAR); |
96 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
80 | year += real_year - 72 + 2000; | 97 | year += real_year - 72 + 2000; |
81 | 98 | ||
82 | return mktime(year, mon, day, hour, min, sec); | 99 | return mktime(year, mon, day, hour, min, sec); |
@@ -95,6 +112,8 @@ static int dec_rtc_set_mmss(unsigned long nowtime) | |||
95 | int real_seconds, real_minutes, cmos_minutes; | 112 | int real_seconds, real_minutes, cmos_minutes; |
96 | unsigned char save_control, save_freq_select; | 113 | unsigned char save_control, save_freq_select; |
97 | 114 | ||
115 | /* irq are locally disabled here */ | ||
116 | spin_lock(&rtc_lock); | ||
98 | /* tell the clock it's being set */ | 117 | /* tell the clock it's being set */ |
99 | save_control = CMOS_READ(RTC_CONTROL); | 118 | save_control = CMOS_READ(RTC_CONTROL); |
100 | CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL); | 119 | CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL); |
@@ -141,6 +160,7 @@ static int dec_rtc_set_mmss(unsigned long nowtime) | |||
141 | */ | 160 | */ |
142 | CMOS_WRITE(save_control, RTC_CONTROL); | 161 | CMOS_WRITE(save_control, RTC_CONTROL); |
143 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); | 162 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); |
163 | spin_unlock(&rtc_lock); | ||
144 | 164 | ||
145 | return retval; | 165 | return retval; |
146 | } | 166 | } |
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c index 1ae4318e1358..8b407d7dc460 100644 --- a/arch/mips/jmr3927/common/rtc_ds1742.c +++ b/arch/mips/jmr3927/common/rtc_ds1742.c | |||
@@ -57,7 +57,9 @@ rtc_ds1742_get_time(void) | |||
57 | { | 57 | { |
58 | unsigned int year, month, day, hour, minute, second; | 58 | unsigned int year, month, day, hour, minute, second; |
59 | unsigned int century; | 59 | unsigned int century; |
60 | unsigned long flags; | ||
60 | 61 | ||
62 | spin_lock_irqsave(&rtc_lock, flags); | ||
61 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 63 | CMOS_WRITE(RTC_READ, RTC_CONTROL); |
62 | second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 64 | second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); |
63 | minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); | 65 | minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); |
@@ -67,6 +69,7 @@ rtc_ds1742_get_time(void) | |||
67 | year = BCD2BIN(CMOS_READ(RTC_YEAR)); | 69 | year = BCD2BIN(CMOS_READ(RTC_YEAR)); |
68 | century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); | 70 | century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); |
69 | CMOS_WRITE(0, RTC_CONTROL); | 71 | CMOS_WRITE(0, RTC_CONTROL); |
72 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
70 | 73 | ||
71 | year += century * 100; | 74 | year += century * 100; |
72 | 75 | ||
@@ -81,7 +84,9 @@ rtc_ds1742_set_time(unsigned long t) | |||
81 | u8 year, month, day, hour, minute, second; | 84 | u8 year, month, day, hour, minute, second; |
82 | u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; | 85 | u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; |
83 | int cmos_century; | 86 | int cmos_century; |
87 | unsigned long flags; | ||
84 | 88 | ||
89 | spin_lock_irqsave(&rtc_lock, flags); | ||
85 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 90 | CMOS_WRITE(RTC_READ, RTC_CONTROL); |
86 | cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 91 | cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); |
87 | cmos_minute = (u8)CMOS_READ(RTC_MINUTES); | 92 | cmos_minute = (u8)CMOS_READ(RTC_MINUTES); |
@@ -139,6 +144,7 @@ rtc_ds1742_set_time(unsigned long t) | |||
139 | 144 | ||
140 | /* RTC_CENTURY and RTC_CONTROL share same address... */ | 145 | /* RTC_CENTURY and RTC_CONTROL share same address... */ |
141 | CMOS_WRITE(cmos_century, RTC_CONTROL); | 146 | CMOS_WRITE(cmos_century, RTC_CONTROL); |
147 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
142 | 148 | ||
143 | return 0; | 149 | return 0; |
144 | } | 150 | } |
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c index 9d7812e03dcd..7dced67c55eb 100644 --- a/arch/mips/lasat/ds1603.c +++ b/arch/mips/lasat/ds1603.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <asm/lasat/lasat.h> | 8 | #include <asm/lasat/lasat.h> |
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <asm/lasat/ds1603.h> | 10 | #include <asm/lasat/ds1603.h> |
11 | #include <asm/time.h> | ||
11 | 12 | ||
12 | #include "ds1603.h" | 13 | #include "ds1603.h" |
13 | 14 | ||
@@ -138,19 +139,27 @@ static void rtc_end_op(void) | |||
138 | unsigned long ds1603_read(void) | 139 | unsigned long ds1603_read(void) |
139 | { | 140 | { |
140 | unsigned long word; | 141 | unsigned long word; |
142 | unsigned long flags; | ||
143 | |||
144 | spin_lock_irqsave(&rtc_lock, flags); | ||
141 | rtc_init_op(); | 145 | rtc_init_op(); |
142 | rtc_write_byte(READ_TIME_CMD); | 146 | rtc_write_byte(READ_TIME_CMD); |
143 | word = rtc_read_word(); | 147 | word = rtc_read_word(); |
144 | rtc_end_op(); | 148 | rtc_end_op(); |
149 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
145 | return word; | 150 | return word; |
146 | } | 151 | } |
147 | 152 | ||
148 | int ds1603_set(unsigned long time) | 153 | int ds1603_set(unsigned long time) |
149 | { | 154 | { |
155 | unsigned long flags; | ||
156 | |||
157 | spin_lock_irqsave(&rtc_lock, flags); | ||
150 | rtc_init_op(); | 158 | rtc_init_op(); |
151 | rtc_write_byte(SET_TIME_CMD); | 159 | rtc_write_byte(SET_TIME_CMD); |
152 | rtc_write_word(time); | 160 | rtc_write_word(time); |
153 | rtc_end_op(); | 161 | rtc_end_op(); |
162 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
154 | 163 | ||
155 | return 0; | 164 | return 0; |
156 | } | 165 | } |
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index 768bf4406452..bab192ddc185 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c | |||
@@ -149,7 +149,9 @@ arch_initcall(per_cpu_mappings); | |||
149 | unsigned long m48t37y_get_time(void) | 149 | unsigned long m48t37y_get_time(void) |
150 | { | 150 | { |
151 | unsigned int year, month, day, hour, min, sec; | 151 | unsigned int year, month, day, hour, min, sec; |
152 | unsigned long flags; | ||
152 | 153 | ||
154 | spin_lock_irqsave(&rtc_lock, flags); | ||
153 | /* stop the update */ | 155 | /* stop the update */ |
154 | rtc_base[0x7ff8] = 0x40; | 156 | rtc_base[0x7ff8] = 0x40; |
155 | 157 | ||
@@ -166,6 +168,7 @@ unsigned long m48t37y_get_time(void) | |||
166 | 168 | ||
167 | /* start the update */ | 169 | /* start the update */ |
168 | rtc_base[0x7ff8] = 0x00; | 170 | rtc_base[0x7ff8] = 0x00; |
171 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
169 | 172 | ||
170 | return mktime(year, month, day, hour, min, sec); | 173 | return mktime(year, month, day, hour, min, sec); |
171 | } | 174 | } |
@@ -173,11 +176,13 @@ unsigned long m48t37y_get_time(void) | |||
173 | int m48t37y_set_time(unsigned long sec) | 176 | int m48t37y_set_time(unsigned long sec) |
174 | { | 177 | { |
175 | struct rtc_time tm; | 178 | struct rtc_time tm; |
179 | unsigned long flags; | ||
176 | 180 | ||
177 | /* convert to a more useful format -- note months count from 0 */ | 181 | /* convert to a more useful format -- note months count from 0 */ |
178 | to_tm(sec, &tm); | 182 | to_tm(sec, &tm); |
179 | tm.tm_mon += 1; | 183 | tm.tm_mon += 1; |
180 | 184 | ||
185 | spin_lock_irqsave(&rtc_lock, flags); | ||
181 | /* enable writing */ | 186 | /* enable writing */ |
182 | rtc_base[0x7ff8] = 0x80; | 187 | rtc_base[0x7ff8] = 0x80; |
183 | 188 | ||
@@ -201,6 +206,7 @@ int m48t37y_set_time(unsigned long sec) | |||
201 | 206 | ||
202 | /* disable writing */ | 207 | /* disable writing */ |
203 | rtc_base[0x7ff8] = 0x00; | 208 | rtc_base[0x7ff8] = 0x00; |
209 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
204 | 210 | ||
205 | return 0; | 211 | return 0; |
206 | } | 212 | } |
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c index a7803e08f9db..c9b7ff8148ec 100644 --- a/arch/mips/momentum/ocelot_3/setup.c +++ b/arch/mips/momentum/ocelot_3/setup.c | |||
@@ -135,7 +135,9 @@ void setup_wired_tlb_entries(void) | |||
135 | unsigned long m48t37y_get_time(void) | 135 | unsigned long m48t37y_get_time(void) |
136 | { | 136 | { |
137 | unsigned int year, month, day, hour, min, sec; | 137 | unsigned int year, month, day, hour, min, sec; |
138 | unsigned long flags; | ||
138 | 139 | ||
140 | spin_lock_irqsave(&rtc_lock, flags); | ||
139 | /* stop the update */ | 141 | /* stop the update */ |
140 | rtc_base[0x7ff8] = 0x40; | 142 | rtc_base[0x7ff8] = 0x40; |
141 | 143 | ||
@@ -152,6 +154,7 @@ unsigned long m48t37y_get_time(void) | |||
152 | 154 | ||
153 | /* start the update */ | 155 | /* start the update */ |
154 | rtc_base[0x7ff8] = 0x00; | 156 | rtc_base[0x7ff8] = 0x00; |
157 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
155 | 158 | ||
156 | return mktime(year, month, day, hour, min, sec); | 159 | return mktime(year, month, day, hour, min, sec); |
157 | } | 160 | } |
@@ -159,11 +162,13 @@ unsigned long m48t37y_get_time(void) | |||
159 | int m48t37y_set_time(unsigned long sec) | 162 | int m48t37y_set_time(unsigned long sec) |
160 | { | 163 | { |
161 | struct rtc_time tm; | 164 | struct rtc_time tm; |
165 | unsigned long flags; | ||
162 | 166 | ||
163 | /* convert to a more useful format -- note months count from 0 */ | 167 | /* convert to a more useful format -- note months count from 0 */ |
164 | to_tm(sec, &tm); | 168 | to_tm(sec, &tm); |
165 | tm.tm_mon += 1; | 169 | tm.tm_mon += 1; |
166 | 170 | ||
171 | spin_lock_irqsave(&rtc_lock, flags); | ||
167 | /* enable writing */ | 172 | /* enable writing */ |
168 | rtc_base[0x7ff8] = 0x80; | 173 | rtc_base[0x7ff8] = 0x80; |
169 | 174 | ||
@@ -187,6 +192,7 @@ int m48t37y_set_time(unsigned long sec) | |||
187 | 192 | ||
188 | /* disable writing */ | 193 | /* disable writing */ |
189 | rtc_base[0x7ff8] = 0x00; | 194 | rtc_base[0x7ff8] = 0x00; |
195 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
190 | 196 | ||
191 | return 0; | 197 | return 0; |
192 | } | 198 | } |
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index ce70fc96f160..2755c1547473 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c | |||
@@ -140,7 +140,9 @@ unsigned long m48t37y_get_time(void) | |||
140 | unsigned char* rtc_base = (unsigned char*)0xfc800000; | 140 | unsigned char* rtc_base = (unsigned char*)0xfc800000; |
141 | #endif | 141 | #endif |
142 | unsigned int year, month, day, hour, min, sec; | 142 | unsigned int year, month, day, hour, min, sec; |
143 | unsigned long flags; | ||
143 | 144 | ||
145 | spin_lock_irqsave(&rtc_lock, flags); | ||
144 | /* stop the update */ | 146 | /* stop the update */ |
145 | rtc_base[0x7ff8] = 0x40; | 147 | rtc_base[0x7ff8] = 0x40; |
146 | 148 | ||
@@ -157,6 +159,7 @@ unsigned long m48t37y_get_time(void) | |||
157 | 159 | ||
158 | /* start the update */ | 160 | /* start the update */ |
159 | rtc_base[0x7ff8] = 0x00; | 161 | rtc_base[0x7ff8] = 0x00; |
162 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
160 | 163 | ||
161 | return mktime(year, month, day, hour, min, sec); | 164 | return mktime(year, month, day, hour, min, sec); |
162 | } | 165 | } |
@@ -169,11 +172,13 @@ int m48t37y_set_time(unsigned long sec) | |||
169 | unsigned char* rtc_base = (unsigned char*)0xfc800000; | 172 | unsigned char* rtc_base = (unsigned char*)0xfc800000; |
170 | #endif | 173 | #endif |
171 | struct rtc_time tm; | 174 | struct rtc_time tm; |
175 | unsigned long flags; | ||
172 | 176 | ||
173 | /* convert to a more useful format -- note months count from 0 */ | 177 | /* convert to a more useful format -- note months count from 0 */ |
174 | to_tm(sec, &tm); | 178 | to_tm(sec, &tm); |
175 | tm.tm_mon += 1; | 179 | tm.tm_mon += 1; |
176 | 180 | ||
181 | spin_lock_irqsave(&rtc_lock, flags); | ||
177 | /* enable writing */ | 182 | /* enable writing */ |
178 | rtc_base[0x7ff8] = 0x80; | 183 | rtc_base[0x7ff8] = 0x80; |
179 | 184 | ||
@@ -197,6 +202,7 @@ int m48t37y_set_time(unsigned long sec) | |||
197 | 202 | ||
198 | /* disable writing */ | 203 | /* disable writing */ |
199 | rtc_base[0x7ff8] = 0x00; | 204 | rtc_base[0x7ff8] = 0x00; |
205 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
200 | 206 | ||
201 | return 0; | 207 | return 0; |
202 | } | 208 | } |
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index bdc2ab55bed6..059755b5ed57 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c | |||
@@ -73,7 +73,9 @@ void __init bus_error_init(void) | |||
73 | unsigned long m48t37y_get_time(void) | 73 | unsigned long m48t37y_get_time(void) |
74 | { | 74 | { |
75 | unsigned int year, month, day, hour, min, sec; | 75 | unsigned int year, month, day, hour, min, sec; |
76 | unsigned long flags; | ||
76 | 77 | ||
78 | spin_lock_irqsave(&rtc_lock, flags); | ||
77 | /* Stop the update to the time */ | 79 | /* Stop the update to the time */ |
78 | m48t37_base->control = 0x40; | 80 | m48t37_base->control = 0x40; |
79 | 81 | ||
@@ -88,6 +90,7 @@ unsigned long m48t37y_get_time(void) | |||
88 | 90 | ||
89 | /* Start the update to the time again */ | 91 | /* Start the update to the time again */ |
90 | m48t37_base->control = 0x00; | 92 | m48t37_base->control = 0x00; |
93 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
91 | 94 | ||
92 | return mktime(year, month, day, hour, min, sec); | 95 | return mktime(year, month, day, hour, min, sec); |
93 | } | 96 | } |
@@ -95,11 +98,13 @@ unsigned long m48t37y_get_time(void) | |||
95 | int m48t37y_set_time(unsigned long sec) | 98 | int m48t37y_set_time(unsigned long sec) |
96 | { | 99 | { |
97 | struct rtc_time tm; | 100 | struct rtc_time tm; |
101 | unsigned long flags; | ||
98 | 102 | ||
99 | /* convert to a more useful format -- note months count from 0 */ | 103 | /* convert to a more useful format -- note months count from 0 */ |
100 | to_tm(sec, &tm); | 104 | to_tm(sec, &tm); |
101 | tm.tm_mon += 1; | 105 | tm.tm_mon += 1; |
102 | 106 | ||
107 | spin_lock_irqsave(&rtc_lock, flags); | ||
103 | /* enable writing */ | 108 | /* enable writing */ |
104 | m48t37_base->control = 0x80; | 109 | m48t37_base->control = 0x80; |
105 | 110 | ||
@@ -123,6 +128,7 @@ int m48t37y_set_time(unsigned long sec) | |||
123 | 128 | ||
124 | /* disable writing */ | 129 | /* disable writing */ |
125 | m48t37_base->control = 0x00; | 130 | m48t37_base->control = 0x00; |
131 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
126 | 132 | ||
127 | return 0; | 133 | return 0; |
128 | } | 134 | } |
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c index df9b5694328a..b7300cc5c5ad 100644 --- a/arch/mips/sgi-ip22/ip22-time.c +++ b/arch/mips/sgi-ip22/ip22-time.c | |||
@@ -35,7 +35,9 @@ static unsigned long indy_rtc_get_time(void) | |||
35 | { | 35 | { |
36 | unsigned int yrs, mon, day, hrs, min, sec; | 36 | unsigned int yrs, mon, day, hrs, min, sec; |
37 | unsigned int save_control; | 37 | unsigned int save_control; |
38 | unsigned long flags; | ||
38 | 39 | ||
40 | spin_lock_irqsave(&rtc_lock, flags); | ||
39 | save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; | 41 | save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; |
40 | hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; | 42 | hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; |
41 | 43 | ||
@@ -47,6 +49,7 @@ static unsigned long indy_rtc_get_time(void) | |||
47 | yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff); | 49 | yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff); |
48 | 50 | ||
49 | hpc3c0->rtcregs[RTC_CMD] = save_control; | 51 | hpc3c0->rtcregs[RTC_CMD] = save_control; |
52 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
50 | 53 | ||
51 | if (yrs < 45) | 54 | if (yrs < 45) |
52 | yrs += 30; | 55 | yrs += 30; |
@@ -60,6 +63,7 @@ static int indy_rtc_set_time(unsigned long tim) | |||
60 | { | 63 | { |
61 | struct rtc_time tm; | 64 | struct rtc_time tm; |
62 | unsigned int save_control; | 65 | unsigned int save_control; |
66 | unsigned long flags; | ||
63 | 67 | ||
64 | to_tm(tim, &tm); | 68 | to_tm(tim, &tm); |
65 | 69 | ||
@@ -68,6 +72,7 @@ static int indy_rtc_set_time(unsigned long tim) | |||
68 | if (tm.tm_year >= 100) | 72 | if (tm.tm_year >= 100) |
69 | tm.tm_year -= 100; | 73 | tm.tm_year -= 100; |
70 | 74 | ||
75 | spin_lock_irqsave(&rtc_lock, flags); | ||
71 | save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; | 76 | save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; |
72 | hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; | 77 | hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; |
73 | 78 | ||
@@ -80,6 +85,7 @@ static int indy_rtc_set_time(unsigned long tim) | |||
80 | hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; | 85 | hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; |
81 | 86 | ||
82 | hpc3c0->rtcregs[RTC_CMD] = save_control; | 87 | hpc3c0->rtcregs[RTC_CMD] = save_control; |
88 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
83 | 89 | ||
84 | return 0; | 90 | return 0; |
85 | } | 91 | } |
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) | |||
144 | int m41t81_set_time(unsigned long t) | 144 | int 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) | |||
187 | unsigned long m41t81_get_time(void) | 190 | unsigned 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) | |||
167 | unsigned long xicor_get_time(void) | 170 | unsigned 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); |
diff --git a/include/asm-mips/mc146818-time.h b/include/asm-mips/mc146818-time.h index a2c2d2c24303..47214861093b 100644 --- a/include/asm-mips/mc146818-time.h +++ b/include/asm-mips/mc146818-time.h | |||
@@ -33,7 +33,9 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime) | |||
33 | int real_seconds, real_minutes, cmos_minutes; | 33 | int real_seconds, real_minutes, cmos_minutes; |
34 | unsigned char save_control, save_freq_select; | 34 | unsigned char save_control, save_freq_select; |
35 | int retval = 0; | 35 | int retval = 0; |
36 | unsigned long flags; | ||
36 | 37 | ||
38 | spin_lock_irqsave(&rtc_lock, flags); | ||
37 | save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ | 39 | save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ |
38 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); | 40 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); |
39 | 41 | ||
@@ -79,14 +81,30 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime) | |||
79 | */ | 81 | */ |
80 | CMOS_WRITE(save_control, RTC_CONTROL); | 82 | CMOS_WRITE(save_control, RTC_CONTROL); |
81 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); | 83 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); |
84 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
82 | 85 | ||
83 | return retval; | 86 | return retval; |
84 | } | 87 | } |
85 | 88 | ||
89 | /* | ||
90 | * Returns true if a clock update is in progress | ||
91 | */ | ||
92 | static inline unsigned char rtc_is_updating(void) | ||
93 | { | ||
94 | unsigned char uip; | ||
95 | unsigned long flags; | ||
96 | |||
97 | spin_lock_irqsave(&rtc_lock, flags); | ||
98 | uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); | ||
99 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
100 | return uip; | ||
101 | } | ||
102 | |||
86 | static inline unsigned long mc146818_get_cmos_time(void) | 103 | static inline unsigned long mc146818_get_cmos_time(void) |
87 | { | 104 | { |
88 | unsigned int year, mon, day, hour, min, sec; | 105 | unsigned int year, mon, day, hour, min, sec; |
89 | int i; | 106 | int i; |
107 | unsigned long flags; | ||
90 | 108 | ||
91 | /* | 109 | /* |
92 | * The Linux interpretation of the CMOS clock register contents: | 110 | * The Linux interpretation of the CMOS clock register contents: |
@@ -97,12 +115,13 @@ static inline unsigned long mc146818_get_cmos_time(void) | |||
97 | 115 | ||
98 | /* read RTC exactly on falling edge of update flag */ | 116 | /* read RTC exactly on falling edge of update flag */ |
99 | for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ | 117 | for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ |
100 | if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) | 118 | if (rtc_is_updating()) |
101 | break; | 119 | break; |
102 | for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ | 120 | for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ |
103 | if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) | 121 | if (!rtc_is_updating()) |
104 | break; | 122 | break; |
105 | 123 | ||
124 | spin_lock_irqsave(&rtc_lock, flags); | ||
106 | do { /* Isn't this overkill ? UIP above should guarantee consistency */ | 125 | do { /* Isn't this overkill ? UIP above should guarantee consistency */ |
107 | sec = CMOS_READ(RTC_SECONDS); | 126 | sec = CMOS_READ(RTC_SECONDS); |
108 | min = CMOS_READ(RTC_MINUTES); | 127 | min = CMOS_READ(RTC_MINUTES); |
@@ -120,6 +139,7 @@ static inline unsigned long mc146818_get_cmos_time(void) | |||
120 | BCD_TO_BIN(mon); | 139 | BCD_TO_BIN(mon); |
121 | BCD_TO_BIN(year); | 140 | BCD_TO_BIN(year); |
122 | } | 141 | } |
142 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
123 | year = mc146818_decode_year(year); | 143 | year = mc146818_decode_year(year); |
124 | 144 | ||
125 | return mktime(year, mon, day, hour, min, sec); | 145 | return mktime(year, mon, day, hour, min, sec); |
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index e22a20665871..9cc3564cc2c9 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/linkage.h> | 20 | #include <linux/linkage.h> |
21 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> |
23 | #include <linux/spinlock.h> | ||
24 | |||
25 | extern spinlock_t rtc_lock; | ||
23 | 26 | ||
24 | /* | 27 | /* |
25 | * RTC ops. By default, they point to no-RTC functions. | 28 | * RTC ops. By default, they point to no-RTC functions. |