diff options
author | Dan Williams <dan.j.williams@intel.com> | 2007-02-13 11:13:34 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-02-17 10:05:40 -0500 |
commit | 3668b45d46f777b0773ef5ff49531c1144efb6dd (patch) | |
tree | d9bb1a1ce8d0cce8bff99578fc0ba4bf8cdedd75 /arch/arm/plat-iop | |
parent | 4434c5c7fd61c6713de882a2272b66f32fe7cac3 (diff) |
[ARM] 4187/1: iop: unify time implementation across iop32x, iop33x, and iop13xx
* architecture specific details are handled in asm/arch/time.h
* ARCH_IOP13XX now selects PLAT_IOP
* as suggested by Lennert use ifdef CONFIG_XSCALE to skip the cp_wait on
XSC3
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-iop')
-rw-r--r-- | arch/arm/plat-iop/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-iop/time.c | 60 |
2 files changed, 35 insertions, 26 deletions
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile index 3250d732a171..4d2b1da3cd82 100644 --- a/arch/arm/plat-iop/Makefile +++ b/arch/arm/plat-iop/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_ARCH_IOP33X) += cp6.o | |||
24 | 24 | ||
25 | # IOP13XX | 25 | # IOP13XX |
26 | obj-$(CONFIG_ARCH_IOP13XX) += cp6.o | 26 | obj-$(CONFIG_ARCH_IOP13XX) += cp6.o |
27 | obj-$(CONFIG_ARCH_IOP13XX) += time.o | ||
27 | 28 | ||
28 | obj-m := | 29 | obj-m := |
29 | obj-n := | 30 | obj-n := |
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 0d53b813cbb4..16300adfb4de 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c | |||
@@ -24,37 +24,45 @@ | |||
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/mach/irq.h> | 25 | #include <asm/mach/irq.h> |
26 | #include <asm/mach/time.h> | 26 | #include <asm/mach/time.h> |
27 | 27 | #include <asm/arch/time.h> | |
28 | #ifdef CONFIG_ARCH_IOP32X | ||
29 | #define IRQ_IOP3XX_TIMER0 IRQ_IOP32X_TIMER0 | ||
30 | #else | ||
31 | #ifdef CONFIG_ARCH_IOP33X | ||
32 | #define IRQ_IOP3XX_TIMER0 IRQ_IOP33X_TIMER0 | ||
33 | #endif | ||
34 | #endif | ||
35 | 28 | ||
36 | static unsigned long ticks_per_jiffy; | 29 | static unsigned long ticks_per_jiffy; |
37 | static unsigned long ticks_per_usec; | 30 | static unsigned long ticks_per_usec; |
38 | static unsigned long next_jiffy_time; | 31 | static unsigned long next_jiffy_time; |
39 | 32 | ||
40 | unsigned long iop3xx_gettimeoffset(void) | 33 | unsigned long iop_gettimeoffset(void) |
41 | { | 34 | { |
42 | unsigned long offset; | 35 | unsigned long offset, temp1, temp2; |
36 | |||
37 | /* enable cp6, if necessary, to avoid taking the overhead of an | ||
38 | * undefined instruction trap | ||
39 | */ | ||
40 | asm volatile ( | ||
41 | "mrc p15, 0, %0, c15, c1, 0\n\t" | ||
42 | "ands %1, %0, #(1 << 6)\n\t" | ||
43 | "orreq %0, %0, #(1 << 6)\n\t" | ||
44 | "mcreq p15, 0, %0, c15, c1, 0\n\t" | ||
45 | #ifdef CONFIG_XSCALE | ||
46 | "mrceq p15, 0, %0, c15, c1, 0\n\t" | ||
47 | "moveq %0, %0\n\t" | ||
48 | "subeq pc, pc, #4\n\t" | ||
49 | #endif | ||
50 | : "=r"(temp1), "=r"(temp2) : : "cc"); | ||
43 | 51 | ||
44 | offset = next_jiffy_time - *IOP3XX_TU_TCR1; | 52 | offset = next_jiffy_time - read_tcr1(); |
45 | 53 | ||
46 | return offset / ticks_per_usec; | 54 | return offset / ticks_per_usec; |
47 | } | 55 | } |
48 | 56 | ||
49 | static irqreturn_t | 57 | static irqreturn_t |
50 | iop3xx_timer_interrupt(int irq, void *dev_id) | 58 | iop_timer_interrupt(int irq, void *dev_id) |
51 | { | 59 | { |
52 | write_seqlock(&xtime_lock); | 60 | write_seqlock(&xtime_lock); |
53 | 61 | ||
54 | asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (1)); | 62 | write_tisr(1); |
55 | 63 | ||
56 | while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1) | 64 | while ((signed long)(next_jiffy_time - read_tcr1()) |
57 | >= ticks_per_jiffy) { | 65 | >= ticks_per_jiffy) { |
58 | timer_tick(); | 66 | timer_tick(); |
59 | next_jiffy_time -= ticks_per_jiffy; | 67 | next_jiffy_time -= ticks_per_jiffy; |
60 | } | 68 | } |
@@ -64,13 +72,13 @@ iop3xx_timer_interrupt(int irq, void *dev_id) | |||
64 | return IRQ_HANDLED; | 72 | return IRQ_HANDLED; |
65 | } | 73 | } |
66 | 74 | ||
67 | static struct irqaction iop3xx_timer_irq = { | 75 | static struct irqaction iop_timer_irq = { |
68 | .name = "IOP3XX Timer Tick", | 76 | .name = "IOP Timer Tick", |
69 | .handler = iop3xx_timer_interrupt, | 77 | .handler = iop_timer_interrupt, |
70 | .flags = IRQF_DISABLED | IRQF_TIMER, | 78 | .flags = IRQF_DISABLED | IRQF_TIMER, |
71 | }; | 79 | }; |
72 | 80 | ||
73 | void __init iop3xx_init_time(unsigned long tick_rate) | 81 | void __init iop_init_time(unsigned long tick_rate) |
74 | { | 82 | { |
75 | u32 timer_ctl; | 83 | u32 timer_ctl; |
76 | 84 | ||
@@ -78,17 +86,17 @@ void __init iop3xx_init_time(unsigned long tick_rate) | |||
78 | ticks_per_usec = tick_rate / 1000000; | 86 | ticks_per_usec = tick_rate / 1000000; |
79 | next_jiffy_time = 0xffffffff; | 87 | next_jiffy_time = 0xffffffff; |
80 | 88 | ||
81 | timer_ctl = IOP3XX_TMR_EN | IOP3XX_TMR_PRIVILEGED | | 89 | timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | |
82 | IOP3XX_TMR_RELOAD | IOP3XX_TMR_RATIO_1_1; | 90 | IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; |
83 | 91 | ||
84 | /* | 92 | /* |
85 | * We use timer 0 for our timer interrupt, and timer 1 as | 93 | * We use timer 0 for our timer interrupt, and timer 1 as |
86 | * monotonic counter for tracking missed jiffies. | 94 | * monotonic counter for tracking missed jiffies. |
87 | */ | 95 | */ |
88 | asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1)); | 96 | write_trr0(ticks_per_jiffy - 1); |
89 | asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); | 97 | write_tmr0(timer_ctl); |
90 | asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff)); | 98 | write_trr1(0xffffffff); |
91 | asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl)); | 99 | write_tmr1(timer_ctl); |
92 | 100 | ||
93 | setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq); | 101 | setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); |
94 | } | 102 | } |