hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/arch/m68k/bvme6000/config.c
....@@ -18,6 +18,7 @@
1818 #include <linux/kernel.h>
1919 #include <linux/mm.h>
2020 #include <linux/tty.h>
21
+#include <linux/clocksource.h>
2122 #include <linux/console.h>
2223 #include <linux/linkage.h>
2324 #include <linux/init.h>
....@@ -30,7 +31,6 @@
3031 #include <asm/bootinfo.h>
3132 #include <asm/bootinfo-vme.h>
3233 #include <asm/byteorder.h>
33
-#include <asm/pgtable.h>
3434 #include <asm/setup.h>
3535 #include <asm/irq.h>
3636 #include <asm/traps.h>
....@@ -39,7 +39,6 @@
3939
4040 static void bvme6000_get_model(char *model);
4141 extern void bvme6000_sched_init(irq_handler_t handler);
42
-extern u32 bvme6000_gettimeoffset(void);
4342 extern int bvme6000_hwclk (int, struct rtc_time *);
4443 extern void bvme6000_reset (void);
4544 void bvme6000_set_vectors (void);
....@@ -105,7 +104,6 @@
105104 mach_max_dma_address = 0xffffffff;
106105 mach_sched_init = bvme6000_sched_init;
107106 mach_init_IRQ = bvme6000_init_IRQ;
108
- arch_gettimeoffset = bvme6000_gettimeoffset;
109107 mach_hwclk = bvme6000_hwclk;
110108 mach_reset = bvme6000_reset;
111109 mach_get_model = bvme6000_get_model;
....@@ -149,6 +147,21 @@
149147 return IRQ_HANDLED;
150148 }
151149
150
+static u64 bvme6000_read_clk(struct clocksource *cs);
151
+
152
+static struct clocksource bvme6000_clk = {
153
+ .name = "rtc",
154
+ .rating = 250,
155
+ .read = bvme6000_read_clk,
156
+ .mask = CLOCKSOURCE_MASK(32),
157
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
158
+};
159
+
160
+static u32 clk_total, clk_offset;
161
+
162
+#define RTC_TIMER_CLOCK_FREQ 8000000
163
+#define RTC_TIMER_CYCLES (RTC_TIMER_CLOCK_FREQ / HZ)
164
+#define RTC_TIMER_COUNT ((RTC_TIMER_CYCLES / 2) - 1)
152165
153166 static irqreturn_t bvme6000_timer_int (int irq, void *dev_id)
154167 {
....@@ -160,6 +173,8 @@
160173 local_irq_save(flags);
161174 msr = rtc->msr & 0xc0;
162175 rtc->msr = msr | 0x20; /* Ack the interrupt */
176
+ clk_total += RTC_TIMER_CYCLES;
177
+ clk_offset = 0;
163178 timer_routine(0, NULL);
164179 local_irq_restore(flags);
165180
....@@ -182,13 +197,13 @@
182197
183198 rtc->msr = 0; /* Ensure timer registers accessible */
184199
185
- if (request_irq(BVME_IRQ_RTC, bvme6000_timer_int, 0, "timer",
200
+ if (request_irq(BVME_IRQ_RTC, bvme6000_timer_int, IRQF_TIMER, "timer",
186201 timer_routine))
187202 panic ("Couldn't register timer int");
188203
189204 rtc->t1cr_omr = 0x04; /* Mode 2, ext clk */
190
- rtc->t1msb = 39999 >> 8;
191
- rtc->t1lsb = 39999 & 0xff;
205
+ rtc->t1msb = RTC_TIMER_COUNT >> 8;
206
+ rtc->t1lsb = RTC_TIMER_COUNT & 0xff;
192207 rtc->irr_icr1 &= 0xef; /* Route timer 1 to INTR pin */
193208 rtc->msr = 0x40; /* Access int.cntrl, etc */
194209 rtc->pfr_icr0 = 0x80; /* Just timer 1 ints enabled */
....@@ -200,13 +215,13 @@
200215
201216 rtc->msr = msr;
202217
218
+ clocksource_register_hz(&bvme6000_clk, RTC_TIMER_CLOCK_FREQ);
219
+
203220 if (request_irq(BVME_IRQ_ABORT, bvme6000_abort_int, 0,
204221 "abort", bvme6000_abort_int))
205222 panic ("Couldn't register abort int");
206223 }
207224
208
-
209
-/* This is always executed with interrupts disabled. */
210225
211226 /*
212227 * NOTE: Don't accept any readings within 5us of rollover, as
....@@ -215,14 +230,18 @@
215230 * results...
216231 */
217232
218
-u32 bvme6000_gettimeoffset(void)
233
+static u64 bvme6000_read_clk(struct clocksource *cs)
219234 {
235
+ unsigned long flags;
220236 volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
221237 volatile PitRegsPtr pit = (PitRegsPtr)BVME_PIT_BASE;
222
- unsigned char msr = rtc->msr & 0xc0;
238
+ unsigned char msr, msb;
223239 unsigned char t1int, t1op;
224240 u32 v = 800000, ov;
225241
242
+ local_irq_save(flags);
243
+
244
+ msr = rtc->msr & 0xc0;
226245 rtc->msr = 0; /* Ensure timer registers accessible */
227246
228247 do {
....@@ -230,22 +249,25 @@
230249 t1int = rtc->msr & 0x20;
231250 t1op = pit->pcdr & 0x04;
232251 rtc->t1cr_omr |= 0x40; /* Latch timer1 */
233
- v = rtc->t1msb << 8; /* Read timer1 */
234
- v |= rtc->t1lsb; /* Read timer1 */
252
+ msb = rtc->t1msb; /* Read timer1 */
253
+ v = (msb << 8) | rtc->t1lsb; /* Read timer1 */
235254 } while (t1int != (rtc->msr & 0x20) ||
236255 t1op != (pit->pcdr & 0x04) ||
237256 abs(ov-v) > 80 ||
238
- v > 39960);
257
+ v > RTC_TIMER_COUNT - (RTC_TIMER_COUNT / 100));
239258
240
- v = 39999 - v;
259
+ v = RTC_TIMER_COUNT - v;
241260 if (!t1op) /* If in second half cycle.. */
242
- v += 40000;
243
- v /= 8; /* Convert ticks to microseconds */
244
- if (t1int)
245
- v += 10000; /* Int pending, + 10ms */
261
+ v += RTC_TIMER_CYCLES / 2;
262
+ if (msb > 0 && t1int)
263
+ clk_offset = RTC_TIMER_CYCLES;
246264 rtc->msr = msr;
247265
248
- return v * 1000;
266
+ v += clk_offset + clk_total;
267
+
268
+ local_irq_restore(flags);
269
+
270
+ return v;
249271 }
250272
251273 /*