@ -54,16 +54,6 @@ static __u8 rbv_clear;
static int gIER , gIFR , gBufA , gBufB ;
/*
* Timer defs .
*/
# define TICK_SIZE 10000
# define MAC_CLOCK_TICK (783300 / HZ) /* ticks per HZ */
# define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF)
# define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8)
/*
* On Macs with a genuine VIA chip there is no way to mask an individual slot
* interrupt . This limitation also seems to apply to VIA clone logic cores in
@ -278,22 +268,6 @@ void __init via_init(void)
}
}
/*
* Start the 100 Hz clock
*/
void __init via_init_clock ( irq_handler_t func )
{
via1 [ vACR ] | = 0x40 ;
via1 [ vT1LL ] = MAC_CLOCK_LOW ;
via1 [ vT1LH ] = MAC_CLOCK_HIGH ;
via1 [ vT1CL ] = MAC_CLOCK_LOW ;
via1 [ vT1CH ] = MAC_CLOCK_HIGH ;
if ( request_irq ( IRQ_MAC_TIMER_1 , func , 0 , " timer " , func ) )
pr_err ( " Couldn't register %s interrupt \n " , " timer " ) ;
}
/*
* Debugging dump , used in various places to see what ' s going on .
*/
@ -321,29 +295,6 @@ void via_debug_dump(void)
}
}
/*
* This is always executed with interrupts disabled .
*
* TBI : get time offset between scheduling timer ticks
*/
u32 mac_gettimeoffset ( void )
{
unsigned long ticks , offset = 0 ;
/* read VIA1 timer 2 current value */
ticks = via1 [ vT1CL ] | ( via1 [ vT1CH ] < < 8 ) ;
/* The probability of underflow is less than 2% */
if ( ticks > MAC_CLOCK_TICK - MAC_CLOCK_TICK / 50 )
/* Check for pending timer interrupt in VIA1 IFR */
if ( via1 [ vIFR ] & 0x40 ) offset = TICK_SIZE ;
ticks = MAC_CLOCK_TICK - ticks ;
ticks = ticks * 10000L / MAC_CLOCK_TICK ;
return ( ticks + offset ) * 1000 ;
}
/*
* Flush the L2 cache on Macs that have it by flipping
* the system into 24 - bit mode for an instant .
@ -612,3 +563,56 @@ int via2_scsi_drq_pending(void)
return via2 [ gIFR ] & ( 1 < < IRQ_IDX ( IRQ_MAC_SCSIDRQ ) ) ;
}
EXPORT_SYMBOL ( via2_scsi_drq_pending ) ;
/* timer and clock source */
# define VIA_CLOCK_FREQ 783360 /* VIA "phase 2" clock in Hz */
# define VIA_TIMER_INTERVAL (1000000 / HZ) /* microseconds per jiffy */
# define VIA_TIMER_CYCLES (VIA_CLOCK_FREQ / HZ) /* clock cycles per jiffy */
# define VIA_TC (VIA_TIMER_CYCLES - 2) /* including 0 and -1 */
# define VIA_TC_LOW (VIA_TC & 0xFF)
# define VIA_TC_HIGH (VIA_TC >> 8)
void __init via_init_clock ( irq_handler_t timer_routine )
{
if ( request_irq ( IRQ_MAC_TIMER_1 , timer_routine , 0 , " timer " , NULL ) ) {
pr_err ( " Couldn't register %s interrupt \n " , " timer " ) ;
return ;
}
via1 [ vT1LL ] = VIA_TC_LOW ;
via1 [ vT1LH ] = VIA_TC_HIGH ;
via1 [ vT1CL ] = VIA_TC_LOW ;
via1 [ vT1CH ] = VIA_TC_HIGH ;
via1 [ vACR ] | = 0x40 ;
}
u32 mac_gettimeoffset ( void )
{
unsigned long flags ;
u8 count_high ;
u16 count , offset = 0 ;
/*
* Timer counter wrap - around is detected with the timer interrupt flag
* but reading the counter low byte ( vT1CL ) would reset the flag .
* Also , accessing both counter registers is essentially a data race .
* These problems are avoided by ignoring the low byte . Clock accuracy
* is 256 times worse ( error can reach 0.327 ms ) but CPU overhead is
* reduced by avoiding slow VIA register accesses .
*/
local_irq_save ( flags ) ;
count_high = via1 [ vT1CH ] ;
if ( count_high = = 0xFF )
count_high = 0 ;
if ( count_high > 0 & & ( via1 [ vIFR ] & VIA_TIMER_1_INT ) )
offset = VIA_TIMER_CYCLES ;
local_irq_restore ( flags ) ;
count = count_high < < 8 ;
count = VIA_TIMER_CYCLES - count + offset ;
return ( ( count * VIA_TIMER_INTERVAL ) / VIA_TIMER_CYCLES ) * 1000 ;
}