diff options
Diffstat (limited to 'target/linux/amazon/patches-2.6.30/220-fix_timer.patch')
-rw-r--r-- | target/linux/amazon/patches-2.6.30/220-fix_timer.patch | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/target/linux/amazon/patches-2.6.30/220-fix_timer.patch b/target/linux/amazon/patches-2.6.30/220-fix_timer.patch new file mode 100644 index 0000000000..6408b88f91 --- /dev/null +++ b/target/linux/amazon/patches-2.6.30/220-fix_timer.patch @@ -0,0 +1,93 @@ +--- a/arch/mips/amazon/setup.c ++++ b/arch/mips/amazon/setup.c +@@ -36,6 +36,12 @@ + #include <asm/amazon/irq.h> + #include <asm/amazon/model.h> + ++static unsigned int r4k_offset; ++static unsigned int r4k_cur; ++ ++/* required in arch/mips/kernel/kspd.c */ ++unsigned long cpu_khz; ++ + extern void prom_printf(const char * fmt, ...); + static void amazon_reboot_setup(void); + +@@ -91,35 +97,32 @@ unsigned int amazon_get_cpu_ver(void) + return cpu_ver; + } + +-void amazon_time_init(void) ++static inline u32 amazon_get_counter_resolution(void) + { +- mips_hpt_frequency = amazon_get_cpu_hz()/2; +- printk("mips_hpt_frequency:%d\n", mips_hpt_frequency); ++ u32 res; ++ __asm__ __volatile__( ++ ".set push\n" ++ ".set mips32r2\n" ++ ".set noreorder\n" ++ "rdhwr %0, $3\n" ++ "ehb\n" ++ ".set pop\n" ++ : "=&r" (res) ++ : /* no input */ ++ : "memory"); ++ instruction_hazard(); ++ return res; + } + +-extern int hr_time_resolution; +- +-/* ISR GPTU Timer 6 for high resolution timer */ +-static void amazon_timer6_interrupt(int irq, void *dev_id) ++void __init plat_time_init(void) + { +- timer_interrupt(AMAZON_TIMER6_INT, NULL); +-} +- +-static struct irqaction hrt_irqaction = { +- .handler = amazon_timer6_interrupt, +- .flags = IRQF_DISABLED, +- .name = "hrt", +-}; ++ mips_hpt_frequency = amazon_get_cpu_hz() / amazon_get_counter_resolution(); ++ r4k_offset = mips_hpt_frequency / HZ; ++ printk("mips_hpt_frequency:%d\n", mips_hpt_frequency); ++ printk("r4k_offset: %08x(%d)\n", r4k_offset, r4k_offset); + +-/* +- * THe CPU counter for System timer, set to HZ +- * GPTU Timer 6 for high resolution timer, set to hr_time_resolution +- * Also misuse this routine to print out the CPU type and clock. +- */ +-void __init plat_timer_setup(struct irqaction *irq) +-{ +- /* cpu counter for timer interrupts */ +- setup_irq(MIPS_CPU_TIMER_IRQ, irq); ++ r4k_cur = (read_c0_count() + r4k_offset); ++ write_c0_compare(r4k_cur); + + /* enable the timer in the PMU */ + amazon_writel(amazon_readl(AMAZON_PMU_PWDCR)| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI, AMAZON_PMU_PWDCR); +@@ -147,7 +150,6 @@ void __init plat_mem_setup(void) + } + + amazon_reboot_setup(); +- board_time_init = amazon_time_init; + + //stop reset TPE and DFE + amazon_writel(0, AMAZON_RST_REQ); +--- a/arch/mips/amazon/interrupt.c ++++ b/arch/mips/amazon/interrupt.c +@@ -184,3 +184,10 @@ void __init arch_init_irq(void) + set_irq_chip(i, &amazon_irq_type); + } + } ++ ++void __cpuinit arch_fixup_c0_irqs(void) ++{ ++ /* FIXME: check for CPUID and only do fix for specific chips/versions */ ++ cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; ++ cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ; ++} |