[amazon] Add kernel 2.6.30 support
[openwrt-10.03/.git] / target / linux / amazon / patches-2.6.30 / 220-fix_timer.patch
1 --- a/arch/mips/amazon/setup.c
2 +++ b/arch/mips/amazon/setup.c
3 @@ -36,6 +36,12 @@
4  #include <asm/amazon/irq.h>
5  #include <asm/amazon/model.h>
6  
7 +static unsigned int r4k_offset;
8 +static unsigned int r4k_cur;
9 +
10 +/* required in arch/mips/kernel/kspd.c */
11 +unsigned long cpu_khz;
12 +
13  extern void prom_printf(const char * fmt, ...);
14  static void amazon_reboot_setup(void);
15  
16 @@ -91,35 +97,32 @@ unsigned int amazon_get_cpu_ver(void)
17         return cpu_ver;
18  }
19  
20 -void amazon_time_init(void)
21 +static inline u32 amazon_get_counter_resolution(void)
22  {
23 -       mips_hpt_frequency = amazon_get_cpu_hz()/2;
24 -       printk("mips_hpt_frequency:%d\n", mips_hpt_frequency);
25 +       u32 res;
26 +       __asm__ __volatile__(
27 +               ".set   push\n"
28 +               ".set   mips32r2\n"
29 +               ".set   noreorder\n"
30 +               "rdhwr  %0, $3\n"
31 +               "ehb\n"
32 +               ".set pop\n"
33 +               : "=&r" (res)
34 +               : /* no input */
35 +               : "memory");
36 +       instruction_hazard();
37 +       return res;
38  }
39  
40 -extern int hr_time_resolution;
41 -
42 -/* ISR GPTU Timer 6 for high resolution timer */
43 -static void amazon_timer6_interrupt(int irq, void *dev_id)
44 +void __init plat_time_init(void)
45  {
46 -       timer_interrupt(AMAZON_TIMER6_INT, NULL);
47 -}
48 -
49 -static struct irqaction hrt_irqaction = {
50 -       .handler = amazon_timer6_interrupt,
51 -       .flags = IRQF_DISABLED,
52 -       .name = "hrt",
53 -};
54 +       mips_hpt_frequency = amazon_get_cpu_hz() / amazon_get_counter_resolution();
55 +       r4k_offset = mips_hpt_frequency / HZ;
56 +       printk("mips_hpt_frequency:%d\n", mips_hpt_frequency);
57 +       printk("r4k_offset: %08x(%d)\n", r4k_offset, r4k_offset);
58  
59 -/*
60 - * THe CPU counter for System timer, set to HZ
61 - * GPTU Timer 6 for high resolution timer, set to hr_time_resolution
62 - * Also misuse this routine to print out the CPU type and clock.
63 - */
64 -void __init plat_timer_setup(struct irqaction *irq)
65 -{
66 -       /* cpu counter for timer interrupts */
67 -       setup_irq(MIPS_CPU_TIMER_IRQ, irq);
68 +       r4k_cur = (read_c0_count() + r4k_offset);
69 +       write_c0_compare(r4k_cur);
70  
71         /* enable the timer in the PMU */
72         amazon_writel(amazon_readl(AMAZON_PMU_PWDCR)| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI, AMAZON_PMU_PWDCR);
73 @@ -147,7 +150,6 @@ void __init plat_mem_setup(void)
74         }
75         
76         amazon_reboot_setup();
77 -       board_time_init = amazon_time_init;
78  
79         //stop reset TPE and DFE
80         amazon_writel(0, AMAZON_RST_REQ);
81 --- a/arch/mips/amazon/interrupt.c
82 +++ b/arch/mips/amazon/interrupt.c
83 @@ -184,3 +184,10 @@ void __init arch_init_irq(void)
84                 set_irq_chip(i, &amazon_irq_type);
85         }
86  }
87 +
88 +void __cpuinit arch_fixup_c0_irqs(void)
89 +{
90 +       /* FIXME: check for CPUID and only do fix for specific chips/versions */
91 +       cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
92 +       cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ;
93 +}