diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-06-29 10:15:54 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-06-29 10:15:54 -0400 |
commit | b720f73296916e87c744193c57bc8687d35888fe (patch) | |
tree | 0fba1e98b336929a8f8c4d20d6a82714b7106c98 /arch/arm/mach-versatile | |
parent | 6904b2465cf30265a67711025815784aa345bfad (diff) |
[PATCH] ARM: Convert ARM timer implementations to use readl/writel
Convert ARMs timer implementations to use readl/writel instead of accessing
the registers via a struct.
People have recently asked if accessing timers via a structure is the
"right way" and its not the Linux way. So fix this code to conform to
"The Linux Way"(tm).
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/mach-versatile')
-rw-r--r-- | arch/arm/mach-versatile/core.c | 61 |
1 files changed, 24 insertions, 37 deletions
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 9d1f2253e987..f01c0f8a2bb3 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
34 | #include <asm/hardware/amba.h> | 34 | #include <asm/hardware/amba.h> |
35 | #include <asm/hardware/amba_clcd.h> | 35 | #include <asm/hardware/amba_clcd.h> |
36 | #include <asm/hardware/arm_timer.h> | ||
36 | #include <asm/hardware/icst307.h> | 37 | #include <asm/hardware/icst307.h> |
37 | 38 | ||
38 | #include <asm/mach/arch.h> | 39 | #include <asm/mach/arch.h> |
@@ -788,38 +789,25 @@ void __init versatile_init(void) | |||
788 | */ | 789 | */ |
789 | #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) | 790 | #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) |
790 | #if TIMER_INTERVAL >= 0x100000 | 791 | #if TIMER_INTERVAL >= 0x100000 |
791 | #define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ | 792 | #define TIMER_RELOAD (TIMER_INTERVAL >> 8) |
792 | #define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ | 793 | #define TIMER_DIVISOR (TIMER_CTRL_DIV256) |
793 | #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) | 794 | #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) |
794 | #elif TIMER_INTERVAL >= 0x10000 | 795 | #elif TIMER_INTERVAL >= 0x10000 |
795 | #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ | 796 | #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ |
796 | #define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ | 797 | #define TIMER_DIVISOR (TIMER_CTRL_DIV16) |
797 | #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) | 798 | #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) |
798 | #else | 799 | #else |
799 | #define TIMER_RELOAD (TIMER_INTERVAL) | 800 | #define TIMER_RELOAD (TIMER_INTERVAL) |
800 | #define TIMER_CTRL 0x80 /* Enable */ | 801 | #define TIMER_DIVISOR (TIMER_CTRL_DIV1) |
801 | #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) | 802 | #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) |
802 | #endif | 803 | #endif |
803 | 804 | ||
804 | #define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ | ||
805 | |||
806 | /* | ||
807 | * What does it look like? | ||
808 | */ | ||
809 | typedef struct TimerStruct { | ||
810 | unsigned long TimerLoad; | ||
811 | unsigned long TimerValue; | ||
812 | unsigned long TimerControl; | ||
813 | unsigned long TimerClear; | ||
814 | } TimerStruct_t; | ||
815 | |||
816 | /* | 805 | /* |
817 | * Returns number of ms since last clock interrupt. Note that interrupts | 806 | * Returns number of ms since last clock interrupt. Note that interrupts |
818 | * will have been disabled by do_gettimeoffset() | 807 | * will have been disabled by do_gettimeoffset() |
819 | */ | 808 | */ |
820 | static unsigned long versatile_gettimeoffset(void) | 809 | static unsigned long versatile_gettimeoffset(void) |
821 | { | 810 | { |
822 | volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; | ||
823 | unsigned long ticks1, ticks2, status; | 811 | unsigned long ticks1, ticks2, status; |
824 | 812 | ||
825 | /* | 813 | /* |
@@ -828,11 +816,11 @@ static unsigned long versatile_gettimeoffset(void) | |||
828 | * an interrupt. We get around this by ensuring that the | 816 | * an interrupt. We get around this by ensuring that the |
829 | * counter has not reloaded between our two reads. | 817 | * counter has not reloaded between our two reads. |
830 | */ | 818 | */ |
831 | ticks2 = timer0->TimerValue & 0xffff; | 819 | ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; |
832 | do { | 820 | do { |
833 | ticks1 = ticks2; | 821 | ticks1 = ticks2; |
834 | status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); | 822 | status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); |
835 | ticks2 = timer0->TimerValue & 0xffff; | 823 | ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; |
836 | } while (ticks2 > ticks1); | 824 | } while (ticks2 > ticks1); |
837 | 825 | ||
838 | /* | 826 | /* |
@@ -859,12 +847,10 @@ static unsigned long versatile_gettimeoffset(void) | |||
859 | */ | 847 | */ |
860 | static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 848 | static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
861 | { | 849 | { |
862 | volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; | ||
863 | |||
864 | write_seqlock(&xtime_lock); | 850 | write_seqlock(&xtime_lock); |
865 | 851 | ||
866 | // ...clear the interrupt | 852 | // ...clear the interrupt |
867 | timer0->TimerClear = 1; | 853 | writel(1, TIMER0_VA_BASE + TIMER_INTCLR); |
868 | 854 | ||
869 | timer_tick(regs); | 855 | timer_tick(regs); |
870 | 856 | ||
@@ -884,31 +870,32 @@ static struct irqaction versatile_timer_irq = { | |||
884 | */ | 870 | */ |
885 | static void __init versatile_timer_init(void) | 871 | static void __init versatile_timer_init(void) |
886 | { | 872 | { |
887 | volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; | 873 | u32 val; |
888 | volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; | ||
889 | volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; | ||
890 | volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; | ||
891 | 874 | ||
892 | /* | 875 | /* |
893 | * set clock frequency: | 876 | * set clock frequency: |
894 | * VERSATILE_REFCLK is 32KHz | 877 | * VERSATILE_REFCLK is 32KHz |
895 | * VERSATILE_TIMCLK is 1MHz | 878 | * VERSATILE_TIMCLK is 1MHz |
896 | */ | 879 | */ |
897 | *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= | 880 | val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE)); |
898 | ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | | 881 | writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | |
899 | (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); | 882 | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | |
883 | (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | | ||
884 | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, | ||
885 | IO_ADDRESS(VERSATILE_SCTL_BASE)); | ||
900 | 886 | ||
901 | /* | 887 | /* |
902 | * Initialise to a known state (all timers off) | 888 | * Initialise to a known state (all timers off) |
903 | */ | 889 | */ |
904 | timer0->TimerControl = 0; | 890 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); |
905 | timer1->TimerControl = 0; | 891 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); |
906 | timer2->TimerControl = 0; | 892 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); |
907 | timer3->TimerControl = 0; | 893 | writel(0, TIMER3_VA_BASE + TIMER_CTRL); |
908 | 894 | ||
909 | timer0->TimerLoad = TIMER_RELOAD; | 895 | writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); |
910 | timer0->TimerValue = TIMER_RELOAD; | 896 | writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); |
911 | timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ | 897 | writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | |
898 | TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); | ||
912 | 899 | ||
913 | /* | 900 | /* |
914 | * Make irqs happen for the system timer | 901 | * Make irqs happen for the system timer |