.. | .. |
---|
23 | 23 | * |
---|
24 | 24 | */ |
---|
25 | 25 | |
---|
| 26 | +#include <linux/clocksource.h> |
---|
26 | 27 | #include <linux/types.h> |
---|
27 | 28 | #include <linux/kernel.h> |
---|
28 | 29 | #include <linux/mm.h> |
---|
.. | .. |
---|
179 | 180 | |
---|
180 | 181 | /* |
---|
181 | 182 | * SE/30: disable video IRQ |
---|
182 | | - * XXX: testing for SE/30 VBL |
---|
183 | 183 | */ |
---|
184 | 184 | |
---|
185 | 185 | if (macintosh_config->ident == MAC_MODEL_SE30) { |
---|
.. | .. |
---|
187 | 187 | via1[vBufB] |= 0x40; |
---|
188 | 188 | } |
---|
189 | 189 | |
---|
190 | | - /* |
---|
191 | | - * Set the RTC bits to a known state: all lines to outputs and |
---|
192 | | - * RTC disabled (yes that's 0 to enable and 1 to disable). |
---|
193 | | - */ |
---|
194 | | - |
---|
195 | | - via1[vDirB] |= (VIA1B_vRTCEnb | VIA1B_vRTCClk | VIA1B_vRTCData); |
---|
196 | | - via1[vBufB] |= (VIA1B_vRTCEnb | VIA1B_vRTCClk); |
---|
| 190 | + switch (macintosh_config->adb_type) { |
---|
| 191 | + case MAC_ADB_IOP: |
---|
| 192 | + case MAC_ADB_II: |
---|
| 193 | + case MAC_ADB_PB1: |
---|
| 194 | + /* |
---|
| 195 | + * Set the RTC bits to a known state: all lines to outputs and |
---|
| 196 | + * RTC disabled (yes that's 0 to enable and 1 to disable). |
---|
| 197 | + */ |
---|
| 198 | + via1[vDirB] |= VIA1B_vRTCEnb | VIA1B_vRTCClk | VIA1B_vRTCData; |
---|
| 199 | + via1[vBufB] |= VIA1B_vRTCEnb | VIA1B_vRTCClk; |
---|
| 200 | + break; |
---|
| 201 | + } |
---|
197 | 202 | |
---|
198 | 203 | /* Everything below this point is VIA2/RBV only... */ |
---|
199 | 204 | |
---|
.. | .. |
---|
365 | 370 | /* Allow NuBus slots 9 through F. */ |
---|
366 | 371 | via2[vDirA] &= 0x80 | ~(1 << irq_idx); |
---|
367 | 372 | } |
---|
368 | | - /* fall through */ |
---|
| 373 | + fallthrough; |
---|
369 | 374 | case MAC_VIA_IICI: |
---|
370 | 375 | via_irq_enable(irq); |
---|
371 | 376 | break; |
---|
.. | .. |
---|
577 | 582 | /* timer and clock source */ |
---|
578 | 583 | |
---|
579 | 584 | #define VIA_CLOCK_FREQ 783360 /* VIA "phase 2" clock in Hz */ |
---|
580 | | -#define VIA_TIMER_INTERVAL (1000000 / HZ) /* microseconds per jiffy */ |
---|
581 | 585 | #define VIA_TIMER_CYCLES (VIA_CLOCK_FREQ / HZ) /* clock cycles per jiffy */ |
---|
582 | 586 | |
---|
583 | 587 | #define VIA_TC (VIA_TIMER_CYCLES - 2) /* including 0 and -1 */ |
---|
584 | 588 | #define VIA_TC_LOW (VIA_TC & 0xFF) |
---|
585 | 589 | #define VIA_TC_HIGH (VIA_TC >> 8) |
---|
586 | 590 | |
---|
| 591 | +static u64 mac_read_clk(struct clocksource *cs); |
---|
| 592 | + |
---|
| 593 | +static struct clocksource mac_clk = { |
---|
| 594 | + .name = "via1", |
---|
| 595 | + .rating = 250, |
---|
| 596 | + .read = mac_read_clk, |
---|
| 597 | + .mask = CLOCKSOURCE_MASK(32), |
---|
| 598 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
---|
| 599 | +}; |
---|
| 600 | + |
---|
| 601 | +static u32 clk_total, clk_offset; |
---|
| 602 | + |
---|
| 603 | +static irqreturn_t via_timer_handler(int irq, void *dev_id) |
---|
| 604 | +{ |
---|
| 605 | + irq_handler_t timer_routine = dev_id; |
---|
| 606 | + |
---|
| 607 | + clk_total += VIA_TIMER_CYCLES; |
---|
| 608 | + clk_offset = 0; |
---|
| 609 | + timer_routine(0, NULL); |
---|
| 610 | + |
---|
| 611 | + return IRQ_HANDLED; |
---|
| 612 | +} |
---|
| 613 | + |
---|
587 | 614 | void __init via_init_clock(irq_handler_t timer_routine) |
---|
588 | 615 | { |
---|
589 | | - if (request_irq(IRQ_MAC_TIMER_1, timer_routine, 0, "timer", NULL)) { |
---|
| 616 | + if (request_irq(IRQ_MAC_TIMER_1, via_timer_handler, IRQF_TIMER, "timer", |
---|
| 617 | + timer_routine)) { |
---|
590 | 618 | pr_err("Couldn't register %s interrupt\n", "timer"); |
---|
591 | 619 | return; |
---|
592 | 620 | } |
---|
.. | .. |
---|
596 | 624 | via1[vT1CL] = VIA_TC_LOW; |
---|
597 | 625 | via1[vT1CH] = VIA_TC_HIGH; |
---|
598 | 626 | via1[vACR] |= 0x40; |
---|
| 627 | + |
---|
| 628 | + clocksource_register_hz(&mac_clk, VIA_CLOCK_FREQ); |
---|
599 | 629 | } |
---|
600 | 630 | |
---|
601 | | -u32 mac_gettimeoffset(void) |
---|
| 631 | +static u64 mac_read_clk(struct clocksource *cs) |
---|
602 | 632 | { |
---|
603 | 633 | unsigned long flags; |
---|
604 | 634 | u8 count_high; |
---|
605 | | - u16 count, offset = 0; |
---|
| 635 | + u16 count; |
---|
| 636 | + u32 ticks; |
---|
606 | 637 | |
---|
607 | 638 | /* |
---|
608 | 639 | * Timer counter wrap-around is detected with the timer interrupt flag |
---|
.. | .. |
---|
618 | 649 | if (count_high == 0xFF) |
---|
619 | 650 | count_high = 0; |
---|
620 | 651 | if (count_high > 0 && (via1[vIFR] & VIA_TIMER_1_INT)) |
---|
621 | | - offset = VIA_TIMER_CYCLES; |
---|
| 652 | + clk_offset = VIA_TIMER_CYCLES; |
---|
| 653 | + count = count_high << 8; |
---|
| 654 | + ticks = VIA_TIMER_CYCLES - count; |
---|
| 655 | + ticks += clk_offset + clk_total; |
---|
622 | 656 | local_irq_restore(flags); |
---|
623 | 657 | |
---|
624 | | - count = count_high << 8; |
---|
625 | | - count = VIA_TIMER_CYCLES - count + offset; |
---|
626 | | - |
---|
627 | | - return ((count * VIA_TIMER_INTERVAL) / VIA_TIMER_CYCLES) * 1000; |
---|
| 658 | + return ticks; |
---|
628 | 659 | } |
---|