Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Dan Williams and committed by
Russell King
3668b45d 4434c5c7

+166 -161
-1
arch/arm/mach-iop13xx/Makefile
··· 5 5 6 6 obj-$(CONFIG_ARCH_IOP13XX) += setup.o 7 7 obj-$(CONFIG_ARCH_IOP13XX) += irq.o 8 - obj-$(CONFIG_ARCH_IOP13XX) += time.o 9 8 obj-$(CONFIG_ARCH_IOP13XX) += pci.o 10 9 obj-$(CONFIG_ARCH_IOP13XX) += io.o 11 10 obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
+3 -2
arch/arm/mach-iop13xx/iq81340mc.c
··· 25 25 #include <asm/mach/arch.h> 26 26 #include <asm/arch/pci.h> 27 27 #include <asm/mach/time.h> 28 + #include <asm/arch/time.h> 28 29 29 30 extern int init_atu; /* Flag to select which ATU(s) to initialize / disable */ 30 31 ··· 79 78 80 79 static void __init iq81340mc_timer_init(void) 81 80 { 82 - iop13xx_init_time(400000000); 81 + iop_init_time(400000000); 83 82 } 84 83 85 84 static struct sys_timer iq81340mc_timer = { 86 85 .init = iq81340mc_timer_init, 87 - .offset = iop13xx_gettimeoffset, 86 + .offset = iop_gettimeoffset, 88 87 }; 89 88 90 89 MACHINE_START(IQ81340MC, "Intel IQ81340MC")
+3 -2
arch/arm/mach-iop13xx/iq81340sc.c
··· 25 25 #include <asm/mach/arch.h> 26 26 #include <asm/arch/pci.h> 27 27 #include <asm/mach/time.h> 28 + #include <asm/arch/time.h> 28 29 29 30 extern int init_atu; 30 31 ··· 81 80 82 81 static void __init iq81340sc_timer_init(void) 83 82 { 84 - iop13xx_init_time(400000000); 83 + iop_init_time(400000000); 85 84 } 86 85 87 86 static struct sys_timer iq81340sc_timer = { 88 87 .init = iq81340sc_timer_init, 89 - .offset = iop13xx_gettimeoffset, 88 + .offset = iop_gettimeoffset, 90 89 }; 91 90 92 91 MACHINE_START(IQ81340SC, "Intel IQ81340SC")
-92
arch/arm/mach-iop13xx/time.c
··· 1 - /* 2 - * arch/arm/mach-iop13xx/time.c 3 - * 4 - * Timer code for IOP13xx (copied from IOP32x/IOP33x implementation) 5 - * 6 - * Author: Deepak Saxena <dsaxena@mvista.com> 7 - * 8 - * Copyright 2002-2003 MontaVista Software Inc. 9 - * 10 - * This program is free software; you can redistribute it and/or modify it 11 - * under the terms of the GNU General Public License as published by the 12 - * Free Software Foundation; either version 2 of the License, or (at your 13 - * option) any later version. 14 - */ 15 - 16 - #include <linux/kernel.h> 17 - #include <linux/interrupt.h> 18 - #include <linux/time.h> 19 - #include <linux/init.h> 20 - #include <linux/timex.h> 21 - #include <asm/io.h> 22 - #include <asm/irq.h> 23 - #include <asm/uaccess.h> 24 - #include <asm/mach/irq.h> 25 - #include <asm/mach/time.h> 26 - 27 - static unsigned long ticks_per_jiffy; 28 - static unsigned long ticks_per_usec; 29 - static unsigned long next_jiffy_time; 30 - 31 - static inline u32 read_tcr1(void) 32 - { 33 - u32 val; 34 - asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val)); 35 - return val; 36 - } 37 - 38 - unsigned long iop13xx_gettimeoffset(void) 39 - { 40 - unsigned long offset; 41 - 42 - offset = next_jiffy_time - read_tcr1(); 43 - 44 - return offset / ticks_per_usec; 45 - } 46 - 47 - static irqreturn_t 48 - iop13xx_timer_interrupt(int irq, void *dev_id) 49 - { 50 - write_seqlock(&xtime_lock); 51 - 52 - asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (1)); 53 - 54 - while ((signed long)(next_jiffy_time - read_tcr1()) 55 - >= ticks_per_jiffy) { 56 - timer_tick(); 57 - next_jiffy_time -= ticks_per_jiffy; 58 - } 59 - 60 - write_sequnlock(&xtime_lock); 61 - 62 - return IRQ_HANDLED; 63 - } 64 - 65 - static struct irqaction iop13xx_timer_irq = { 66 - .name = "IOP13XX Timer Tick", 67 - .handler = iop13xx_timer_interrupt, 68 - .flags = IRQF_DISABLED | IRQF_TIMER, 69 - }; 70 - 71 - void __init iop13xx_init_time(unsigned long tick_rate) 72 - { 73 - u32 timer_ctl; 74 - 75 - ticks_per_jiffy = (tick_rate + HZ/2) / HZ; 76 - ticks_per_usec = tick_rate / 1000000; 77 - next_jiffy_time = 0xffffffff; 78 - 79 - timer_ctl = IOP13XX_TMR_EN | IOP13XX_TMR_PRIVILEGED | 80 - IOP13XX_TMR_RELOAD | IOP13XX_TMR_RATIO_1_1; 81 - 82 - /* 83 - * We use timer 0 for our timer interrupt, and timer 1 as 84 - * monotonic counter for tracking missed jiffies. 85 - */ 86 - asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (ticks_per_jiffy - 1)); 87 - asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (timer_ctl)); 88 - asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (0xffffffff)); 89 - asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (timer_ctl)); 90 - 91 - setup_irq(IRQ_IOP13XX_TIMER0, &iop13xx_timer_irq); 92 - }
+3 -2
arch/arm/mach-iop32x/glantank.c
··· 31 31 #include <asm/mach/time.h> 32 32 #include <asm/mach-types.h> 33 33 #include <asm/page.h> 34 + #include <asm/arch/time.h> 34 35 35 36 /* 36 37 * GLAN Tank timer tick configuration. ··· 39 38 static void __init glantank_timer_init(void) 40 39 { 41 40 /* 33.333 MHz crystal. */ 42 - iop3xx_init_time(200000000); 41 + iop_init_time(200000000); 43 42 } 44 43 45 44 static struct sys_timer glantank_timer = { 46 45 .init = glantank_timer_init, 47 - .offset = iop3xx_gettimeoffset, 46 + .offset = iop_gettimeoffset, 48 47 }; 49 48 50 49
+4 -4
arch/arm/mach-iop32x/iq31244.c
··· 36 36 #include <asm/mach-types.h> 37 37 #include <asm/page.h> 38 38 #include <asm/pgtable.h> 39 - 39 + #include <asm/arch/time.h> 40 40 41 41 /* 42 42 * The EP80219 and IQ31244 use the same machine ID. To find out ··· 56 56 { 57 57 if (is_80219()) { 58 58 /* 33.333 MHz crystal. */ 59 - iop3xx_init_time(200000000); 59 + iop_init_time(200000000); 60 60 } else { 61 61 /* 33.000 MHz crystal. */ 62 - iop3xx_init_time(198000000); 62 + iop_init_time(198000000); 63 63 } 64 64 } 65 65 66 66 static struct sys_timer iq31244_timer = { 67 67 .init = iq31244_timer_init, 68 - .offset = iop3xx_gettimeoffset, 68 + .offset = iop_gettimeoffset, 69 69 }; 70 70 71 71
+3 -2
arch/arm/mach-iop32x/iq80321.c
··· 33 33 #include <asm/mach-types.h> 34 34 #include <asm/page.h> 35 35 #include <asm/pgtable.h> 36 + #include <asm/arch/time.h> 36 37 37 38 /* 38 39 * IQ80321 timer tick configuration. ··· 41 40 static void __init iq80321_timer_init(void) 42 41 { 43 42 /* 33.333 MHz crystal. */ 44 - iop3xx_init_time(200000000); 43 + iop_init_time(200000000); 45 44 } 46 45 47 46 static struct sys_timer iq80321_timer = { 48 47 .init = iq80321_timer_init, 49 - .offset = iop3xx_gettimeoffset, 48 + .offset = iop_gettimeoffset, 50 49 }; 51 50 52 51
+3 -2
arch/arm/mach-iop32x/n2100.c
··· 37 37 #include <asm/mach-types.h> 38 38 #include <asm/page.h> 39 39 #include <asm/pgtable.h> 40 + #include <asm/arch/time.h> 40 41 41 42 /* 42 43 * N2100 timer tick configuration. ··· 45 44 static void __init n2100_timer_init(void) 46 45 { 47 46 /* 33.000 MHz crystal. */ 48 - iop3xx_init_time(198000000); 47 + iop_init_time(198000000); 49 48 } 50 49 51 50 static struct sys_timer n2100_timer = { 52 51 .init = n2100_timer_init, 53 - .offset = iop3xx_gettimeoffset, 52 + .offset = iop_gettimeoffset, 54 53 }; 55 54 56 55
+4 -3
arch/arm/mach-iop33x/iq80331.c
··· 32 32 #include <asm/mach-types.h> 33 33 #include <asm/page.h> 34 34 #include <asm/pgtable.h> 35 + #include <asm/arch/time.h> 35 36 36 37 /* 37 38 * IQ80331 timer tick configuration. ··· 41 40 { 42 41 /* D-Step parts run at a higher internal bus frequency */ 43 42 if (*IOP3XX_ATURID >= 0xa) 44 - iop3xx_init_time(333000000); 43 + iop_init_time(333000000); 45 44 else 46 - iop3xx_init_time(266000000); 45 + iop_init_time(266000000); 47 46 } 48 47 49 48 static struct sys_timer iq80331_timer = { 50 49 .init = iq80331_timer_init, 51 - .offset = iop3xx_gettimeoffset, 50 + .offset = iop_gettimeoffset, 52 51 }; 53 52 54 53
+4 -3
arch/arm/mach-iop33x/iq80332.c
··· 32 32 #include <asm/mach-types.h> 33 33 #include <asm/page.h> 34 34 #include <asm/pgtable.h> 35 + #include <asm/arch/time.h> 35 36 36 37 /* 37 38 * IQ80332 timer tick configuration. ··· 41 40 { 42 41 /* D-Step parts and the iop333 run at a higher internal bus frequency */ 43 42 if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374) 44 - iop3xx_init_time(333000000); 43 + iop_init_time(333000000); 45 44 else 46 - iop3xx_init_time(266000000); 45 + iop_init_time(266000000); 47 46 } 48 47 49 48 static struct sys_timer iq80332_timer = { 50 49 .init = iq80332_timer_init, 51 - .offset = iop3xx_gettimeoffset, 50 + .offset = iop_gettimeoffset, 52 51 }; 53 52 54 53
+1
arch/arm/plat-iop/Makefile
··· 24 24 25 25 # IOP13XX 26 26 obj-$(CONFIG_ARCH_IOP13XX) += cp6.o 27 + obj-$(CONFIG_ARCH_IOP13XX) += time.o 27 28 28 29 obj-m := 29 30 obj-n :=
+34 -26
arch/arm/plat-iop/time.c
··· 24 24 #include <asm/uaccess.h> 25 25 #include <asm/mach/irq.h> 26 26 #include <asm/mach/time.h> 27 - 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 27 + #include <asm/arch/time.h> 35 28 36 29 static unsigned long ticks_per_jiffy; 37 30 static unsigned long ticks_per_usec; 38 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; 43 36 44 - offset = next_jiffy_time - *IOP3XX_TU_TCR1; 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"); 51 + 52 + offset = next_jiffy_time - read_tcr1(); 45 53 46 54 return offset / ticks_per_usec; 47 55 } 48 56 49 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 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) 57 - >= ticks_per_jiffy) { 64 + while ((signed long)(next_jiffy_time - read_tcr1()) 65 + >= ticks_per_jiffy) { 58 66 timer_tick(); 59 67 next_jiffy_time -= ticks_per_jiffy; 60 68 } ··· 72 64 return IRQ_HANDLED; 73 65 } 74 66 75 - static struct irqaction iop3xx_timer_irq = { 76 - .name = "IOP3XX Timer Tick", 77 - .handler = iop3xx_timer_interrupt, 67 + static struct irqaction iop_timer_irq = { 68 + .name = "IOP Timer Tick", 69 + .handler = iop_timer_interrupt, 78 70 .flags = IRQF_DISABLED | IRQF_TIMER, 79 71 }; 80 72 81 - void __init iop3xx_init_time(unsigned long tick_rate) 73 + void __init iop_init_time(unsigned long tick_rate) 82 74 { 83 75 u32 timer_ctl; 84 76 ··· 86 78 ticks_per_usec = tick_rate / 1000000; 87 79 next_jiffy_time = 0xffffffff; 88 80 89 - timer_ctl = IOP3XX_TMR_EN | IOP3XX_TMR_PRIVILEGED | 90 - IOP3XX_TMR_RELOAD | IOP3XX_TMR_RATIO_1_1; 81 + timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | 82 + IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; 91 83 92 84 /* 93 85 * We use timer 0 for our timer interrupt, and timer 1 as 94 86 * monotonic counter for tracking missed jiffies. 95 87 */ 96 - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1)); 97 - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); 98 - asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff)); 99 - asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl)); 88 + write_trr0(ticks_per_jiffy - 1); 89 + write_tmr0(timer_ctl); 90 + write_trr1(0xffffffff); 91 + write_tmr1(timer_ctl); 100 92 101 - setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq); 93 + setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); 102 94 }
-12
include/asm-arm/arch-iop13xx/iop13xx.h
··· 9 9 void iop13xx_map_io(void); 10 10 void iop13xx_platform_init(void); 11 11 void iop13xx_init_irq(void); 12 - void iop13xx_init_time(unsigned long tickrate); 13 - unsigned long iop13xx_gettimeoffset(void); 14 12 15 13 /* CPUID CP6 R0 Page 0 */ 16 14 static inline int iop13xx_cpu_id(void) ··· 450 452 #define IOP13XX_PBI_LR0 IOP13XX_PBI_OFFSET(0xc) 451 453 #define IOP13XX_PBI_BAR1 IOP13XX_PBI_OFFSET(0x10) 452 454 #define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14) 453 - 454 - #define IOP13XX_TMR_TC 0x01 455 - #define IOP13XX_TMR_EN 0x02 456 - #define IOP13XX_TMR_RELOAD 0x04 457 - #define IOP13XX_TMR_PRIVILEGED 0x08 458 - 459 - #define IOP13XX_TMR_RATIO_1_1 0x00 460 - #define IOP13XX_TMR_RATIO_4_1 0x10 461 - #define IOP13XX_TMR_RATIO_8_1 0x20 462 - #define IOP13XX_TMR_RATIO_16_1 0x30 463 455 464 456 #endif /* _IOP13XX_HW_H_ */
+51
include/asm-arm/arch-iop13xx/time.h
··· 1 + #ifndef _IOP13XX_TIME_H_ 2 + #define _IOP13XX_TIME_H_ 3 + #define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0 4 + 5 + #define IOP_TMR_EN 0x02 6 + #define IOP_TMR_RELOAD 0x04 7 + #define IOP_TMR_PRIVILEGED 0x08 8 + #define IOP_TMR_RATIO_1_1 0x00 9 + 10 + void iop_init_time(unsigned long tickrate); 11 + unsigned long iop_gettimeoffset(void); 12 + 13 + static inline void write_tmr0(u32 val) 14 + { 15 + asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val)); 16 + } 17 + 18 + static inline void write_tmr1(u32 val) 19 + { 20 + asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (val)); 21 + } 22 + 23 + static inline u32 read_tcr0(void) 24 + { 25 + u32 val; 26 + asm volatile("mrc p6, 0, %0, c2, c9, 0" : "=r" (val)); 27 + return val; 28 + } 29 + 30 + static inline u32 read_tcr1(void) 31 + { 32 + u32 val; 33 + asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val)); 34 + return val; 35 + } 36 + 37 + static inline void write_trr0(u32 val) 38 + { 39 + asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val)); 40 + } 41 + 42 + static inline void write_trr1(u32 val) 43 + { 44 + asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (val)); 45 + } 46 + 47 + static inline void write_tisr(u32 val) 48 + { 49 + asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (val)); 50 + } 51 + #endif
+4
include/asm-arm/arch-iop32x/time.h
··· 1 + #ifndef _IOP32X_TIME_H_ 2 + #define _IOP32X_TIME_H_ 3 + #define IRQ_IOP_TIMER0 IRQ_IOP32X_TIMER0 4 + #endif
+4
include/asm-arm/arch-iop33x/time.h
··· 1 + #ifndef _IOP33X_TIME_H_ 2 + #define _IOP33X_TIME_H_ 3 + #define IRQ_IOP_TIMER0 IRQ_IOP33X_TIMER0 4 + #endif
+45 -10
include/asm-arm/hardware/iop3xx.h
··· 188 188 #define IOP3XX_TU_TRR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0014) 189 189 #define IOP3XX_TU_TISR (volatile u32 *)IOP3XX_TIMER_REG(0x0018) 190 190 #define IOP3XX_TU_WDTCR (volatile u32 *)IOP3XX_TIMER_REG(0x001c) 191 - #define IOP3XX_TMR_TC 0x01 192 - #define IOP3XX_TMR_EN 0x02 193 - #define IOP3XX_TMR_RELOAD 0x04 194 - #define IOP3XX_TMR_PRIVILEGED 0x09 195 - #define IOP3XX_TMR_RATIO_1_1 0x00 196 - #define IOP3XX_TMR_RATIO_4_1 0x10 197 - #define IOP3XX_TMR_RATIO_8_1 0x20 198 - #define IOP3XX_TMR_RATIO_16_1 0x30 191 + #define IOP_TMR_EN 0x02 192 + #define IOP_TMR_RELOAD 0x04 193 + #define IOP_TMR_PRIVILEGED 0x08 194 + #define IOP_TMR_RATIO_1_1 0x00 199 195 200 196 /* Application accelerator unit */ 201 197 #define IOP3XX_AAU_ACR (volatile u32 *)IOP3XX_REG_ADDR(0x0800) ··· 272 276 273 277 #ifndef __ASSEMBLY__ 274 278 void iop3xx_map_io(void); 275 - void iop3xx_init_time(unsigned long); 276 - unsigned long iop3xx_gettimeoffset(void); 277 279 void iop_init_cp6_handler(void); 280 + void iop_init_time(unsigned long tickrate); 281 + unsigned long iop_gettimeoffset(void); 282 + 283 + static inline void write_tmr0(u32 val) 284 + { 285 + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (val)); 286 + } 287 + 288 + static inline void write_tmr1(u32 val) 289 + { 290 + asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (val)); 291 + } 292 + 293 + static inline u32 read_tcr0(void) 294 + { 295 + u32 val; 296 + asm volatile("mrc p6, 0, %0, c2, c1, 0" : "=r" (val)); 297 + return val; 298 + } 299 + 300 + static inline u32 read_tcr1(void) 301 + { 302 + u32 val; 303 + asm volatile("mrc p6, 0, %0, c3, c1, 0" : "=r" (val)); 304 + return val; 305 + } 306 + 307 + static inline void write_trr0(u32 val) 308 + { 309 + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); 310 + } 311 + 312 + static inline void write_trr1(u32 val) 313 + { 314 + asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (val)); 315 + } 316 + 317 + static inline void write_tisr(u32 val) 318 + { 319 + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val)); 320 + } 278 321 279 322 extern struct platform_device iop3xx_i2c0_device; 280 323 extern struct platform_device iop3xx_i2c1_device;