diff options
author | Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | 2013-08-13 10:43:11 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2013-09-02 15:43:58 -0400 |
commit | 3579698e85ef9984e698ac3d8e2257a1adeeb722 (patch) | |
tree | 443343811c194656a847c82fbaf1d57c7a1c41da | |
parent | ad48bd618f3761922c53f08e05fe00f3c85ca275 (diff) |
clocksource: armada-370-xp: Simplify TIMER_CTRL register access
This commit creates two functions to access the TIMER_CTRL register:
one for global one for the per-cpu. This makes the code much more
readable. In addition, since the TIMER_CTRL register is also used for
watchdog, this is preparation work for future thread-safe improvements.
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r-- | drivers/clocksource/time-armada-370-xp.c | 69 |
1 files changed, 30 insertions, 39 deletions
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index a3d273943bce..abc2c9f04821 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c | |||
@@ -71,6 +71,18 @@ static u32 ticks_per_jiffy; | |||
71 | 71 | ||
72 | static struct clock_event_device __percpu **percpu_armada_370_xp_evt; | 72 | static struct clock_event_device __percpu **percpu_armada_370_xp_evt; |
73 | 73 | ||
74 | static void timer_ctrl_clrset(u32 clr, u32 set) | ||
75 | { | ||
76 | writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set, | ||
77 | timer_base + TIMER_CTRL_OFF); | ||
78 | } | ||
79 | |||
80 | static void local_timer_ctrl_clrset(u32 clr, u32 set) | ||
81 | { | ||
82 | writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set, | ||
83 | local_base + TIMER_CTRL_OFF); | ||
84 | } | ||
85 | |||
74 | static u32 notrace armada_370_xp_read_sched_clock(void) | 86 | static u32 notrace armada_370_xp_read_sched_clock(void) |
75 | { | 87 | { |
76 | return ~readl(timer_base + TIMER0_VAL_OFF); | 88 | return ~readl(timer_base + TIMER0_VAL_OFF); |
@@ -83,7 +95,6 @@ static int | |||
83 | armada_370_xp_clkevt_next_event(unsigned long delta, | 95 | armada_370_xp_clkevt_next_event(unsigned long delta, |
84 | struct clock_event_device *dev) | 96 | struct clock_event_device *dev) |
85 | { | 97 | { |
86 | u32 u; | ||
87 | /* | 98 | /* |
88 | * Clear clockevent timer interrupt. | 99 | * Clear clockevent timer interrupt. |
89 | */ | 100 | */ |
@@ -97,11 +108,8 @@ armada_370_xp_clkevt_next_event(unsigned long delta, | |||
97 | /* | 108 | /* |
98 | * Enable the timer. | 109 | * Enable the timer. |
99 | */ | 110 | */ |
100 | u = readl(local_base + TIMER_CTRL_OFF); | 111 | local_timer_ctrl_clrset(TIMER0_RELOAD_EN, |
101 | u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN | | 112 | TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); |
102 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | ||
103 | writel(u, local_base + TIMER_CTRL_OFF); | ||
104 | |||
105 | return 0; | 113 | return 0; |
106 | } | 114 | } |
107 | 115 | ||
@@ -109,8 +117,6 @@ static void | |||
109 | armada_370_xp_clkevt_mode(enum clock_event_mode mode, | 117 | armada_370_xp_clkevt_mode(enum clock_event_mode mode, |
110 | struct clock_event_device *dev) | 118 | struct clock_event_device *dev) |
111 | { | 119 | { |
112 | u32 u; | ||
113 | |||
114 | if (mode == CLOCK_EVT_MODE_PERIODIC) { | 120 | if (mode == CLOCK_EVT_MODE_PERIODIC) { |
115 | 121 | ||
116 | /* | 122 | /* |
@@ -122,18 +128,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode, | |||
122 | /* | 128 | /* |
123 | * Enable timer. | 129 | * Enable timer. |
124 | */ | 130 | */ |
125 | 131 | local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | | |
126 | u = readl(local_base + TIMER_CTRL_OFF); | 132 | TIMER0_EN | |
127 | 133 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | |
128 | writel((u | TIMER0_EN | TIMER0_RELOAD_EN | | ||
129 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)), | ||
130 | local_base + TIMER_CTRL_OFF); | ||
131 | } else { | 134 | } else { |
132 | /* | 135 | /* |
133 | * Disable timer. | 136 | * Disable timer. |
134 | */ | 137 | */ |
135 | u = readl(local_base + TIMER_CTRL_OFF); | 138 | local_timer_ctrl_clrset(TIMER0_EN, 0); |
136 | writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF); | ||
137 | 139 | ||
138 | /* | 140 | /* |
139 | * ACK pending timer interrupt. | 141 | * ACK pending timer interrupt. |
@@ -169,18 +171,18 @@ static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) | |||
169 | */ | 171 | */ |
170 | static int armada_370_xp_timer_setup(struct clock_event_device *evt) | 172 | static int armada_370_xp_timer_setup(struct clock_event_device *evt) |
171 | { | 173 | { |
172 | u32 u; | 174 | u32 clr = 0, set = 0; |
173 | int cpu = smp_processor_id(); | 175 | int cpu = smp_processor_id(); |
174 | 176 | ||
175 | /* Use existing clock_event for cpu 0 */ | 177 | /* Use existing clock_event for cpu 0 */ |
176 | if (!smp_processor_id()) | 178 | if (!smp_processor_id()) |
177 | return 0; | 179 | return 0; |
178 | 180 | ||
179 | u = readl(local_base + TIMER_CTRL_OFF); | ||
180 | if (timer25Mhz) | 181 | if (timer25Mhz) |
181 | writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); | 182 | set = TIMER0_25MHZ; |
182 | else | 183 | else |
183 | writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); | 184 | clr = TIMER0_25MHZ; |
185 | local_timer_ctrl_clrset(clr, set); | ||
184 | 186 | ||
185 | evt->name = armada_370_xp_clkevt.name; | 187 | evt->name = armada_370_xp_clkevt.name; |
186 | evt->irq = armada_370_xp_clkevt.irq; | 188 | evt->irq = armada_370_xp_clkevt.irq; |
@@ -212,7 +214,7 @@ static struct local_timer_ops armada_370_xp_local_timer_ops = { | |||
212 | 214 | ||
213 | void __init armada_370_xp_timer_init(void) | 215 | void __init armada_370_xp_timer_init(void) |
214 | { | 216 | { |
215 | u32 u; | 217 | u32 clr = 0, set = 0; |
216 | struct device_node *np; | 218 | struct device_node *np; |
217 | int res; | 219 | int res; |
218 | 220 | ||
@@ -223,29 +225,20 @@ void __init armada_370_xp_timer_init(void) | |||
223 | 225 | ||
224 | if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { | 226 | if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { |
225 | /* The fixed 25MHz timer is available so let's use it */ | 227 | /* The fixed 25MHz timer is available so let's use it */ |
226 | u = readl(local_base + TIMER_CTRL_OFF); | 228 | set = TIMER0_25MHZ; |
227 | writel(u | TIMER0_25MHZ, | ||
228 | local_base + TIMER_CTRL_OFF); | ||
229 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
230 | writel(u | TIMER0_25MHZ, | ||
231 | timer_base + TIMER_CTRL_OFF); | ||
232 | timer_clk = 25000000; | 229 | timer_clk = 25000000; |
233 | } else { | 230 | } else { |
234 | unsigned long rate = 0; | 231 | unsigned long rate = 0; |
235 | struct clk *clk = of_clk_get(np, 0); | 232 | struct clk *clk = of_clk_get(np, 0); |
236 | WARN_ON(IS_ERR(clk)); | 233 | WARN_ON(IS_ERR(clk)); |
237 | rate = clk_get_rate(clk); | 234 | rate = clk_get_rate(clk); |
238 | u = readl(local_base + TIMER_CTRL_OFF); | ||
239 | writel(u & ~(TIMER0_25MHZ), | ||
240 | local_base + TIMER_CTRL_OFF); | ||
241 | |||
242 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
243 | writel(u & ~(TIMER0_25MHZ), | ||
244 | timer_base + TIMER_CTRL_OFF); | ||
245 | |||
246 | timer_clk = rate / TIMER_DIVIDER; | 235 | timer_clk = rate / TIMER_DIVIDER; |
236 | |||
237 | clr = TIMER0_25MHZ; | ||
247 | timer25Mhz = false; | 238 | timer25Mhz = false; |
248 | } | 239 | } |
240 | timer_ctrl_clrset(clr, set); | ||
241 | local_timer_ctrl_clrset(clr, set); | ||
249 | 242 | ||
250 | /* | 243 | /* |
251 | * We use timer 0 as clocksource, and private(local) timer 0 | 244 | * We use timer 0 as clocksource, and private(local) timer 0 |
@@ -267,10 +260,8 @@ void __init armada_370_xp_timer_init(void) | |||
267 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); | 260 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); |
268 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); | 261 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); |
269 | 262 | ||
270 | u = readl(timer_base + TIMER_CTRL_OFF); | 263 | timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN | |
271 | 264 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | |
272 | writel((u | TIMER0_EN | TIMER0_RELOAD_EN | | ||
273 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF); | ||
274 | 265 | ||
275 | clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, | 266 | clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, |
276 | "armada_370_xp_clocksource", | 267 | "armada_370_xp_clocksource", |