aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2013-08-13 10:43:11 -0400
committerDaniel Lezcano <daniel.lezcano@linaro.org>2013-09-02 15:43:58 -0400
commit3579698e85ef9984e698ac3d8e2257a1adeeb722 (patch)
tree443343811c194656a847c82fbaf1d57c7a1c41da
parentad48bd618f3761922c53f08e05fe00f3c85ca275 (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.c69
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
72static struct clock_event_device __percpu **percpu_armada_370_xp_evt; 72static struct clock_event_device __percpu **percpu_armada_370_xp_evt;
73 73
74static 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
80static 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
74static u32 notrace armada_370_xp_read_sched_clock(void) 86static 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
83armada_370_xp_clkevt_next_event(unsigned long delta, 95armada_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
109armada_370_xp_clkevt_mode(enum clock_event_mode mode, 117armada_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 */
170static int armada_370_xp_timer_setup(struct clock_event_device *evt) 172static 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
213void __init armada_370_xp_timer_init(void) 215void __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",