aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/sunxi_timer.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2013-03-10 12:03:46 -0400
committerMaxime Ripard <maxime.ripard@free-electrons.com>2013-04-08 15:41:37 -0400
commit049817319a5cf2812ada74018ae9f5c5b739607b (patch)
treeb70504e31c2e63d90ab30ea3e5679bd2328c1bf9 /drivers/clocksource/sunxi_timer.c
parent7c91d302ffe2ffac813c47d6ba2e7489a2ccb35f (diff)
clocksource: sunxi: Cleanup the timer code
The timer code was not exact to some aspects, since most of this code was written wihout any datasheet. Make the needed corrections to match the datasheet. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Diffstat (limited to 'drivers/clocksource/sunxi_timer.c')
-rw-r--r--drivers/clocksource/sunxi_timer.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/clocksource/sunxi_timer.c b/drivers/clocksource/sunxi_timer.c
index 0ce85e29769b..7a3ea236be52 100644
--- a/drivers/clocksource/sunxi_timer.c
+++ b/drivers/clocksource/sunxi_timer.c
@@ -25,15 +25,15 @@
25#include <linux/sunxi_timer.h> 25#include <linux/sunxi_timer.h>
26#include <linux/clk/sunxi.h> 26#include <linux/clk/sunxi.h>
27 27
28#define TIMER_CTL_REG 0x00 28#define TIMER_IRQ_EN_REG 0x00
29#define TIMER_CTL_ENABLE (1 << 0) 29#define TIMER_IRQ_EN(val) (1 << val)
30#define TIMER_IRQ_ST_REG 0x04 30#define TIMER_IRQ_ST_REG 0x04
31#define TIMER0_CTL_REG 0x10 31#define TIMER_CTL_REG(val) (0x10 * val + 0x10)
32#define TIMER0_CTL_ENABLE (1 << 0) 32#define TIMER_CTL_ENABLE (1 << 0)
33#define TIMER0_CTL_AUTORELOAD (1 << 1) 33#define TIMER_CTL_AUTORELOAD (1 << 1)
34#define TIMER0_CTL_ONESHOT (1 << 7) 34#define TIMER_CTL_ONESHOT (1 << 7)
35#define TIMER0_INTVAL_REG 0x14 35#define TIMER_INTVAL_REG(val) (0x10 * val + 0x14)
36#define TIMER0_CNTVAL_REG 0x18 36#define TIMER_CNTVAL_REG(val) (0x10 * val + 0x18)
37 37
38#define TIMER_SCAL 16 38#define TIMER_SCAL 16
39 39
@@ -42,21 +42,21 @@ static void __iomem *timer_base;
42static void sunxi_clkevt_mode(enum clock_event_mode mode, 42static void sunxi_clkevt_mode(enum clock_event_mode mode,
43 struct clock_event_device *clk) 43 struct clock_event_device *clk)
44{ 44{
45 u32 u = readl(timer_base + TIMER0_CTL_REG); 45 u32 u = readl(timer_base + TIMER_CTL_REG(0));
46 46
47 switch (mode) { 47 switch (mode) {
48 case CLOCK_EVT_MODE_PERIODIC: 48 case CLOCK_EVT_MODE_PERIODIC:
49 u &= ~(TIMER0_CTL_ONESHOT); 49 u &= ~(TIMER_CTL_ONESHOT);
50 writel(u | TIMER0_CTL_ENABLE, timer_base + TIMER0_CTL_REG); 50 writel(u | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(0));
51 break; 51 break;
52 52
53 case CLOCK_EVT_MODE_ONESHOT: 53 case CLOCK_EVT_MODE_ONESHOT:
54 writel(u | TIMER0_CTL_ONESHOT, timer_base + TIMER0_CTL_REG); 54 writel(u | TIMER_CTL_ONESHOT, timer_base + TIMER_CTL_REG(0));
55 break; 55 break;
56 case CLOCK_EVT_MODE_UNUSED: 56 case CLOCK_EVT_MODE_UNUSED:
57 case CLOCK_EVT_MODE_SHUTDOWN: 57 case CLOCK_EVT_MODE_SHUTDOWN:
58 default: 58 default:
59 writel(u & ~(TIMER0_CTL_ENABLE), timer_base + TIMER0_CTL_REG); 59 writel(u & ~(TIMER_CTL_ENABLE), timer_base + TIMER_CTL_REG(0));
60 break; 60 break;
61 } 61 }
62} 62}
@@ -64,10 +64,10 @@ static void sunxi_clkevt_mode(enum clock_event_mode mode,
64static int sunxi_clkevt_next_event(unsigned long evt, 64static int sunxi_clkevt_next_event(unsigned long evt,
65 struct clock_event_device *unused) 65 struct clock_event_device *unused)
66{ 66{
67 u32 u = readl(timer_base + TIMER0_CTL_REG); 67 u32 u = readl(timer_base + TIMER_CTL_REG(0));
68 writel(evt, timer_base + TIMER0_CNTVAL_REG); 68 writel(evt, timer_base + TIMER_CNTVAL_REG(0));
69 writel(u | TIMER0_CTL_ENABLE | TIMER0_CTL_AUTORELOAD, 69 writel(u | TIMER_CTL_ENABLE | TIMER_CTL_AUTORELOAD,
70 timer_base + TIMER0_CTL_REG); 70 timer_base + TIMER_CTL_REG(0));
71 71
72 return 0; 72 return 0;
73} 73}
@@ -132,26 +132,26 @@ void __init sunxi_timer_init(void)
132 rate = clk_get_rate(clk); 132 rate = clk_get_rate(clk);
133 133
134 writel(rate / (TIMER_SCAL * HZ), 134 writel(rate / (TIMER_SCAL * HZ),
135 timer_base + TIMER0_INTVAL_REG); 135 timer_base + TIMER_INTVAL_REG(0));
136 136
137 /* set clock source to HOSC, 16 pre-division */ 137 /* set clock source to HOSC, 16 pre-division */
138 val = readl(timer_base + TIMER0_CTL_REG); 138 val = readl(timer_base + TIMER_CTL_REG(0));
139 val &= ~(0x07 << 4); 139 val &= ~(0x07 << 4);
140 val &= ~(0x03 << 2); 140 val &= ~(0x03 << 2);
141 val |= (4 << 4) | (1 << 2); 141 val |= (4 << 4) | (1 << 2);
142 writel(val, timer_base + TIMER0_CTL_REG); 142 writel(val, timer_base + TIMER_CTL_REG(0));
143 143
144 /* set mode to auto reload */ 144 /* set mode to auto reload */
145 val = readl(timer_base + TIMER0_CTL_REG); 145 val = readl(timer_base + TIMER_CTL_REG(0));
146 writel(val | TIMER0_CTL_AUTORELOAD, timer_base + TIMER0_CTL_REG); 146 writel(val | TIMER_CTL_AUTORELOAD, timer_base + TIMER_CTL_REG(0));
147 147
148 ret = setup_irq(irq, &sunxi_timer_irq); 148 ret = setup_irq(irq, &sunxi_timer_irq);
149 if (ret) 149 if (ret)
150 pr_warn("failed to setup irq %d\n", irq); 150 pr_warn("failed to setup irq %d\n", irq);
151 151
152 /* Enable timer0 interrupt */ 152 /* Enable timer0 interrupt */
153 val = readl(timer_base + TIMER_CTL_REG); 153 val = readl(timer_base + TIMER_IRQ_EN_REG);
154 writel(val | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG); 154 writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
155 155
156 sunxi_clockevent.cpumask = cpumask_of(0); 156 sunxi_clockevent.cpumask = cpumask_of(0);
157 157