diff options
Diffstat (limited to 'arch/sparc/kernel/pcic.c')
| -rw-r--r-- | arch/sparc/kernel/pcic.c | 48 | 
1 files changed, 26 insertions, 22 deletions
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 6edec801e46..118a3f5806a 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -703,31 +703,28 @@ static void pcic_clear_clock_irq(void)  	pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);  } -static irqreturn_t pcic_timer_handler (int irq, void *h) +/* CPU frequency is 100 MHz, timer increments every 4 CPU clocks */ +#define USECS_PER_JIFFY  (1000000 / HZ) +#define TICK_TIMER_LIMIT ((100 * 1000000 / 4) / HZ) + +static unsigned int pcic_cycles_offset(void)  { -	pcic_clear_clock_irq(); -	xtime_update(1); -#ifndef CONFIG_SMP -	update_process_times(user_mode(get_irq_regs())); -#endif -	return IRQ_HANDLED; -} +	u32 value, count; -#define USECS_PER_JIFFY  10000  /* We have 100HZ "standard" timer for sparc */ -#define TICK_TIMER_LIMIT ((100*1000000/4)/100) +	value = readl(pcic0.pcic_regs + PCI_SYS_COUNTER); +	count = value & ~PCI_SYS_COUNTER_OVERFLOW; -u32 pci_gettimeoffset(void) -{ +	if (value & PCI_SYS_COUNTER_OVERFLOW) +		count += TICK_TIMER_LIMIT;  	/* -	 * We divide all by 100 +	 * We divide all by HZ  	 * to have microsecond resolution and to avoid overflow  	 */ -	unsigned long count = -	    readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW; -	count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100); -	return count * 1000; -} +	count = ((count / HZ) * USECS_PER_JIFFY) / (TICK_TIMER_LIMIT / HZ); +	/* Coordinate with the fact that timer_cs rate is 2MHz */ +	return count * 2; +}  void __init pci_time_init(void)  { @@ -736,9 +733,16 @@ void __init pci_time_init(void)  	int timer_irq, irq;  	int err; -	do_arch_gettimeoffset = pci_gettimeoffset; - -	btfixup(); +#ifndef CONFIG_SMP +	/* +	 * It's in SBUS dimension, because timer_cs is in this dimension. +	 * We take into account this in pcic_cycles_offset() +	 */ +	timer_cs_period = SBUS_CLOCK_RATE / HZ; +	sparc_config.features |= FEAT_L10_CLOCKEVENT; +#endif +	sparc_config.features |= FEAT_L10_CLOCKSOURCE; +	sparc_config.get_cycles_offset = pcic_cycles_offset;  	writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);  	/* PROM should set appropriate irq */ @@ -747,7 +751,7 @@ void __init pci_time_init(void)  	writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),  		pcic->pcic_regs+PCI_COUNTER_IRQ);  	irq = pcic_build_device_irq(NULL, timer_irq); -	err = request_irq(irq, pcic_timer_handler, +	err = request_irq(irq, timer_interrupt,  			  IRQF_TIMER, "timer", NULL);  	if (err) {  		prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);  |