aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-11-27 05:47:10 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-11-27 05:47:38 -0500
commit89de77a8c557f14d2713a1f43fbc33980e639b98 (patch)
tree3d7f32120b6b155e3d1374b277a6333cdb9c31cc
parentcb2aa63469f81426c7406227be70b628b42f7a05 (diff)
parent4a22d9c93af1f2b2c40354c4bc59fd007f33f05e (diff)
Merge branch 'clockevents/3.19' of http://git.linaro.org/people/daniel.lezcano/linux into timers/core
Daniel Lezcano muttered: * Marvell timer updates from Ezequiel Garcia - Add missing clock enable calls for armada - Change source clock for clocksource and watchdog * SIRF timer updates from Yanchang Li - Make clock rate configurable
-rw-r--r--Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt9
-rw-r--r--Documentation/devicetree/bindings/watchdog/marvel.txt13
-rw-r--r--drivers/clocksource/time-armada-370-xp.c30
-rw-r--r--drivers/clocksource/timer-marco.c23
-rw-r--r--drivers/watchdog/orion_wdt.c42
5 files changed, 99 insertions, 18 deletions
diff --git a/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt b/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
index f455182b1086..e9c78ce880e6 100644
--- a/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
+++ b/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
@@ -2,8 +2,10 @@ Marvell Armada 370 and Armada XP Timers
2--------------------------------------- 2---------------------------------------
3 3
4Required properties: 4Required properties:
5- compatible: Should be either "marvell,armada-370-timer" or 5- compatible: Should be one of the following
6 "marvell,armada-xp-timer" as appropriate. 6 "marvell,armada-370-timer",
7 "marvell,armada-375-timer",
8 "marvell,armada-xp-timer".
7- interrupts: Should contain the list of Global Timer interrupts and 9- interrupts: Should contain the list of Global Timer interrupts and
8 then local timer interrupts 10 then local timer interrupts
9- reg: Should contain location and length for timers register. First 11- reg: Should contain location and length for timers register. First
@@ -13,7 +15,8 @@ Required properties:
13Clocks required for compatible = "marvell,armada-370-timer": 15Clocks required for compatible = "marvell,armada-370-timer":
14- clocks : Must contain a single entry describing the clock input 16- clocks : Must contain a single entry describing the clock input
15 17
16Clocks required for compatible = "marvell,armada-xp-timer": 18Clocks required for compatibles = "marvell,armada-xp-timer",
19 "marvell,armada-375-timer":
17- clocks : Must contain an entry for each entry in clock-names. 20- clocks : Must contain an entry for each entry in clock-names.
18- clock-names : Must include the following entries: 21- clock-names : Must include the following entries:
19 "nbclk" (L2/coherency fabric clock), 22 "nbclk" (L2/coherency fabric clock),
diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt
index 97223fddb7bd..858ed9221ac4 100644
--- a/Documentation/devicetree/bindings/watchdog/marvel.txt
+++ b/Documentation/devicetree/bindings/watchdog/marvel.txt
@@ -17,6 +17,18 @@ For "marvell,armada-375-wdt" and "marvell,armada-380-wdt":
17- reg : A third entry is mandatory and should contain the 17- reg : A third entry is mandatory and should contain the
18 shared mask/unmask RSTOUT address. 18 shared mask/unmask RSTOUT address.
19 19
20Clocks required for compatibles = "marvell,orion-wdt",
21 "marvell,armada-370-wdt":
22- clocks : Must contain a single entry describing the clock input
23
24Clocks required for compatibles = "marvell,armada-xp-wdt"
25 "marvell,armada-375-wdt"
26 "marvell,armada-380-wdt":
27- clocks : Must contain an entry for each entry in clock-names.
28- clock-names : Must include the following entries:
29 "nbclk" (L2/coherency fabric clock),
30 "fixed" (Reference 25 MHz fixed-clock).
31
20Optional properties: 32Optional properties:
21 33
22- interrupts : Contains the IRQ for watchdog expiration 34- interrupts : Contains the IRQ for watchdog expiration
@@ -30,4 +42,5 @@ Example:
30 interrupts = <3>; 42 interrupts = <3>;
31 timeout-sec = <10>; 43 timeout-sec = <10>;
32 status = "okay"; 44 status = "okay";
45 clocks = <&gate_clk 7>;
33 }; 46 };
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 0451e62fac7a..3a0704b0d739 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -293,6 +293,7 @@ static void __init armada_xp_timer_init(struct device_node *np)
293 293
294 /* The 25Mhz fixed clock is mandatory, and must always be available */ 294 /* The 25Mhz fixed clock is mandatory, and must always be available */
295 BUG_ON(IS_ERR(clk)); 295 BUG_ON(IS_ERR(clk));
296 clk_prepare_enable(clk);
296 timer_clk = clk_get_rate(clk); 297 timer_clk = clk_get_rate(clk);
297 298
298 armada_370_xp_timer_common_init(np); 299 armada_370_xp_timer_common_init(np);
@@ -300,11 +301,40 @@ static void __init armada_xp_timer_init(struct device_node *np)
300CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", 301CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
301 armada_xp_timer_init); 302 armada_xp_timer_init);
302 303
304static void __init armada_375_timer_init(struct device_node *np)
305{
306 struct clk *clk;
307
308 clk = of_clk_get_by_name(np, "fixed");
309 if (!IS_ERR(clk)) {
310 clk_prepare_enable(clk);
311 timer_clk = clk_get_rate(clk);
312 } else {
313
314 /*
315 * This fallback is required in order to retain proper
316 * devicetree backwards compatibility.
317 */
318 clk = of_clk_get(np, 0);
319
320 /* Must have at least a clock */
321 BUG_ON(IS_ERR(clk));
322 clk_prepare_enable(clk);
323 timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
324 timer25Mhz = false;
325 }
326
327 armada_370_xp_timer_common_init(np);
328}
329CLOCKSOURCE_OF_DECLARE(armada_375, "marvell,armada-375-timer",
330 armada_375_timer_init);
331
303static void __init armada_370_timer_init(struct device_node *np) 332static void __init armada_370_timer_init(struct device_node *np)
304{ 333{
305 struct clk *clk = of_clk_get(np, 0); 334 struct clk *clk = of_clk_get(np, 0);
306 335
307 BUG_ON(IS_ERR(clk)); 336 BUG_ON(IS_ERR(clk));
337 clk_prepare_enable(clk);
308 timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; 338 timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
309 timer25Mhz = false; 339 timer25Mhz = false;
310 340
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c
index caf7a2030461..361a789d4bee 100644
--- a/drivers/clocksource/timer-marco.c
+++ b/drivers/clocksource/timer-marco.c
@@ -20,8 +20,6 @@
20#include <linux/of_address.h> 20#include <linux/of_address.h>
21#include <linux/sched_clock.h> 21#include <linux/sched_clock.h>
22 22
23#define MARCO_CLOCK_FREQ 1000000
24
25#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 23#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
26#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004 24#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
27#define SIRFSOC_TIMER_MATCH_0 0x0018 25#define SIRFSOC_TIMER_MATCH_0 0x0018
@@ -40,6 +38,8 @@
40 38
41#define SIRFSOC_TIMER_REG_CNT 6 39#define SIRFSOC_TIMER_REG_CNT 6
42 40
41static unsigned long marco_timer_rate;
42
43static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = { 43static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
44 SIRFSOC_TIMER_WATCHDOG_EN, 44 SIRFSOC_TIMER_WATCHDOG_EN,
45 SIRFSOC_TIMER_32COUNTER_0_CTRL, 45 SIRFSOC_TIMER_32COUNTER_0_CTRL,
@@ -195,7 +195,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
195 ce->rating = 200; 195 ce->rating = 200;
196 ce->set_mode = sirfsoc_timer_set_mode; 196 ce->set_mode = sirfsoc_timer_set_mode;
197 ce->set_next_event = sirfsoc_timer_set_next_event; 197 ce->set_next_event = sirfsoc_timer_set_next_event;
198 clockevents_calc_mult_shift(ce, MARCO_CLOCK_FREQ, 60); 198 clockevents_calc_mult_shift(ce, marco_timer_rate, 60);
199 ce->max_delta_ns = clockevent_delta2ns(-2, ce); 199 ce->max_delta_ns = clockevent_delta2ns(-2, ce);
200 ce->min_delta_ns = clockevent_delta2ns(2, ce); 200 ce->min_delta_ns = clockevent_delta2ns(2, ce);
201 ce->cpumask = cpumask_of(cpu); 201 ce->cpumask = cpumask_of(cpu);
@@ -257,7 +257,6 @@ static void __init sirfsoc_clockevent_init(void)
257/* initialize the kernel jiffy timer source */ 257/* initialize the kernel jiffy timer source */
258static void __init sirfsoc_marco_timer_init(struct device_node *np) 258static void __init sirfsoc_marco_timer_init(struct device_node *np)
259{ 259{
260 unsigned long rate;
261 u32 timer_div; 260 u32 timer_div;
262 struct clk *clk; 261 struct clk *clk;
263 262
@@ -266,16 +265,12 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
266 265
267 BUG_ON(clk_prepare_enable(clk)); 266 BUG_ON(clk_prepare_enable(clk));
268 267
269 rate = clk_get_rate(clk); 268 marco_timer_rate = clk_get_rate(clk);
270
271 BUG_ON(rate < MARCO_CLOCK_FREQ);
272 BUG_ON(rate % MARCO_CLOCK_FREQ);
273 269
274 /* Initialize the timer dividers */ 270 /* timer dividers: 0, not divided */
275 timer_div = rate / MARCO_CLOCK_FREQ - 1; 271 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
276 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); 272 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
277 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); 273 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
278 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
279 274
280 /* Initialize timer counters to 0 */ 275 /* Initialize timer counters to 0 */
281 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO); 276 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
@@ -288,7 +283,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
288 /* Clear all interrupts */ 283 /* Clear all interrupts */
289 writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); 284 writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
290 285
291 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, MARCO_CLOCK_FREQ)); 286 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, marco_timer_rate));
292 287
293 sirfsoc_clockevent_init(); 288 sirfsoc_clockevent_init();
294} 289}
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 00d0741228fc..8cb1ff3bcd90 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -114,6 +114,46 @@ static int armada370_wdt_clock_init(struct platform_device *pdev,
114 return 0; 114 return 0;
115} 115}
116 116
117static int armada375_wdt_clock_init(struct platform_device *pdev,
118 struct orion_watchdog *dev)
119{
120 int ret;
121
122 dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
123 if (!IS_ERR(dev->clk)) {
124 ret = clk_prepare_enable(dev->clk);
125 if (ret) {
126 clk_put(dev->clk);
127 return ret;
128 }
129
130 atomic_io_modify(dev->reg + TIMER_CTRL,
131 WDT_AXP_FIXED_ENABLE_BIT,
132 WDT_AXP_FIXED_ENABLE_BIT);
133 dev->clk_rate = clk_get_rate(dev->clk);
134
135 return 0;
136 }
137
138 /* Mandatory fallback for proper devicetree backward compatibility */
139 dev->clk = clk_get(&pdev->dev, NULL);
140 if (IS_ERR(dev->clk))
141 return PTR_ERR(dev->clk);
142
143 ret = clk_prepare_enable(dev->clk);
144 if (ret) {
145 clk_put(dev->clk);
146 return ret;
147 }
148
149 atomic_io_modify(dev->reg + TIMER_CTRL,
150 WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT),
151 WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT));
152 dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO;
153
154 return 0;
155}
156
117static int armadaxp_wdt_clock_init(struct platform_device *pdev, 157static int armadaxp_wdt_clock_init(struct platform_device *pdev,
118 struct orion_watchdog *dev) 158 struct orion_watchdog *dev)
119{ 159{
@@ -394,7 +434,7 @@ static const struct orion_watchdog_data armada375_data = {
394 .rstout_mask_bit = BIT(10), 434 .rstout_mask_bit = BIT(10),
395 .wdt_enable_bit = BIT(8), 435 .wdt_enable_bit = BIT(8),
396 .wdt_counter_offset = 0x34, 436 .wdt_counter_offset = 0x34,
397 .clock_init = armada370_wdt_clock_init, 437 .clock_init = armada375_wdt_clock_init,
398 .enabled = armada375_enabled, 438 .enabled = armada375_enabled,
399 .start = armada375_start, 439 .start = armada375_start,
400 .stop = armada375_stop, 440 .stop = armada375_stop,