aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/pcic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/pcic.c')
-rw-r--r--arch/sparc/kernel/pcic.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 6edec801e46a..118a3f5806a8 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -703,31 +703,28 @@ static void pcic_clear_clock_irq(void)
703 pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT); 703 pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);
704} 704}
705 705
706static irqreturn_t pcic_timer_handler (int irq, void *h) 706/* CPU frequency is 100 MHz, timer increments every 4 CPU clocks */
707#define USECS_PER_JIFFY (1000000 / HZ)
708#define TICK_TIMER_LIMIT ((100 * 1000000 / 4) / HZ)
709
710static unsigned int pcic_cycles_offset(void)
707{ 711{
708 pcic_clear_clock_irq(); 712 u32 value, count;
709 xtime_update(1);
710#ifndef CONFIG_SMP
711 update_process_times(user_mode(get_irq_regs()));
712#endif
713 return IRQ_HANDLED;
714}
715 713
716#define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */ 714 value = readl(pcic0.pcic_regs + PCI_SYS_COUNTER);
717#define TICK_TIMER_LIMIT ((100*1000000/4)/100) 715 count = value & ~PCI_SYS_COUNTER_OVERFLOW;
718 716
719u32 pci_gettimeoffset(void) 717 if (value & PCI_SYS_COUNTER_OVERFLOW)
720{ 718 count += TICK_TIMER_LIMIT;
721 /* 719 /*
722 * We divide all by 100 720 * We divide all by HZ
723 * to have microsecond resolution and to avoid overflow 721 * to have microsecond resolution and to avoid overflow
724 */ 722 */
725 unsigned long count = 723 count = ((count / HZ) * USECS_PER_JIFFY) / (TICK_TIMER_LIMIT / HZ);
726 readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
727 count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
728 return count * 1000;
729}
730 724
725 /* Coordinate with the fact that timer_cs rate is 2MHz */
726 return count * 2;
727}
731 728
732void __init pci_time_init(void) 729void __init pci_time_init(void)
733{ 730{
@@ -736,9 +733,16 @@ void __init pci_time_init(void)
736 int timer_irq, irq; 733 int timer_irq, irq;
737 int err; 734 int err;
738 735
739 do_arch_gettimeoffset = pci_gettimeoffset; 736#ifndef CONFIG_SMP
740 737 /*
741 btfixup(); 738 * It's in SBUS dimension, because timer_cs is in this dimension.
739 * We take into account this in pcic_cycles_offset()
740 */
741 timer_cs_period = SBUS_CLOCK_RATE / HZ;
742 sparc_config.features |= FEAT_L10_CLOCKEVENT;
743#endif
744 sparc_config.features |= FEAT_L10_CLOCKSOURCE;
745 sparc_config.get_cycles_offset = pcic_cycles_offset;
742 746
743 writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT); 747 writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);
744 /* PROM should set appropriate irq */ 748 /* PROM should set appropriate irq */
@@ -747,7 +751,7 @@ void __init pci_time_init(void)
747 writel (PCI_COUNTER_IRQ_SET(timer_irq, 0), 751 writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),
748 pcic->pcic_regs+PCI_COUNTER_IRQ); 752 pcic->pcic_regs+PCI_COUNTER_IRQ);
749 irq = pcic_build_device_irq(NULL, timer_irq); 753 irq = pcic_build_device_irq(NULL, timer_irq);
750 err = request_irq(irq, pcic_timer_handler, 754 err = request_irq(irq, timer_interrupt,
751 IRQF_TIMER, "timer", NULL); 755 IRQF_TIMER, "timer", NULL);
752 if (err) { 756 if (err) {
753 prom_printf("time_init: unable to attach IRQ%d\n", timer_irq); 757 prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);