aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:31:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:31:18 -0400
commit6fa52ed33bea997374a88dbacbba5bf8c7ac4fef (patch)
treea0904b78d66c9b99d6acf944cf58bcaa0cffc511 /drivers/clocksource
parent1db772216f48978d5146b858586f6178433aad38 (diff)
parentbc8fd900c4d460b4e4bf785bb48bfced0ac9941b (diff)
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver changes from Olof Johansson: "This is a rather large set of patches for device drivers that for one reason or another the subsystem maintainer preferred to get merged through the arm-soc tree. There are both new drivers as well as existing drivers that are getting converted from platform-specific code into standalone drivers using the appropriate subsystem specific interfaces. In particular, we can now have pinctrl, clk, clksource and irqchip drivers in one file per driver, without the need to call into platform specific interface, or to get called from platform specific code, as long as all information about the hardware is provided through a device tree. Most of the drivers we touch this time are for clocksource. Since now most of them are part of drivers/clocksource, I expect that we won't have to touch these again from arm-soc and can let the clocksource maintainers take care of these in the future. Another larger part of this series is specific to the exynos platform, which is seeing some significant effort in upstreaming and modernization of its device drivers this time around, which unfortunately is also the cause for the churn and a lot of the merge conflicts. There is one new subsystem that gets merged as part of this series: the reset controller interface, which is a very simple interface for taking devices on the SoC out of reset or back into reset. Patches to use this interface on i.MX follow later in this merge window, and we are going to have other platforms (at least tegra and sirf) get converted in 3.11. This will let us get rid of platform specific callbacks in a number of platform independent device drivers." * tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (256 commits) irqchip: s3c24xx: add missing __init annotations ARM: dts: Disable the RTC by default on exynos5 clk: exynos5250: Fix parent clock for sclk_mmc{0,1,2,3} ARM: exynos: restore mach/regs-clock.h for exynos5 clocksource: exynos_mct: fix build error on non-DT pinctrl: vt8500: wmt: Fix checking return value of pinctrl_register() irqchip: vt8500: Convert arch-vt8500 to new irqchip infrastructure reset: NULL deref on allocation failure reset: Add reset controller API dt: describe base reset signal binding ARM: EXYNOS: Add arm-pmu DT binding for exynos421x ARM: EXYNOS: Add arm-pmu DT binding for exynos5250 ARM: EXYNOS: Enable PMUs for exynos4 irqchip: exynos-combiner: Correct combined IRQs for exynos4 irqchip: exynos-combiner: Add set_irq_affinity function for combiner_irq ARM: EXYNOS: fix compilation error introduced due to common clock migration clk: exynos5250: Fix divider values for sclk_mmc{0,1,2,3} clk: exynos4: export clocks required for fimc-is clk: samsung: Fix compilation error clk: tegra: fix enum tegra114_clk to match binding ...
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/Kconfig8
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/cadence_ttc_timer.c436
-rw-r--r--drivers/clocksource/em_sti.c13
-rw-r--r--drivers/clocksource/exynos_mct.c568
-rw-r--r--drivers/clocksource/sh_cmt.c189
-rw-r--r--drivers/clocksource/sh_mtu2.c2
-rw-r--r--drivers/clocksource/sh_tmu.c2
8 files changed, 1146 insertions, 74 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9002185a0a1a..7bc6e51757ee 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -31,6 +31,9 @@ config SUN4I_TIMER
31config VT8500_TIMER 31config VT8500_TIMER
32 bool 32 bool
33 33
34config CADENCE_TTC_TIMER
35 bool
36
34config CLKSRC_NOMADIK_MTU 37config CLKSRC_NOMADIK_MTU
35 bool 38 bool
36 depends on (ARCH_NOMADIK || ARCH_U8500) 39 depends on (ARCH_NOMADIK || ARCH_U8500)
@@ -67,3 +70,8 @@ config CLKSRC_METAG_GENERIC
67 def_bool y if METAG 70 def_bool y if METAG
68 help 71 help
69 This option enables support for the Meta per-thread timers. 72 This option enables support for the Meta per-thread timers.
73
74config CLKSRC_EXYNOS_MCT
75 def_bool y if ARCH_EXYNOS
76 help
77 Support for Multi Core Timer controller on Exynos SoCs.
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 682d48d08164..caacdb63aff9 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -23,6 +23,8 @@ obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
23obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o 23obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
24obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o 24obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
25obj-$(CONFIG_ARCH_BCM) += bcm_kona_timer.o 25obj-$(CONFIG_ARCH_BCM) += bcm_kona_timer.o
26obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
27obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
26 28
27obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 29obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
28obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o 30obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c
new file mode 100644
index 000000000000..685bc60e210a
--- /dev/null
+++ b/drivers/clocksource/cadence_ttc_timer.c
@@ -0,0 +1,436 @@
1/*
2 * This file contains driver for the Cadence Triple Timer Counter Rev 06
3 *
4 * Copyright (C) 2011-2013 Xilinx
5 *
6 * based on arch/mips/kernel/time.c timer driver
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/clk.h>
19#include <linux/interrupt.h>
20#include <linux/clockchips.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
23#include <linux/slab.h>
24#include <linux/clk-provider.h>
25
26/*
27 * This driver configures the 2 16-bit count-up timers as follows:
28 *
29 * T1: Timer 1, clocksource for generic timekeeping
30 * T2: Timer 2, clockevent source for hrtimers
31 * T3: Timer 3, <unused>
32 *
33 * The input frequency to the timer module for emulation is 2.5MHz which is
34 * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32,
35 * the timers are clocked at 78.125KHz (12.8 us resolution).
36
37 * The input frequency to the timer module in silicon is configurable and
38 * obtained from device tree. The pre-scaler of 32 is used.
39 */
40
41/*
42 * Timer Register Offset Definitions of Timer 1, Increment base address by 4
43 * and use same offsets for Timer 2
44 */
45#define TTC_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */
46#define TTC_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */
47#define TTC_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */
48#define TTC_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */
49#define TTC_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */
50#define TTC_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */
51
52#define TTC_CNT_CNTRL_DISABLE_MASK 0x1
53
54/*
55 * Setup the timers to use pre-scaling, using a fixed value for now that will
56 * work across most input frequency, but it may need to be more dynamic
57 */
58#define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */
59#define PRESCALE 2048 /* The exponent must match this */
60#define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1)
61#define CLK_CNTRL_PRESCALE_EN 1
62#define CNT_CNTRL_RESET (1 << 4)
63
64/**
65 * struct ttc_timer - This definition defines local timer structure
66 *
67 * @base_addr: Base address of timer
68 * @clk: Associated clock source
69 * @clk_rate_change_nb Notifier block for clock rate changes
70 */
71struct ttc_timer {
72 void __iomem *base_addr;
73 struct clk *clk;
74 struct notifier_block clk_rate_change_nb;
75};
76
77#define to_ttc_timer(x) \
78 container_of(x, struct ttc_timer, clk_rate_change_nb)
79
80struct ttc_timer_clocksource {
81 struct ttc_timer ttc;
82 struct clocksource cs;
83};
84
85#define to_ttc_timer_clksrc(x) \
86 container_of(x, struct ttc_timer_clocksource, cs)
87
88struct ttc_timer_clockevent {
89 struct ttc_timer ttc;
90 struct clock_event_device ce;
91};
92
93#define to_ttc_timer_clkevent(x) \
94 container_of(x, struct ttc_timer_clockevent, ce)
95
96/**
97 * ttc_set_interval - Set the timer interval value
98 *
99 * @timer: Pointer to the timer instance
100 * @cycles: Timer interval ticks
101 **/
102static void ttc_set_interval(struct ttc_timer *timer,
103 unsigned long cycles)
104{
105 u32 ctrl_reg;
106
107 /* Disable the counter, set the counter value and re-enable counter */
108 ctrl_reg = __raw_readl(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
109 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
110 __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
111
112 __raw_writel(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET);
113
114 /*
115 * Reset the counter (0x10) so that it starts from 0, one-shot
116 * mode makes this needed for timing to be right.
117 */
118 ctrl_reg |= CNT_CNTRL_RESET;
119 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
120 __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
121}
122
123/**
124 * ttc_clock_event_interrupt - Clock event timer interrupt handler
125 *
126 * @irq: IRQ number of the Timer
127 * @dev_id: void pointer to the ttc_timer instance
128 *
129 * returns: Always IRQ_HANDLED - success
130 **/
131static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id)
132{
133 struct ttc_timer_clockevent *ttce = dev_id;
134 struct ttc_timer *timer = &ttce->ttc;
135
136 /* Acknowledge the interrupt and call event handler */
137 __raw_readl(timer->base_addr + TTC_ISR_OFFSET);
138
139 ttce->ce.event_handler(&ttce->ce);
140
141 return IRQ_HANDLED;
142}
143
144/**
145 * __ttc_clocksource_read - Reads the timer counter register
146 *
147 * returns: Current timer counter register value
148 **/
149static cycle_t __ttc_clocksource_read(struct clocksource *cs)
150{
151 struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
152
153 return (cycle_t)__raw_readl(timer->base_addr +
154 TTC_COUNT_VAL_OFFSET);
155}
156
157/**
158 * ttc_set_next_event - Sets the time interval for next event
159 *
160 * @cycles: Timer interval ticks
161 * @evt: Address of clock event instance
162 *
163 * returns: Always 0 - success
164 **/
165static int ttc_set_next_event(unsigned long cycles,
166 struct clock_event_device *evt)
167{
168 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
169 struct ttc_timer *timer = &ttce->ttc;
170
171 ttc_set_interval(timer, cycles);
172 return 0;
173}
174
175/**
176 * ttc_set_mode - Sets the mode of timer
177 *
178 * @mode: Mode to be set
179 * @evt: Address of clock event instance
180 **/
181static void ttc_set_mode(enum clock_event_mode mode,
182 struct clock_event_device *evt)
183{
184 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
185 struct ttc_timer *timer = &ttce->ttc;
186 u32 ctrl_reg;
187
188 switch (mode) {
189 case CLOCK_EVT_MODE_PERIODIC:
190 ttc_set_interval(timer,
191 DIV_ROUND_CLOSEST(clk_get_rate(ttce->ttc.clk),
192 PRESCALE * HZ));
193 break;
194 case CLOCK_EVT_MODE_ONESHOT:
195 case CLOCK_EVT_MODE_UNUSED:
196 case CLOCK_EVT_MODE_SHUTDOWN:
197 ctrl_reg = __raw_readl(timer->base_addr +
198 TTC_CNT_CNTRL_OFFSET);
199 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
200 __raw_writel(ctrl_reg,
201 timer->base_addr + TTC_CNT_CNTRL_OFFSET);
202 break;
203 case CLOCK_EVT_MODE_RESUME:
204 ctrl_reg = __raw_readl(timer->base_addr +
205 TTC_CNT_CNTRL_OFFSET);
206 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
207 __raw_writel(ctrl_reg,
208 timer->base_addr + TTC_CNT_CNTRL_OFFSET);
209 break;
210 }
211}
212
213static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
214 unsigned long event, void *data)
215{
216 struct clk_notifier_data *ndata = data;
217 struct ttc_timer *ttc = to_ttc_timer(nb);
218 struct ttc_timer_clocksource *ttccs = container_of(ttc,
219 struct ttc_timer_clocksource, ttc);
220
221 switch (event) {
222 case POST_RATE_CHANGE:
223 /*
224 * Do whatever is necessary to maintain a proper time base
225 *
226 * I cannot find a way to adjust the currently used clocksource
227 * to the new frequency. __clocksource_updatefreq_hz() sounds
228 * good, but does not work. Not sure what's that missing.
229 *
230 * This approach works, but triggers two clocksource switches.
231 * The first after unregister to clocksource jiffies. And
232 * another one after the register to the newly registered timer.
233 *
234 * Alternatively we could 'waste' another HW timer to ping pong
235 * between clock sources. That would also use one register and
236 * one unregister call, but only trigger one clocksource switch
237 * for the cost of another HW timer used by the OS.
238 */
239 clocksource_unregister(&ttccs->cs);
240 clocksource_register_hz(&ttccs->cs,
241 ndata->new_rate / PRESCALE);
242 /* fall through */
243 case PRE_RATE_CHANGE:
244 case ABORT_RATE_CHANGE:
245 default:
246 return NOTIFY_DONE;
247 }
248}
249
250static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base)
251{
252 struct ttc_timer_clocksource *ttccs;
253 int err;
254
255 ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL);
256 if (WARN_ON(!ttccs))
257 return;
258
259 ttccs->ttc.clk = clk;
260
261 err = clk_prepare_enable(ttccs->ttc.clk);
262 if (WARN_ON(err)) {
263 kfree(ttccs);
264 return;
265 }
266
267 ttccs->ttc.clk_rate_change_nb.notifier_call =
268 ttc_rate_change_clocksource_cb;
269 ttccs->ttc.clk_rate_change_nb.next = NULL;
270 if (clk_notifier_register(ttccs->ttc.clk,
271 &ttccs->ttc.clk_rate_change_nb))
272 pr_warn("Unable to register clock notifier.\n");
273
274 ttccs->ttc.base_addr = base;
275 ttccs->cs.name = "ttc_clocksource";
276 ttccs->cs.rating = 200;
277 ttccs->cs.read = __ttc_clocksource_read;
278 ttccs->cs.mask = CLOCKSOURCE_MASK(16);
279 ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
280
281 /*
282 * Setup the clock source counter to be an incrementing counter
283 * with no interrupt and it rolls over at 0xFFFF. Pre-scale
284 * it by 32 also. Let it start running now.
285 */
286 __raw_writel(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET);
287 __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
288 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
289 __raw_writel(CNT_CNTRL_RESET,
290 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
291
292 err = clocksource_register_hz(&ttccs->cs,
293 clk_get_rate(ttccs->ttc.clk) / PRESCALE);
294 if (WARN_ON(err)) {
295 kfree(ttccs);
296 return;
297 }
298}
299
300static int ttc_rate_change_clockevent_cb(struct notifier_block *nb,
301 unsigned long event, void *data)
302{
303 struct clk_notifier_data *ndata = data;
304 struct ttc_timer *ttc = to_ttc_timer(nb);
305 struct ttc_timer_clockevent *ttcce = container_of(ttc,
306 struct ttc_timer_clockevent, ttc);
307
308 switch (event) {
309 case POST_RATE_CHANGE:
310 {
311 unsigned long flags;
312
313 /*
314 * clockevents_update_freq should be called with IRQ disabled on
315 * the CPU the timer provides events for. The timer we use is
316 * common to both CPUs, not sure if we need to run on both
317 * cores.
318 */
319 local_irq_save(flags);
320 clockevents_update_freq(&ttcce->ce,
321 ndata->new_rate / PRESCALE);
322 local_irq_restore(flags);
323
324 /* fall through */
325 }
326 case PRE_RATE_CHANGE:
327 case ABORT_RATE_CHANGE:
328 default:
329 return NOTIFY_DONE;
330 }
331}
332
333static void __init ttc_setup_clockevent(struct clk *clk,
334 void __iomem *base, u32 irq)
335{
336 struct ttc_timer_clockevent *ttcce;
337 int err;
338
339 ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL);
340 if (WARN_ON(!ttcce))
341 return;
342
343 ttcce->ttc.clk = clk;
344
345 err = clk_prepare_enable(ttcce->ttc.clk);
346 if (WARN_ON(err)) {
347 kfree(ttcce);
348 return;
349 }
350
351 ttcce->ttc.clk_rate_change_nb.notifier_call =
352 ttc_rate_change_clockevent_cb;
353 ttcce->ttc.clk_rate_change_nb.next = NULL;
354 if (clk_notifier_register(ttcce->ttc.clk,
355 &ttcce->ttc.clk_rate_change_nb))
356 pr_warn("Unable to register clock notifier.\n");
357
358 ttcce->ttc.base_addr = base;
359 ttcce->ce.name = "ttc_clockevent";
360 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
361 ttcce->ce.set_next_event = ttc_set_next_event;
362 ttcce->ce.set_mode = ttc_set_mode;
363 ttcce->ce.rating = 200;
364 ttcce->ce.irq = irq;
365 ttcce->ce.cpumask = cpu_possible_mask;
366
367 /*
368 * Setup the clock event timer to be an interval timer which
369 * is prescaled by 32 using the interval interrupt. Leave it
370 * disabled for now.
371 */
372 __raw_writel(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
373 __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
374 ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
375 __raw_writel(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET);
376
377 err = request_irq(irq, ttc_clock_event_interrupt,
378 IRQF_DISABLED | IRQF_TIMER,
379 ttcce->ce.name, ttcce);
380 if (WARN_ON(err)) {
381 kfree(ttcce);
382 return;
383 }
384
385 clockevents_config_and_register(&ttcce->ce,
386 clk_get_rate(ttcce->ttc.clk) / PRESCALE, 1, 0xfffe);
387}
388
389/**
390 * ttc_timer_init - Initialize the timer
391 *
392 * Initializes the timer hardware and register the clock source and clock event
393 * timers with Linux kernal timer framework
394 */
395static void __init ttc_timer_init(struct device_node *timer)
396{
397 unsigned int irq;
398 void __iomem *timer_baseaddr;
399 struct clk *clk;
400 static int initialized;
401
402 if (initialized)
403 return;
404
405 initialized = 1;
406
407 /*
408 * Get the 1st Triple Timer Counter (TTC) block from the device tree
409 * and use it. Note that the event timer uses the interrupt and it's the
410 * 2nd TTC hence the irq_of_parse_and_map(,1)
411 */
412 timer_baseaddr = of_iomap(timer, 0);
413 if (!timer_baseaddr) {
414 pr_err("ERROR: invalid timer base address\n");
415 BUG();
416 }
417
418 irq = irq_of_parse_and_map(timer, 1);
419 if (irq <= 0) {
420 pr_err("ERROR: invalid interrupt number\n");
421 BUG();
422 }
423
424 clk = of_clk_get_by_name(timer, "cpu_1x");
425 if (IS_ERR(clk)) {
426 pr_err("ERROR: timer input clock not found\n");
427 BUG();
428 }
429
430 ttc_setup_clocksource(clk, timer_baseaddr);
431 ttc_setup_clockevent(clk, timer_baseaddr + 4, irq);
432
433 pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq);
434}
435
436CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init);
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
index e6a553cb73e8..4329a29a5310 100644
--- a/drivers/clocksource/em_sti.c
+++ b/drivers/clocksource/em_sti.c
@@ -399,7 +399,18 @@ static struct platform_driver em_sti_device_driver = {
399 } 399 }
400}; 400};
401 401
402module_platform_driver(em_sti_device_driver); 402static int __init em_sti_init(void)
403{
404 return platform_driver_register(&em_sti_device_driver);
405}
406
407static void __exit em_sti_exit(void)
408{
409 platform_driver_unregister(&em_sti_device_driver);
410}
411
412subsys_initcall(em_sti_init);
413module_exit(em_sti_exit);
403 414
404MODULE_AUTHOR("Magnus Damm"); 415MODULE_AUTHOR("Magnus Damm");
405MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver"); 416MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver");
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
new file mode 100644
index 000000000000..661026834b23
--- /dev/null
+++ b/drivers/clocksource/exynos_mct.c
@@ -0,0 +1,568 @@
1/* linux/arch/arm/mach-exynos4/mct.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 MCT(Multi-Core Timer) support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/sched.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/err.h>
17#include <linux/clk.h>
18#include <linux/clockchips.h>
19#include <linux/platform_device.h>
20#include <linux/delay.h>
21#include <linux/percpu.h>
22#include <linux/of.h>
23#include <linux/of_irq.h>
24#include <linux/of_address.h>
25#include <linux/clocksource.h>
26
27#include <asm/arch_timer.h>
28#include <asm/localtimer.h>
29
30#include <plat/cpu.h>
31
32#include <mach/map.h>
33#include <mach/irqs.h>
34#include <asm/mach/time.h>
35
36#define EXYNOS4_MCTREG(x) (x)
37#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
38#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104)
39#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110)
40#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200)
41#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204)
42#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208)
43#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240)
44#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244)
45#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248)
46#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C)
47#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300)
48#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x))
49#define EXYNOS4_MCT_L_MASK (0xffffff00)
50
51#define MCT_L_TCNTB_OFFSET (0x00)
52#define MCT_L_ICNTB_OFFSET (0x08)
53#define MCT_L_TCON_OFFSET (0x20)
54#define MCT_L_INT_CSTAT_OFFSET (0x30)
55#define MCT_L_INT_ENB_OFFSET (0x34)
56#define MCT_L_WSTAT_OFFSET (0x40)
57#define MCT_G_TCON_START (1 << 8)
58#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1)
59#define MCT_G_TCON_COMP0_ENABLE (1 << 0)
60#define MCT_L_TCON_INTERVAL_MODE (1 << 2)
61#define MCT_L_TCON_INT_START (1 << 1)
62#define MCT_L_TCON_TIMER_START (1 << 0)
63
64#define TICK_BASE_CNT 1
65
66enum {
67 MCT_INT_SPI,
68 MCT_INT_PPI
69};
70
71enum {
72 MCT_G0_IRQ,
73 MCT_G1_IRQ,
74 MCT_G2_IRQ,
75 MCT_G3_IRQ,
76 MCT_L0_IRQ,
77 MCT_L1_IRQ,
78 MCT_L2_IRQ,
79 MCT_L3_IRQ,
80 MCT_NR_IRQS,
81};
82
83static void __iomem *reg_base;
84static unsigned long clk_rate;
85static unsigned int mct_int_type;
86static int mct_irqs[MCT_NR_IRQS];
87
88struct mct_clock_event_device {
89 struct clock_event_device *evt;
90 unsigned long base;
91 char name[10];
92};
93
94static void exynos4_mct_write(unsigned int value, unsigned long offset)
95{
96 unsigned long stat_addr;
97 u32 mask;
98 u32 i;
99
100 __raw_writel(value, reg_base + offset);
101
102 if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) {
103 stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET;
104 switch (offset & EXYNOS4_MCT_L_MASK) {
105 case MCT_L_TCON_OFFSET:
106 mask = 1 << 3; /* L_TCON write status */
107 break;
108 case MCT_L_ICNTB_OFFSET:
109 mask = 1 << 1; /* L_ICNTB write status */
110 break;
111 case MCT_L_TCNTB_OFFSET:
112 mask = 1 << 0; /* L_TCNTB write status */
113 break;
114 default:
115 return;
116 }
117 } else {
118 switch (offset) {
119 case EXYNOS4_MCT_G_TCON:
120 stat_addr = EXYNOS4_MCT_G_WSTAT;
121 mask = 1 << 16; /* G_TCON write status */
122 break;
123 case EXYNOS4_MCT_G_COMP0_L:
124 stat_addr = EXYNOS4_MCT_G_WSTAT;
125 mask = 1 << 0; /* G_COMP0_L write status */
126 break;
127 case EXYNOS4_MCT_G_COMP0_U:
128 stat_addr = EXYNOS4_MCT_G_WSTAT;
129 mask = 1 << 1; /* G_COMP0_U write status */
130 break;
131 case EXYNOS4_MCT_G_COMP0_ADD_INCR:
132 stat_addr = EXYNOS4_MCT_G_WSTAT;
133 mask = 1 << 2; /* G_COMP0_ADD_INCR w status */
134 break;
135 case EXYNOS4_MCT_G_CNT_L:
136 stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
137 mask = 1 << 0; /* G_CNT_L write status */
138 break;
139 case EXYNOS4_MCT_G_CNT_U:
140 stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
141 mask = 1 << 1; /* G_CNT_U write status */
142 break;
143 default:
144 return;
145 }
146 }
147
148 /* Wait maximum 1 ms until written values are applied */
149 for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
150 if (__raw_readl(reg_base + stat_addr) & mask) {
151 __raw_writel(mask, reg_base + stat_addr);
152 return;
153 }
154
155 panic("MCT hangs after writing %d (offset:0x%lx)\n", value, offset);
156}
157
158/* Clocksource handling */
159static void exynos4_mct_frc_start(u32 hi, u32 lo)
160{
161 u32 reg;
162
163 exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
164 exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
165
166 reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
167 reg |= MCT_G_TCON_START;
168 exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
169}
170
171static cycle_t exynos4_frc_read(struct clocksource *cs)
172{
173 unsigned int lo, hi;
174 u32 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U);
175
176 do {
177 hi = hi2;
178 lo = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_L);
179 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U);
180 } while (hi != hi2);
181
182 return ((cycle_t)hi << 32) | lo;
183}
184
185static void exynos4_frc_resume(struct clocksource *cs)
186{
187 exynos4_mct_frc_start(0, 0);
188}
189
190struct clocksource mct_frc = {
191 .name = "mct-frc",
192 .rating = 400,
193 .read = exynos4_frc_read,
194 .mask = CLOCKSOURCE_MASK(64),
195 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
196 .resume = exynos4_frc_resume,
197};
198
199static void __init exynos4_clocksource_init(void)
200{
201 exynos4_mct_frc_start(0, 0);
202
203 if (clocksource_register_hz(&mct_frc, clk_rate))
204 panic("%s: can't register clocksource\n", mct_frc.name);
205}
206
207static void exynos4_mct_comp0_stop(void)
208{
209 unsigned int tcon;
210
211 tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
212 tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
213
214 exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
215 exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
216}
217
218static void exynos4_mct_comp0_start(enum clock_event_mode mode,
219 unsigned long cycles)
220{
221 unsigned int tcon;
222 cycle_t comp_cycle;
223
224 tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
225
226 if (mode == CLOCK_EVT_MODE_PERIODIC) {
227 tcon |= MCT_G_TCON_COMP0_AUTO_INC;
228 exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
229 }
230
231 comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
232 exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
233 exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
234
235 exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
236
237 tcon |= MCT_G_TCON_COMP0_ENABLE;
238 exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
239}
240
241static int exynos4_comp_set_next_event(unsigned long cycles,
242 struct clock_event_device *evt)
243{
244 exynos4_mct_comp0_start(evt->mode, cycles);
245
246 return 0;
247}
248
249static void exynos4_comp_set_mode(enum clock_event_mode mode,
250 struct clock_event_device *evt)
251{
252 unsigned long cycles_per_jiffy;
253 exynos4_mct_comp0_stop();
254
255 switch (mode) {
256 case CLOCK_EVT_MODE_PERIODIC:
257 cycles_per_jiffy =
258 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
259 exynos4_mct_comp0_start(mode, cycles_per_jiffy);
260 break;
261
262 case CLOCK_EVT_MODE_ONESHOT:
263 case CLOCK_EVT_MODE_UNUSED:
264 case CLOCK_EVT_MODE_SHUTDOWN:
265 case CLOCK_EVT_MODE_RESUME:
266 break;
267 }
268}
269
270static struct clock_event_device mct_comp_device = {
271 .name = "mct-comp",
272 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
273 .rating = 250,
274 .set_next_event = exynos4_comp_set_next_event,
275 .set_mode = exynos4_comp_set_mode,
276};
277
278static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
279{
280 struct clock_event_device *evt = dev_id;
281
282 exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
283
284 evt->event_handler(evt);
285
286 return IRQ_HANDLED;
287}
288
289static struct irqaction mct_comp_event_irq = {
290 .name = "mct_comp_irq",
291 .flags = IRQF_TIMER | IRQF_IRQPOLL,
292 .handler = exynos4_mct_comp_isr,
293 .dev_id = &mct_comp_device,
294};
295
296static void exynos4_clockevent_init(void)
297{
298 mct_comp_device.cpumask = cpumask_of(0);
299 clockevents_config_and_register(&mct_comp_device, clk_rate,
300 0xf, 0xffffffff);
301 setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq);
302}
303
304#ifdef CONFIG_LOCAL_TIMERS
305
306static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
307
308/* Clock event handling */
309static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
310{
311 unsigned long tmp;
312 unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
313 unsigned long offset = mevt->base + MCT_L_TCON_OFFSET;
314
315 tmp = __raw_readl(reg_base + offset);
316 if (tmp & mask) {
317 tmp &= ~mask;
318 exynos4_mct_write(tmp, offset);
319 }
320}
321
322static void exynos4_mct_tick_start(unsigned long cycles,
323 struct mct_clock_event_device *mevt)
324{
325 unsigned long tmp;
326
327 exynos4_mct_tick_stop(mevt);
328
329 tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */
330
331 /* update interrupt count buffer */
332 exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
333
334 /* enable MCT tick interrupt */
335 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
336
337 tmp = __raw_readl(reg_base + mevt->base + MCT_L_TCON_OFFSET);
338 tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
339 MCT_L_TCON_INTERVAL_MODE;
340 exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
341}
342
343static int exynos4_tick_set_next_event(unsigned long cycles,
344 struct clock_event_device *evt)
345{
346 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
347
348 exynos4_mct_tick_start(cycles, mevt);
349
350 return 0;
351}
352
353static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
354 struct clock_event_device *evt)
355{
356 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
357 unsigned long cycles_per_jiffy;
358
359 exynos4_mct_tick_stop(mevt);
360
361 switch (mode) {
362 case CLOCK_EVT_MODE_PERIODIC:
363 cycles_per_jiffy =
364 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
365 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
366 break;
367
368 case CLOCK_EVT_MODE_ONESHOT:
369 case CLOCK_EVT_MODE_UNUSED:
370 case CLOCK_EVT_MODE_SHUTDOWN:
371 case CLOCK_EVT_MODE_RESUME:
372 break;
373 }
374}
375
376static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
377{
378 struct clock_event_device *evt = mevt->evt;
379
380 /*
381 * This is for supporting oneshot mode.
382 * Mct would generate interrupt periodically
383 * without explicit stopping.
384 */
385 if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
386 exynos4_mct_tick_stop(mevt);
387
388 /* Clear the MCT tick interrupt */
389 if (__raw_readl(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
390 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
391 return 1;
392 } else {
393 return 0;
394 }
395}
396
397static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
398{
399 struct mct_clock_event_device *mevt = dev_id;
400 struct clock_event_device *evt = mevt->evt;
401
402 exynos4_mct_tick_clear(mevt);
403
404 evt->event_handler(evt);
405
406 return IRQ_HANDLED;
407}
408
409static struct irqaction mct_tick0_event_irq = {
410 .name = "mct_tick0_irq",
411 .flags = IRQF_TIMER | IRQF_NOBALANCING,
412 .handler = exynos4_mct_tick_isr,
413};
414
415static struct irqaction mct_tick1_event_irq = {
416 .name = "mct_tick1_irq",
417 .flags = IRQF_TIMER | IRQF_NOBALANCING,
418 .handler = exynos4_mct_tick_isr,
419};
420
421static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
422{
423 struct mct_clock_event_device *mevt;
424 unsigned int cpu = smp_processor_id();
425
426 mevt = this_cpu_ptr(&percpu_mct_tick);
427 mevt->evt = evt;
428
429 mevt->base = EXYNOS4_MCT_L_BASE(cpu);
430 sprintf(mevt->name, "mct_tick%d", cpu);
431
432 evt->name = mevt->name;
433 evt->cpumask = cpumask_of(cpu);
434 evt->set_next_event = exynos4_tick_set_next_event;
435 evt->set_mode = exynos4_tick_set_mode;
436 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
437 evt->rating = 450;
438 clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
439 0xf, 0x7fffffff);
440
441 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
442
443 if (mct_int_type == MCT_INT_SPI) {
444 if (cpu == 0) {
445 mct_tick0_event_irq.dev_id = mevt;
446 evt->irq = mct_irqs[MCT_L0_IRQ];
447 setup_irq(evt->irq, &mct_tick0_event_irq);
448 } else {
449 mct_tick1_event_irq.dev_id = mevt;
450 evt->irq = mct_irqs[MCT_L1_IRQ];
451 setup_irq(evt->irq, &mct_tick1_event_irq);
452 irq_set_affinity(evt->irq, cpumask_of(1));
453 }
454 } else {
455 enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
456 }
457
458 return 0;
459}
460
461static void exynos4_local_timer_stop(struct clock_event_device *evt)
462{
463 unsigned int cpu = smp_processor_id();
464 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
465 if (mct_int_type == MCT_INT_SPI)
466 if (cpu == 0)
467 remove_irq(evt->irq, &mct_tick0_event_irq);
468 else
469 remove_irq(evt->irq, &mct_tick1_event_irq);
470 else
471 disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
472}
473
474static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
475 .setup = exynos4_local_timer_setup,
476 .stop = exynos4_local_timer_stop,
477};
478#endif /* CONFIG_LOCAL_TIMERS */
479
480static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
481{
482 struct clk *mct_clk, *tick_clk;
483
484 tick_clk = np ? of_clk_get_by_name(np, "fin_pll") :
485 clk_get(NULL, "fin_pll");
486 if (IS_ERR(tick_clk))
487 panic("%s: unable to determine tick clock rate\n", __func__);
488 clk_rate = clk_get_rate(tick_clk);
489
490 mct_clk = np ? of_clk_get_by_name(np, "mct") : clk_get(NULL, "mct");
491 if (IS_ERR(mct_clk))
492 panic("%s: unable to retrieve mct clock instance\n", __func__);
493 clk_prepare_enable(mct_clk);
494
495 reg_base = base;
496 if (!reg_base)
497 panic("%s: unable to ioremap mct address space\n", __func__);
498
499#ifdef CONFIG_LOCAL_TIMERS
500 if (mct_int_type == MCT_INT_PPI) {
501 int err;
502
503 err = request_percpu_irq(mct_irqs[MCT_L0_IRQ],
504 exynos4_mct_tick_isr, "MCT",
505 &percpu_mct_tick);
506 WARN(err, "MCT: can't request IRQ %d (%d)\n",
507 mct_irqs[MCT_L0_IRQ], err);
508 }
509
510 local_timer_register(&exynos4_mct_tick_ops);
511#endif /* CONFIG_LOCAL_TIMERS */
512}
513
514void __init mct_init(void)
515{
516 if (soc_is_exynos4210()) {
517 mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0;
518 mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0;
519 mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1;
520 mct_int_type = MCT_INT_SPI;
521 } else {
522 panic("unable to determine mct controller type\n");
523 }
524
525 exynos4_timer_resources(NULL, S5P_VA_SYSTIMER);
526 exynos4_clocksource_init();
527 exynos4_clockevent_init();
528}
529
530static void __init mct_init_dt(struct device_node *np, unsigned int int_type)
531{
532 u32 nr_irqs, i;
533
534 mct_int_type = int_type;
535
536 /* This driver uses only one global timer interrupt */
537 mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
538
539 /*
540 * Find out the number of local irqs specified. The local
541 * timer irqs are specified after the four global timer
542 * irqs are specified.
543 */
544#ifdef CONFIG_OF
545 nr_irqs = of_irq_count(np);
546#else
547 nr_irqs = 0;
548#endif
549 for (i = MCT_L0_IRQ; i < nr_irqs; i++)
550 mct_irqs[i] = irq_of_parse_and_map(np, i);
551
552 exynos4_timer_resources(np, of_iomap(np, 0));
553 exynos4_clocksource_init();
554 exynos4_clockevent_init();
555}
556
557
558static void __init mct_init_spi(struct device_node *np)
559{
560 return mct_init_dt(np, MCT_INT_SPI);
561}
562
563static void __init mct_init_ppi(struct device_node *np)
564{
565 return mct_init_dt(np, MCT_INT_PPI);
566}
567CLOCKSOURCE_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
568CLOCKSOURCE_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 488c14cc8dbf..08d0c418c94a 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -54,62 +54,100 @@ struct sh_cmt_priv {
54 struct clocksource cs; 54 struct clocksource cs;
55 unsigned long total_cycles; 55 unsigned long total_cycles;
56 bool cs_enabled; 56 bool cs_enabled;
57
58 /* callbacks for CMSTR and CMCSR access */
59 unsigned long (*read_control)(void __iomem *base, unsigned long offs);
60 void (*write_control)(void __iomem *base, unsigned long offs,
61 unsigned long value);
62
63 /* callbacks for CMCNT and CMCOR access */
64 unsigned long (*read_count)(void __iomem *base, unsigned long offs);
65 void (*write_count)(void __iomem *base, unsigned long offs,
66 unsigned long value);
57}; 67};
58 68
59static DEFINE_RAW_SPINLOCK(sh_cmt_lock); 69/* Examples of supported CMT timer register layouts and I/O access widths:
70 *
71 * "16-bit counter and 16-bit control" as found on sh7263:
72 * CMSTR 0xfffec000 16-bit
73 * CMCSR 0xfffec002 16-bit
74 * CMCNT 0xfffec004 16-bit
75 * CMCOR 0xfffec006 16-bit
76 *
77 * "32-bit counter and 16-bit control" as found on sh7372, sh73a0, r8a7740:
78 * CMSTR 0xffca0000 16-bit
79 * CMCSR 0xffca0060 16-bit
80 * CMCNT 0xffca0064 32-bit
81 * CMCOR 0xffca0068 32-bit
82 */
83
84static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
85{
86 return ioread16(base + (offs << 1));
87}
88
89static unsigned long sh_cmt_read32(void __iomem *base, unsigned long offs)
90{
91 return ioread32(base + (offs << 2));
92}
93
94static void sh_cmt_write16(void __iomem *base, unsigned long offs,
95 unsigned long value)
96{
97 iowrite16(value, base + (offs << 1));
98}
99
100static void sh_cmt_write32(void __iomem *base, unsigned long offs,
101 unsigned long value)
102{
103 iowrite32(value, base + (offs << 2));
104}
60 105
61#define CMSTR -1 /* shared register */
62#define CMCSR 0 /* channel register */ 106#define CMCSR 0 /* channel register */
63#define CMCNT 1 /* channel register */ 107#define CMCNT 1 /* channel register */
64#define CMCOR 2 /* channel register */ 108#define CMCOR 2 /* channel register */
65 109
66static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) 110static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
67{ 111{
68 struct sh_timer_config *cfg = p->pdev->dev.platform_data; 112 struct sh_timer_config *cfg = p->pdev->dev.platform_data;
69 void __iomem *base = p->mapbase;
70 unsigned long offs;
71
72 if (reg_nr == CMSTR) {
73 offs = 0;
74 base -= cfg->channel_offset;
75 } else
76 offs = reg_nr;
77
78 if (p->width == 16)
79 offs <<= 1;
80 else {
81 offs <<= 2;
82 if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
83 return ioread32(base + offs);
84 }
85 113
86 return ioread16(base + offs); 114 return p->read_control(p->mapbase - cfg->channel_offset, 0);
87} 115}
88 116
89static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, 117static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
90 unsigned long value) 118{
119 return p->read_control(p->mapbase, CMCSR);
120}
121
122static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
123{
124 return p->read_count(p->mapbase, CMCNT);
125}
126
127static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
128 unsigned long value)
91{ 129{
92 struct sh_timer_config *cfg = p->pdev->dev.platform_data; 130 struct sh_timer_config *cfg = p->pdev->dev.platform_data;
93 void __iomem *base = p->mapbase;
94 unsigned long offs;
95
96 if (reg_nr == CMSTR) {
97 offs = 0;
98 base -= cfg->channel_offset;
99 } else
100 offs = reg_nr;
101
102 if (p->width == 16)
103 offs <<= 1;
104 else {
105 offs <<= 2;
106 if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
107 iowrite32(value, base + offs);
108 return;
109 }
110 }
111 131
112 iowrite16(value, base + offs); 132 p->write_control(p->mapbase - cfg->channel_offset, 0, value);
133}
134
135static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
136 unsigned long value)
137{
138 p->write_control(p->mapbase, CMCSR, value);
139}
140
141static inline void sh_cmt_write_cmcnt(struct sh_cmt_priv *p,
142 unsigned long value)
143{
144 p->write_count(p->mapbase, CMCNT, value);
145}
146
147static inline void sh_cmt_write_cmcor(struct sh_cmt_priv *p,
148 unsigned long value)
149{
150 p->write_count(p->mapbase, CMCOR, value);
113} 151}
114 152
115static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, 153static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
@@ -118,15 +156,15 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
118 unsigned long v1, v2, v3; 156 unsigned long v1, v2, v3;
119 int o1, o2; 157 int o1, o2;
120 158
121 o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; 159 o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
122 160
123 /* Make sure the timer value is stable. Stolen from acpi_pm.c */ 161 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
124 do { 162 do {
125 o2 = o1; 163 o2 = o1;
126 v1 = sh_cmt_read(p, CMCNT); 164 v1 = sh_cmt_read_cmcnt(p);
127 v2 = sh_cmt_read(p, CMCNT); 165 v2 = sh_cmt_read_cmcnt(p);
128 v3 = sh_cmt_read(p, CMCNT); 166 v3 = sh_cmt_read_cmcnt(p);
129 o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; 167 o1 = sh_cmt_read_cmcsr(p) & p->overflow_bit;
130 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) 168 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
131 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); 169 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
132 170
@@ -134,6 +172,7 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
134 return v2; 172 return v2;
135} 173}
136 174
175static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
137 176
138static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) 177static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
139{ 178{
@@ -142,14 +181,14 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
142 181
143 /* start stop register shared by multiple timer channels */ 182 /* start stop register shared by multiple timer channels */
144 raw_spin_lock_irqsave(&sh_cmt_lock, flags); 183 raw_spin_lock_irqsave(&sh_cmt_lock, flags);
145 value = sh_cmt_read(p, CMSTR); 184 value = sh_cmt_read_cmstr(p);
146 185
147 if (start) 186 if (start)
148 value |= 1 << cfg->timer_bit; 187 value |= 1 << cfg->timer_bit;
149 else 188 else
150 value &= ~(1 << cfg->timer_bit); 189 value &= ~(1 << cfg->timer_bit);
151 190
152 sh_cmt_write(p, CMSTR, value); 191 sh_cmt_write_cmstr(p, value);
153 raw_spin_unlock_irqrestore(&sh_cmt_lock, flags); 192 raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
154} 193}
155 194
@@ -173,14 +212,14 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
173 /* configure channel, periodic mode and maximum timeout */ 212 /* configure channel, periodic mode and maximum timeout */
174 if (p->width == 16) { 213 if (p->width == 16) {
175 *rate = clk_get_rate(p->clk) / 512; 214 *rate = clk_get_rate(p->clk) / 512;
176 sh_cmt_write(p, CMCSR, 0x43); 215 sh_cmt_write_cmcsr(p, 0x43);
177 } else { 216 } else {
178 *rate = clk_get_rate(p->clk) / 8; 217 *rate = clk_get_rate(p->clk) / 8;
179 sh_cmt_write(p, CMCSR, 0x01a4); 218 sh_cmt_write_cmcsr(p, 0x01a4);
180 } 219 }
181 220
182 sh_cmt_write(p, CMCOR, 0xffffffff); 221 sh_cmt_write_cmcor(p, 0xffffffff);
183 sh_cmt_write(p, CMCNT, 0); 222 sh_cmt_write_cmcnt(p, 0);
184 223
185 /* 224 /*
186 * According to the sh73a0 user's manual, as CMCNT can be operated 225 * According to the sh73a0 user's manual, as CMCNT can be operated
@@ -194,12 +233,12 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
194 * take RCLKx2 at maximum. 233 * take RCLKx2 at maximum.
195 */ 234 */
196 for (k = 0; k < 100; k++) { 235 for (k = 0; k < 100; k++) {
197 if (!sh_cmt_read(p, CMCNT)) 236 if (!sh_cmt_read_cmcnt(p))
198 break; 237 break;
199 udelay(1); 238 udelay(1);
200 } 239 }
201 240
202 if (sh_cmt_read(p, CMCNT)) { 241 if (sh_cmt_read_cmcnt(p)) {
203 dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); 242 dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
204 ret = -ETIMEDOUT; 243 ret = -ETIMEDOUT;
205 goto err1; 244 goto err1;
@@ -222,7 +261,7 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
222 sh_cmt_start_stop_ch(p, 0); 261 sh_cmt_start_stop_ch(p, 0);
223 262
224 /* disable interrupts in CMT block */ 263 /* disable interrupts in CMT block */
225 sh_cmt_write(p, CMCSR, 0); 264 sh_cmt_write_cmcsr(p, 0);
226 265
227 /* stop clock */ 266 /* stop clock */
228 clk_disable(p->clk); 267 clk_disable(p->clk);
@@ -270,7 +309,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
270 if (new_match > p->max_match_value) 309 if (new_match > p->max_match_value)
271 new_match = p->max_match_value; 310 new_match = p->max_match_value;
272 311
273 sh_cmt_write(p, CMCOR, new_match); 312 sh_cmt_write_cmcor(p, new_match);
274 313
275 now = sh_cmt_get_counter(p, &has_wrapped); 314 now = sh_cmt_get_counter(p, &has_wrapped);
276 if (has_wrapped && (new_match > p->match_value)) { 315 if (has_wrapped && (new_match > p->match_value)) {
@@ -346,7 +385,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
346 struct sh_cmt_priv *p = dev_id; 385 struct sh_cmt_priv *p = dev_id;
347 386
348 /* clear flags */ 387 /* clear flags */
349 sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits); 388 sh_cmt_write_cmcsr(p, sh_cmt_read_cmcsr(p) & p->clear_bits);
350 389
351 /* update clock source counter to begin with if enabled 390 /* update clock source counter to begin with if enabled
352 * the wrap flag should be cleared by the timer specific 391 * the wrap flag should be cleared by the timer specific
@@ -625,14 +664,6 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
625 unsigned long clockevent_rating, 664 unsigned long clockevent_rating,
626 unsigned long clocksource_rating) 665 unsigned long clocksource_rating)
627{ 666{
628 if (p->width == (sizeof(p->max_match_value) * 8))
629 p->max_match_value = ~0;
630 else
631 p->max_match_value = (1 << p->width) - 1;
632
633 p->match_value = p->max_match_value;
634 raw_spin_lock_init(&p->lock);
635
636 if (clockevent_rating) 667 if (clockevent_rating)
637 sh_cmt_register_clockevent(p, name, clockevent_rating); 668 sh_cmt_register_clockevent(p, name, clockevent_rating);
638 669
@@ -657,8 +688,6 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
657 goto err0; 688 goto err0;
658 } 689 }
659 690
660 platform_set_drvdata(pdev, p);
661
662 res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); 691 res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
663 if (!res) { 692 if (!res) {
664 dev_err(&p->pdev->dev, "failed to get I/O memory\n"); 693 dev_err(&p->pdev->dev, "failed to get I/O memory\n");
@@ -693,32 +722,51 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
693 goto err1; 722 goto err1;
694 } 723 }
695 724
725 p->read_control = sh_cmt_read16;
726 p->write_control = sh_cmt_write16;
727
696 if (resource_size(res) == 6) { 728 if (resource_size(res) == 6) {
697 p->width = 16; 729 p->width = 16;
730 p->read_count = sh_cmt_read16;
731 p->write_count = sh_cmt_write16;
698 p->overflow_bit = 0x80; 732 p->overflow_bit = 0x80;
699 p->clear_bits = ~0x80; 733 p->clear_bits = ~0x80;
700 } else { 734 } else {
701 p->width = 32; 735 p->width = 32;
736 p->read_count = sh_cmt_read32;
737 p->write_count = sh_cmt_write32;
702 p->overflow_bit = 0x8000; 738 p->overflow_bit = 0x8000;
703 p->clear_bits = ~0xc000; 739 p->clear_bits = ~0xc000;
704 } 740 }
705 741
742 if (p->width == (sizeof(p->max_match_value) * 8))
743 p->max_match_value = ~0;
744 else
745 p->max_match_value = (1 << p->width) - 1;
746
747 p->match_value = p->max_match_value;
748 raw_spin_lock_init(&p->lock);
749
706 ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev), 750 ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
707 cfg->clockevent_rating, 751 cfg->clockevent_rating,
708 cfg->clocksource_rating); 752 cfg->clocksource_rating);
709 if (ret) { 753 if (ret) {
710 dev_err(&p->pdev->dev, "registration failed\n"); 754 dev_err(&p->pdev->dev, "registration failed\n");
711 goto err1; 755 goto err2;
712 } 756 }
713 p->cs_enabled = false; 757 p->cs_enabled = false;
714 758
715 ret = setup_irq(irq, &p->irqaction); 759 ret = setup_irq(irq, &p->irqaction);
716 if (ret) { 760 if (ret) {
717 dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); 761 dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
718 goto err1; 762 goto err2;
719 } 763 }
720 764
765 platform_set_drvdata(pdev, p);
766
721 return 0; 767 return 0;
768err2:
769 clk_put(p->clk);
722 770
723err1: 771err1:
724 iounmap(p->mapbase); 772 iounmap(p->mapbase);
@@ -751,7 +799,6 @@ static int sh_cmt_probe(struct platform_device *pdev)
751 ret = sh_cmt_setup(p, pdev); 799 ret = sh_cmt_setup(p, pdev);
752 if (ret) { 800 if (ret) {
753 kfree(p); 801 kfree(p);
754 platform_set_drvdata(pdev, NULL);
755 pm_runtime_idle(&pdev->dev); 802 pm_runtime_idle(&pdev->dev);
756 return ret; 803 return ret;
757 } 804 }
@@ -791,7 +838,7 @@ static void __exit sh_cmt_exit(void)
791} 838}
792 839
793early_platform_init("earlytimer", &sh_cmt_device_driver); 840early_platform_init("earlytimer", &sh_cmt_device_driver);
794module_init(sh_cmt_init); 841subsys_initcall(sh_cmt_init);
795module_exit(sh_cmt_exit); 842module_exit(sh_cmt_exit);
796 843
797MODULE_AUTHOR("Magnus Damm"); 844MODULE_AUTHOR("Magnus Damm");
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 83943e27cfac..4aac9ee0d0c0 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -386,7 +386,7 @@ static void __exit sh_mtu2_exit(void)
386} 386}
387 387
388early_platform_init("earlytimer", &sh_mtu2_device_driver); 388early_platform_init("earlytimer", &sh_mtu2_device_driver);
389module_init(sh_mtu2_init); 389subsys_initcall(sh_mtu2_init);
390module_exit(sh_mtu2_exit); 390module_exit(sh_mtu2_exit);
391 391
392MODULE_AUTHOR("Magnus Damm"); 392MODULE_AUTHOR("Magnus Damm");
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index b4502edce2a1..78b8dae49628 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -549,7 +549,7 @@ static void __exit sh_tmu_exit(void)
549} 549}
550 550
551early_platform_init("earlytimer", &sh_tmu_device_driver); 551early_platform_init("earlytimer", &sh_tmu_device_driver);
552module_init(sh_tmu_init); 552subsys_initcall(sh_tmu_init);
553module_exit(sh_tmu_exit); 553module_exit(sh_tmu_exit);
554 554
555MODULE_AUTHOR("Magnus Damm"); 555MODULE_AUTHOR("Magnus Damm");