diff options
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/iop3xx.h | 18 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/include/mach/time.h | 18 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/iq81340mc.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop13xx/iq81340sc.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/em7210.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/glantank.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/iq31244.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/iq80321.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/n2100.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/iq80331.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/iq80332.c | 1 | ||||
-rw-r--r-- | arch/arm/mm/proc-xsc3.S | 2 | ||||
-rw-r--r-- | arch/arm/plat-iop/time.c | 176 |
14 files changed, 178 insertions, 47 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1c4119c60040..455284edda25 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -810,6 +810,8 @@ config ARCH_ACORN | |||
810 | 810 | ||
811 | config PLAT_IOP | 811 | config PLAT_IOP |
812 | bool | 812 | bool |
813 | select GENERIC_CLOCKEVENTS | ||
814 | select GENERIC_TIME | ||
813 | 815 | ||
814 | config PLAT_ORION | 816 | config PLAT_ORION |
815 | bool | 817 | bool |
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 8d60ad267e3a..5daea2961d48 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h | |||
@@ -234,7 +234,13 @@ extern int iop3xx_get_init_atu(void); | |||
234 | void iop3xx_map_io(void); | 234 | void iop3xx_map_io(void); |
235 | void iop_init_cp6_handler(void); | 235 | void iop_init_cp6_handler(void); |
236 | void iop_init_time(unsigned long tickrate); | 236 | void iop_init_time(unsigned long tickrate); |
237 | unsigned long iop_gettimeoffset(void); | 237 | |
238 | static inline u32 read_tmr0(void) | ||
239 | { | ||
240 | u32 val; | ||
241 | asm volatile("mrc p6, 0, %0, c0, c1, 0" : "=r" (val)); | ||
242 | return val; | ||
243 | } | ||
238 | 244 | ||
239 | static inline void write_tmr0(u32 val) | 245 | static inline void write_tmr0(u32 val) |
240 | { | 246 | { |
@@ -253,6 +259,11 @@ static inline u32 read_tcr0(void) | |||
253 | return val; | 259 | return val; |
254 | } | 260 | } |
255 | 261 | ||
262 | static inline void write_tcr0(u32 val) | ||
263 | { | ||
264 | asm volatile("mcr p6, 0, %0, c2, c1, 0" : : "r" (val)); | ||
265 | } | ||
266 | |||
256 | static inline u32 read_tcr1(void) | 267 | static inline u32 read_tcr1(void) |
257 | { | 268 | { |
258 | u32 val; | 269 | u32 val; |
@@ -260,6 +271,11 @@ static inline u32 read_tcr1(void) | |||
260 | return val; | 271 | return val; |
261 | } | 272 | } |
262 | 273 | ||
274 | static inline void write_tcr1(u32 val) | ||
275 | { | ||
276 | asm volatile("mcr p6, 0, %0, c3, c1, 0" : : "r" (val)); | ||
277 | } | ||
278 | |||
263 | static inline void write_trr0(u32 val) | 279 | static inline void write_trr0(u32 val) |
264 | { | 280 | { |
265 | asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); | 281 | asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); |
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h index d6d52527589d..f1c00d6d560b 100644 --- a/arch/arm/mach-iop13xx/include/mach/time.h +++ b/arch/arm/mach-iop13xx/include/mach/time.h | |||
@@ -20,7 +20,6 @@ | |||
20 | #define IOP13XX_CORE_FREQ_1200 (5 << 16) | 20 | #define IOP13XX_CORE_FREQ_1200 (5 << 16) |
21 | 21 | ||
22 | void iop_init_time(unsigned long tickrate); | 22 | void iop_init_time(unsigned long tickrate); |
23 | unsigned long iop_gettimeoffset(void); | ||
24 | 23 | ||
25 | static inline unsigned long iop13xx_core_freq(void) | 24 | static inline unsigned long iop13xx_core_freq(void) |
26 | { | 25 | { |
@@ -66,6 +65,13 @@ static inline unsigned long iop13xx_xsi_bus_ratio(void) | |||
66 | return 2; | 65 | return 2; |
67 | } | 66 | } |
68 | 67 | ||
68 | static inline u32 read_tmr0(void) | ||
69 | { | ||
70 | u32 val; | ||
71 | asm volatile("mrc p6, 0, %0, c0, c9, 0" : "=r" (val)); | ||
72 | return val; | ||
73 | } | ||
74 | |||
69 | static inline void write_tmr0(u32 val) | 75 | static inline void write_tmr0(u32 val) |
70 | { | 76 | { |
71 | asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val)); | 77 | asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val)); |
@@ -83,6 +89,11 @@ static inline u32 read_tcr0(void) | |||
83 | return val; | 89 | return val; |
84 | } | 90 | } |
85 | 91 | ||
92 | static inline void write_tcr0(u32 val) | ||
93 | { | ||
94 | asm volatile("mcr p6, 0, %0, c2, c9, 0" : : "r" (val)); | ||
95 | } | ||
96 | |||
86 | static inline u32 read_tcr1(void) | 97 | static inline u32 read_tcr1(void) |
87 | { | 98 | { |
88 | u32 val; | 99 | u32 val; |
@@ -90,6 +101,11 @@ static inline u32 read_tcr1(void) | |||
90 | return val; | 101 | return val; |
91 | } | 102 | } |
92 | 103 | ||
104 | static inline void write_tcr1(u32 val) | ||
105 | { | ||
106 | asm volatile("mcr p6, 0, %0, c3, c9, 0" : : "r" (val)); | ||
107 | } | ||
108 | |||
93 | static inline void write_trr0(u32 val) | 109 | static inline void write_trr0(u32 val) |
94 | { | 110 | { |
95 | asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val)); | 111 | asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val)); |
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 5051c03d437c..f91f3154577d 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c | |||
@@ -87,7 +87,6 @@ static void __init iq81340mc_timer_init(void) | |||
87 | 87 | ||
88 | static struct sys_timer iq81340mc_timer = { | 88 | static struct sys_timer iq81340mc_timer = { |
89 | .init = iq81340mc_timer_init, | 89 | .init = iq81340mc_timer_init, |
90 | .offset = iop_gettimeoffset, | ||
91 | }; | 90 | }; |
92 | 91 | ||
93 | MACHINE_START(IQ81340MC, "Intel IQ81340MC") | 92 | MACHINE_START(IQ81340MC, "Intel IQ81340MC") |
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index bc443073a8e3..ddb7a3435de9 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c | |||
@@ -89,7 +89,6 @@ static void __init iq81340sc_timer_init(void) | |||
89 | 89 | ||
90 | static struct sys_timer iq81340sc_timer = { | 90 | static struct sys_timer iq81340sc_timer = { |
91 | .init = iq81340sc_timer_init, | 91 | .init = iq81340sc_timer_init, |
92 | .offset = iop_gettimeoffset, | ||
93 | }; | 92 | }; |
94 | 93 | ||
95 | MACHINE_START(IQ81340SC, "Intel IQ81340SC") | 94 | MACHINE_START(IQ81340SC, "Intel IQ81340SC") |
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c index 3ad4696ade42..2bef9b6e1cc9 100644 --- a/arch/arm/mach-iop32x/em7210.c +++ b/arch/arm/mach-iop32x/em7210.c | |||
@@ -42,7 +42,6 @@ static void __init em7210_timer_init(void) | |||
42 | 42 | ||
43 | static struct sys_timer em7210_timer = { | 43 | static struct sys_timer em7210_timer = { |
44 | .init = em7210_timer_init, | 44 | .init = em7210_timer_init, |
45 | .offset = iop_gettimeoffset, | ||
46 | }; | 45 | }; |
47 | 46 | ||
48 | /* | 47 | /* |
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index a9c2dfdb2507..93370a46b620 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c | |||
@@ -47,7 +47,6 @@ static void __init glantank_timer_init(void) | |||
47 | 47 | ||
48 | static struct sys_timer glantank_timer = { | 48 | static struct sys_timer glantank_timer = { |
49 | .init = glantank_timer_init, | 49 | .init = glantank_timer_init, |
50 | .offset = iop_gettimeoffset, | ||
51 | }; | 50 | }; |
52 | 51 | ||
53 | 52 | ||
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index dd1cd9904518..a7a08dda7f33 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c | |||
@@ -78,7 +78,6 @@ static void __init iq31244_timer_init(void) | |||
78 | 78 | ||
79 | static struct sys_timer iq31244_timer = { | 79 | static struct sys_timer iq31244_timer = { |
80 | .init = iq31244_timer_init, | 80 | .init = iq31244_timer_init, |
81 | .offset = iop_gettimeoffset, | ||
82 | }; | 81 | }; |
83 | 82 | ||
84 | 83 | ||
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index fbe27798759d..0200f80c1e17 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c | |||
@@ -46,7 +46,6 @@ static void __init iq80321_timer_init(void) | |||
46 | 46 | ||
47 | static struct sys_timer iq80321_timer = { | 47 | static struct sys_timer iq80321_timer = { |
48 | .init = iq80321_timer_init, | 48 | .init = iq80321_timer_init, |
49 | .offset = iop_gettimeoffset, | ||
50 | }; | 49 | }; |
51 | 50 | ||
52 | 51 | ||
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index d2e427899729..2a5c637639bb 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c | |||
@@ -53,7 +53,6 @@ static void __init n2100_timer_init(void) | |||
53 | 53 | ||
54 | static struct sys_timer n2100_timer = { | 54 | static struct sys_timer n2100_timer = { |
55 | .init = n2100_timer_init, | 55 | .init = n2100_timer_init, |
56 | .offset = iop_gettimeoffset, | ||
57 | }; | 56 | }; |
58 | 57 | ||
59 | 58 | ||
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index d51e10cddf20..394e95a30b75 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c | |||
@@ -48,7 +48,6 @@ static void __init iq80331_timer_init(void) | |||
48 | 48 | ||
49 | static struct sys_timer iq80331_timer = { | 49 | static struct sys_timer iq80331_timer = { |
50 | .init = iq80331_timer_init, | 50 | .init = iq80331_timer_init, |
51 | .offset = iop_gettimeoffset, | ||
52 | }; | 51 | }; |
53 | 52 | ||
54 | 53 | ||
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 92fb44cdbcad..a40badf126c2 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c | |||
@@ -48,7 +48,6 @@ static void __init iq80332_timer_init(void) | |||
48 | 48 | ||
49 | static struct sys_timer iq80332_timer = { | 49 | static struct sys_timer iq80332_timer = { |
50 | .init = iq80332_timer_init, | 50 | .init = iq80332_timer_init, |
51 | .offset = iop_gettimeoffset, | ||
52 | }; | 51 | }; |
53 | 52 | ||
54 | 53 | ||
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 2028f3702881..fab134e29826 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S | |||
@@ -396,7 +396,7 @@ __xsc3_setup: | |||
396 | orr r4, r4, #0x18 @ cache the page table in L2 | 396 | orr r4, r4, #0x18 @ cache the page table in L2 |
397 | mcr p15, 0, r4, c2, c0, 0 @ load page table pointer | 397 | mcr p15, 0, r4, c2, c0, 0 @ load page table pointer |
398 | 398 | ||
399 | mov r0, #0 @ don't allow CP access | 399 | mov r0, #1 << 6 @ cp6 access for early sched_clock |
400 | mcr p15, 0, r0, c15, c1, 0 @ write CP access register | 400 | mcr p15, 0, r0, c15, c1, 0 @ write CP access register |
401 | 401 | ||
402 | mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg | 402 | mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg |
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 8da95d57c21f..6c8a02ad98e3 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/timex.h> | 20 | #include <linux/timex.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/clocksource.h> | ||
23 | #include <linux/clockchips.h> | ||
22 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
23 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
24 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -26,45 +28,136 @@ | |||
26 | #include <asm/mach/time.h> | 28 | #include <asm/mach/time.h> |
27 | #include <mach/time.h> | 29 | #include <mach/time.h> |
28 | 30 | ||
31 | /* | ||
32 | * IOP clocksource (free-running timer 1). | ||
33 | */ | ||
34 | static cycle_t iop_clocksource_read(struct clocksource *unused) | ||
35 | { | ||
36 | return 0xffffffffu - read_tcr1(); | ||
37 | } | ||
38 | |||
39 | static struct clocksource iop_clocksource = { | ||
40 | .name = "iop_timer1", | ||
41 | .rating = 300, | ||
42 | .read = iop_clocksource_read, | ||
43 | .mask = CLOCKSOURCE_MASK(32), | ||
44 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
45 | }; | ||
46 | |||
47 | static void __init iop_clocksource_set_hz(struct clocksource *cs, unsigned int hz) | ||
48 | { | ||
49 | u64 temp; | ||
50 | u32 shift; | ||
51 | |||
52 | /* Find shift and mult values for hz. */ | ||
53 | shift = 32; | ||
54 | do { | ||
55 | temp = (u64) NSEC_PER_SEC << shift; | ||
56 | do_div(temp, hz); | ||
57 | if ((temp >> 32) == 0) | ||
58 | break; | ||
59 | } while (--shift != 0); | ||
60 | |||
61 | cs->shift = shift; | ||
62 | cs->mult = (u32) temp; | ||
63 | |||
64 | printk(KERN_INFO "clocksource: %s uses shift %u mult %#x\n", | ||
65 | cs->name, cs->shift, cs->mult); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * IOP sched_clock() implementation via its clocksource. | ||
70 | */ | ||
71 | unsigned long long sched_clock(void) | ||
72 | { | ||
73 | cycle_t cyc = iop_clocksource_read(NULL); | ||
74 | struct clocksource *cs = &iop_clocksource; | ||
75 | |||
76 | return clocksource_cyc2ns(cyc, cs->mult, cs->shift); | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * IOP clockevents (interrupting timer 0). | ||
81 | */ | ||
82 | static int iop_set_next_event(unsigned long delta, | ||
83 | struct clock_event_device *unused) | ||
84 | { | ||
85 | u32 tmr = IOP_TMR_PRIVILEGED | IOP_TMR_RATIO_1_1; | ||
86 | |||
87 | BUG_ON(delta == 0); | ||
88 | write_tmr0(tmr & ~(IOP_TMR_EN | IOP_TMR_RELOAD)); | ||
89 | write_tcr0(delta); | ||
90 | write_tmr0((tmr & ~IOP_TMR_RELOAD) | IOP_TMR_EN); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
29 | static unsigned long ticks_per_jiffy; | 95 | static unsigned long ticks_per_jiffy; |
30 | static unsigned long ticks_per_usec; | ||
31 | static unsigned long next_jiffy_time; | ||
32 | 96 | ||
33 | unsigned long iop_gettimeoffset(void) | 97 | static void iop_set_mode(enum clock_event_mode mode, |
98 | struct clock_event_device *unused) | ||
34 | { | 99 | { |
35 | unsigned long offset, temp; | 100 | u32 tmr = read_tmr0(); |
101 | |||
102 | switch (mode) { | ||
103 | case CLOCK_EVT_MODE_PERIODIC: | ||
104 | write_tmr0(tmr & ~IOP_TMR_EN); | ||
105 | write_tcr0(ticks_per_jiffy - 1); | ||
106 | tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN); | ||
107 | break; | ||
108 | case CLOCK_EVT_MODE_ONESHOT: | ||
109 | /* ->set_next_event sets period and enables timer */ | ||
110 | tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN); | ||
111 | break; | ||
112 | case CLOCK_EVT_MODE_RESUME: | ||
113 | tmr |= IOP_TMR_EN; | ||
114 | break; | ||
115 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
116 | case CLOCK_EVT_MODE_UNUSED: | ||
117 | default: | ||
118 | tmr &= ~IOP_TMR_EN; | ||
119 | break; | ||
120 | } | ||
36 | 121 | ||
37 | /* enable cp6, if necessary, to avoid taking the overhead of an | 122 | write_tmr0(tmr); |
38 | * undefined instruction trap | 123 | } |
39 | */ | 124 | |
40 | asm volatile ( | 125 | static struct clock_event_device iop_clockevent = { |
41 | "mrc p15, 0, %0, c15, c1, 0\n\t" | 126 | .name = "iop_timer0", |
42 | "tst %0, #(1 << 6)\n\t" | 127 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
43 | "orreq %0, %0, #(1 << 6)\n\t" | 128 | .rating = 300, |
44 | "mcreq p15, 0, %0, c15, c1, 0\n\t" | 129 | .set_next_event = iop_set_next_event, |
45 | #ifdef CONFIG_CPU_XSCALE | 130 | .set_mode = iop_set_mode, |
46 | "mrceq p15, 0, %0, c15, c1, 0\n\t" | 131 | }; |
47 | "moveq %0, %0\n\t" | 132 | |
48 | "subeq pc, pc, #4\n\t" | 133 | static void __init iop_clockevent_set_hz(struct clock_event_device *ce, unsigned int hz) |
49 | #endif | 134 | { |
50 | : "=r"(temp) : : "cc"); | 135 | u64 temp; |
51 | 136 | u32 shift; | |
52 | offset = next_jiffy_time - read_tcr1(); | 137 | |
53 | 138 | /* Find shift and mult values for hz. */ | |
54 | return offset / ticks_per_usec; | 139 | shift = 32; |
140 | do { | ||
141 | temp = (u64) hz << shift; | ||
142 | do_div(temp, NSEC_PER_SEC); | ||
143 | if ((temp >> 32) == 0) | ||
144 | break; | ||
145 | } while (--shift != 0); | ||
146 | |||
147 | ce->shift = shift; | ||
148 | ce->mult = (u32) temp; | ||
149 | |||
150 | printk(KERN_INFO "clockevent: %s uses shift %u mult %#lx\n", | ||
151 | ce->name, ce->shift, ce->mult); | ||
55 | } | 152 | } |
56 | 153 | ||
57 | static irqreturn_t | 154 | static irqreturn_t |
58 | iop_timer_interrupt(int irq, void *dev_id) | 155 | iop_timer_interrupt(int irq, void *dev_id) |
59 | { | 156 | { |
60 | write_tisr(1); | 157 | struct clock_event_device *evt = dev_id; |
61 | |||
62 | while ((signed long)(next_jiffy_time - read_tcr1()) | ||
63 | >= ticks_per_jiffy) { | ||
64 | timer_tick(); | ||
65 | next_jiffy_time -= ticks_per_jiffy; | ||
66 | } | ||
67 | 158 | ||
159 | write_tisr(1); | ||
160 | evt->event_handler(evt); | ||
68 | return IRQ_HANDLED; | 161 | return IRQ_HANDLED; |
69 | } | 162 | } |
70 | 163 | ||
@@ -72,6 +165,7 @@ static struct irqaction iop_timer_irq = { | |||
72 | .name = "IOP Timer Tick", | 165 | .name = "IOP Timer Tick", |
73 | .handler = iop_timer_interrupt, | 166 | .handler = iop_timer_interrupt, |
74 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 167 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
168 | .dev_id = &iop_clockevent, | ||
75 | }; | 169 | }; |
76 | 170 | ||
77 | static unsigned long iop_tick_rate; | 171 | static unsigned long iop_tick_rate; |
@@ -86,21 +180,33 @@ void __init iop_init_time(unsigned long tick_rate) | |||
86 | u32 timer_ctl; | 180 | u32 timer_ctl; |
87 | 181 | ||
88 | ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ); | 182 | ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ); |
89 | ticks_per_usec = tick_rate / 1000000; | ||
90 | next_jiffy_time = 0xffffffff; | ||
91 | iop_tick_rate = tick_rate; | 183 | iop_tick_rate = tick_rate; |
92 | 184 | ||
93 | timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | | 185 | timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | |
94 | IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; | 186 | IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; |
95 | 187 | ||
96 | /* | 188 | /* |
97 | * We use timer 0 for our timer interrupt, and timer 1 as | 189 | * Set up interrupting clockevent timer 0. |
98 | * monotonic counter for tracking missed jiffies. | ||
99 | */ | 190 | */ |
191 | write_tmr0(timer_ctl & ~IOP_TMR_EN); | ||
192 | setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); | ||
193 | iop_clockevent_set_hz(&iop_clockevent, tick_rate); | ||
194 | iop_clockevent.max_delta_ns = | ||
195 | clockevent_delta2ns(0xfffffffe, &iop_clockevent); | ||
196 | iop_clockevent.min_delta_ns = | ||
197 | clockevent_delta2ns(0xf, &iop_clockevent); | ||
198 | iop_clockevent.cpumask = cpumask_of(0); | ||
199 | clockevents_register_device(&iop_clockevent); | ||
100 | write_trr0(ticks_per_jiffy - 1); | 200 | write_trr0(ticks_per_jiffy - 1); |
201 | write_tcr0(ticks_per_jiffy - 1); | ||
101 | write_tmr0(timer_ctl); | 202 | write_tmr0(timer_ctl); |
203 | |||
204 | /* | ||
205 | * Set up free-running clocksource timer 1. | ||
206 | */ | ||
102 | write_trr1(0xffffffff); | 207 | write_trr1(0xffffffff); |
208 | write_tcr1(0xffffffff); | ||
103 | write_tmr1(timer_ctl); | 209 | write_tmr1(timer_ctl); |
104 | 210 | iop_clocksource_set_hz(&iop_clocksource, tick_rate); | |
105 | setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); | 211 | clocksource_register(&iop_clocksource); |
106 | } | 212 | } |