Use helpers to obtain task pid in printks (arch code)
[wrt350n-kernel.git] / arch / mips / mipssim / sim_time.c
blobe7fa0d1078a383685e16abe15d7876a441f7bddf
1 #include <linux/types.h>
2 #include <linux/init.h>
3 #include <linux/kernel_stat.h>
4 #include <linux/sched.h>
5 #include <linux/spinlock.h>
6 #include <linux/interrupt.h>
7 #include <linux/mc146818rtc.h>
8 #include <linux/smp.h>
9 #include <linux/timex.h>
11 #include <asm/hardirq.h>
12 #include <asm/div64.h>
13 #include <asm/cpu.h>
14 #include <asm/time.h>
15 #include <asm/irq.h>
16 #include <asm/mc146818-time.h>
17 #include <asm/msc01_ic.h>
19 #include <asm/mips-boards/generic.h>
20 #include <asm/mips-boards/prom.h>
21 #include <asm/mips-boards/simint.h>
24 unsigned long cpu_khz;
27 * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
29 static unsigned int __init estimate_cpu_frequency(void)
31 unsigned int prid = read_c0_prid() & 0xffff00;
32 unsigned int count;
34 #if 1
36 * hardwire the board frequency to 12MHz.
39 if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
40 (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
41 count = 12000000;
42 else
43 count = 6000000;
44 #else
45 unsigned int flags;
47 local_irq_save(flags);
49 /* Start counter exactly on falling edge of update flag */
50 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
51 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
53 /* Start r4k counter. */
54 write_c0_count(0);
56 /* Read counter exactly on falling edge of update flag */
57 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
58 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
60 count = read_c0_count();
62 /* restore interrupts */
63 local_irq_restore(flags);
64 #endif
66 mips_hpt_frequency = count;
68 if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
69 (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
70 count *= 2;
72 count += 5000; /* round */
73 count -= count%10000;
75 return count;
78 void __init plat_time_init(void)
80 unsigned int est_freq, flags;
82 local_irq_save(flags);
84 /* Set Data mode - binary. */
85 CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
87 est_freq = estimate_cpu_frequency();
89 printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
90 (est_freq % 1000000) * 100 / 1000000);
92 cpu_khz = est_freq / 1000;
94 local_irq_restore(flags);
97 static int mips_cpu_timer_irq;
99 static void mips_timer_dispatch(void)
101 do_IRQ(mips_cpu_timer_irq);
105 void __init plat_timer_setup(struct irqaction *irq)
107 if (cpu_has_veic) {
108 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
109 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
110 } else {
111 if (cpu_has_vint)
112 set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
113 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
116 /* we are using the cpu counter for timer interrupts */
117 setup_irq(mips_cpu_timer_irq, irq);
119 #ifdef CONFIG_SMP
120 /* irq_desc(riptor) is a global resource, when the interrupt overlaps
121 on seperate cpu's the first one tries to handle the second interrupt.
122 The effect is that the int remains disabled on the second cpu.
123 Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
124 irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU;
125 set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq);
126 #endif