aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-19 14:11:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-19 14:11:20 -0400
commita13f950ef13ff1eaf2ce14f5462ca59c4b60fdd0 (patch)
tree0a660b71881580c9222f2d36d9d9899f0e9e953d
parentd9351ea14ddca708d3cb384f828af4bf82fcc772 (diff)
parentea7a5f90f103591f1f38dede52e731ec95ef3c55 (diff)
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull clocksource updates from Ingo Molnar: "Misc clocksource/clockevent driver updates that came in a bit late but are ready for v5.2" * 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: misc: atmel_tclib: Do not probe already used TCBs clocksource/drivers/timer-atmel-tcb: Convert tc_clksrc_suspend|resume() to static clocksource/drivers/tcb_clksrc: Rename the file for consistency clocksource/drivers/timer-atmel-pit: Rework Kconfig option clocksource/drivers/tcb_clksrc: Move Kconfig option ARM: at91: Implement clocksource selection clocksource/drivers/tcb_clksrc: Use tcb as sched_clock clocksource/drivers/tcb_clksrc: Stop depending on atmel_tclib ARM: at91: move SoC specific definitions to SoC folder clocksource/drivers/timer-milbeaut: Cleanup common register accesses clocksource/drivers/timer-milbeaut: Add shutdown function clocksource/drivers/timer-milbeaut: Fix to enable one-shot timer clocksource/drivers/tegra: Rework for compensation of suspend time clocksource/drivers/sp804: Add COMPILE_TEST to CONFIG_ARM_TIMER_SP804 clocksource/drivers/sun4i: Add a compatible for suniv dt-bindings: timer: Add Allwinner suniv timer
-rw-r--r--Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt4
-rw-r--r--arch/arm/mach-at91/Kconfig23
-rw-r--r--drivers/clocksource/Kconfig14
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/timer-atmel-tcb.c (renamed from drivers/clocksource/tcb_clksrc.c)126
-rw-r--r--drivers/clocksource/timer-milbeaut.c66
-rw-r--r--drivers/clocksource/timer-sun4i.c5
-rw-r--r--drivers/clocksource/timer-tegra20.c63
-rw-r--r--drivers/misc/Kconfig24
-rw-r--r--drivers/misc/atmel_tclib.c5
-rw-r--r--drivers/pwm/pwm-atmel-tcb.c2
-rw-r--r--include/soc/at91/atmel_tcb.h (renamed from include/linux/atmel_tc.h)4
12 files changed, 202 insertions, 136 deletions
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt
index 5c2e23574ca0..3da9d515c03a 100644
--- a/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt
+++ b/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt
@@ -2,7 +2,9 @@ Allwinner A1X SoCs Timer Controller
2 2
3Required properties: 3Required properties:
4 4
5- compatible : should be "allwinner,sun4i-a10-timer" 5- compatible : should be one of the following:
6 "allwinner,sun4i-a10-timer"
7 "allwinner,suniv-f1c100s-timer"
6- reg : Specifies base physical address and size of the registers. 8- reg : Specifies base physical address and size of the registers.
7- interrupts : The interrupt of the first timer 9- interrupts : The interrupt of the first timer
8- clocks: phandle to the source clock (usually a 24 MHz fixed clock) 10- clocks: phandle to the source clock (usually a 24 MHz fixed clock)
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 01b1bdb4fb6e..a2220e522f62 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -104,6 +104,29 @@ config SOC_AT91SAM9
104 AT91SAM9X35 104 AT91SAM9X35
105 AT91SAM9XE 105 AT91SAM9XE
106 106
107comment "Clocksource driver selection"
108
109config ATMEL_CLOCKSOURCE_PIT
110 bool "Periodic Interval Timer (PIT) support"
111 depends on SOC_AT91SAM9 || SOC_SAMA5
112 default SOC_AT91SAM9 || SOC_SAMA5
113 select ATMEL_PIT
114 help
115 Select this to get a clocksource based on the Atmel Periodic Interval
116 Timer. It has a relatively low resolution and the TC Block clocksource
117 should be preferred.
118
119config ATMEL_CLOCKSOURCE_TCB
120 bool "Timer Counter Blocks (TCB) support"
121 default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5
122 select ATMEL_TCB_CLKSRC
123 help
124 Select this to get a high precision clocksource based on a
125 TC block with a 5+ MHz base clock rate.
126 On platforms with 16-bit counters, two timer channels are combined
127 to make a single 32-bit timer.
128 It can also be used as a clock event device supporting oneshot mode.
129
107config HAVE_AT91_UTMI 130config HAVE_AT91_UTMI
108 bool 131 bool
109 132
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 48321488f0fd..6bcaa4e2e72c 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -387,7 +387,7 @@ config ARM_GLOBAL_TIMER
387 This options enables support for the ARM global timer unit 387 This options enables support for the ARM global timer unit
388 388
389config ARM_TIMER_SP804 389config ARM_TIMER_SP804
390 bool "Support for Dual Timer SP804 module" 390 bool "Support for Dual Timer SP804 module" if COMPILE_TEST
391 depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP 391 depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP
392 select CLKSRC_MMIO 392 select CLKSRC_MMIO
393 select TIMER_OF if OF 393 select TIMER_OF if OF
@@ -407,8 +407,11 @@ config ARMV7M_SYSTICK
407 This options enables support for the ARMv7M system timer unit 407 This options enables support for the ARMv7M system timer unit
408 408
409config ATMEL_PIT 409config ATMEL_PIT
410 bool "Atmel PIT support" if COMPILE_TEST
411 depends on HAS_IOMEM
410 select TIMER_OF if OF 412 select TIMER_OF if OF
411 def_bool SOC_AT91SAM9 || SOC_SAMA5 413 help
414 Support for the Periodic Interval Timer found on Atmel SoCs.
412 415
413config ATMEL_ST 416config ATMEL_ST
414 bool "Atmel ST timer support" if COMPILE_TEST 417 bool "Atmel ST timer support" if COMPILE_TEST
@@ -418,6 +421,13 @@ config ATMEL_ST
418 help 421 help
419 Support for the Atmel ST timer. 422 Support for the Atmel ST timer.
420 423
424config ATMEL_TCB_CLKSRC
425 bool "Atmel TC Block timer driver" if COMPILE_TEST
426 depends on HAS_IOMEM
427 select TIMER_OF if OF
428 help
429 Support for Timer Counter Blocks on Atmel SoCs.
430
421config CLKSRC_EXYNOS_MCT 431config CLKSRC_EXYNOS_MCT
422 bool "Exynos multi core timer driver" if COMPILE_TEST 432 bool "Exynos multi core timer driver" if COMPILE_TEST
423 depends on ARM || ARM64 433 depends on ARM || ARM64
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index dba4eff880de..236858fa7fbf 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_TIMER_OF) += timer-of.o
3obj-$(CONFIG_TIMER_PROBE) += timer-probe.o 3obj-$(CONFIG_TIMER_PROBE) += timer-probe.o
4obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o 4obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o
5obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o 5obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o
6obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o 6obj-$(CONFIG_ATMEL_TCB_CLKSRC) += timer-atmel-tcb.o
7obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o 7obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
8obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o 8obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
9obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += timer-cs5535.o 9obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += timer-cs5535.o
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/timer-atmel-tcb.c
index f987027ca566..6ed31f9def7e 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -9,9 +9,11 @@
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/ioport.h> 10#include <linux/ioport.h>
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/platform_device.h> 12#include <linux/of_address.h>
13#include <linux/of_irq.h>
14#include <linux/sched_clock.h>
13#include <linux/syscore_ops.h> 15#include <linux/syscore_ops.h>
14#include <linux/atmel_tc.h> 16#include <soc/at91/atmel_tcb.h>
15 17
16 18
17/* 19/*
@@ -28,13 +30,6 @@
28 * source, used in either periodic or oneshot mode. This runs 30 * source, used in either periodic or oneshot mode. This runs
29 * at 32 KiHZ, and can handle delays of up to two seconds. 31 * at 32 KiHZ, and can handle delays of up to two seconds.
30 * 32 *
31 * A boot clocksource and clockevent source are also currently needed,
32 * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
33 * this code can be used when init_timers() is called, well before most
34 * devices are set up. (Some low end AT91 parts, which can run uClinux,
35 * have only the timers in one TC block... they currently don't support
36 * the tclib code, because of that initialization issue.)
37 *
38 * REVISIT behavior during system suspend states... we should disable 33 * REVISIT behavior during system suspend states... we should disable
39 * all clocks and save the power. Easily done for clockevent devices, 34 * all clocks and save the power. Easily done for clockevent devices,
40 * but clocksources won't necessarily get the needed notifications. 35 * but clocksources won't necessarily get the needed notifications.
@@ -112,7 +107,6 @@ static void tc_clksrc_resume(struct clocksource *cs)
112} 107}
113 108
114static struct clocksource clksrc = { 109static struct clocksource clksrc = {
115 .name = "tcb_clksrc",
116 .rating = 200, 110 .rating = 200,
117 .read = tc_get_cycles, 111 .read = tc_get_cycles,
118 .mask = CLOCKSOURCE_MASK(32), 112 .mask = CLOCKSOURCE_MASK(32),
@@ -121,6 +115,16 @@ static struct clocksource clksrc = {
121 .resume = tc_clksrc_resume, 115 .resume = tc_clksrc_resume,
122}; 116};
123 117
118static u64 notrace tc_sched_clock_read(void)
119{
120 return tc_get_cycles(&clksrc);
121}
122
123static u64 notrace tc_sched_clock_read32(void)
124{
125 return tc_get_cycles32(&clksrc);
126}
127
124#ifdef CONFIG_GENERIC_CLOCKEVENTS 128#ifdef CONFIG_GENERIC_CLOCKEVENTS
125 129
126struct tc_clkevt_device { 130struct tc_clkevt_device {
@@ -214,7 +218,6 @@ static int tc_next_event(unsigned long delta, struct clock_event_device *d)
214 218
215static struct tc_clkevt_device clkevt = { 219static struct tc_clkevt_device clkevt = {
216 .clkevt = { 220 .clkevt = {
217 .name = "tc_clkevt",
218 .features = CLOCK_EVT_FEAT_PERIODIC | 221 .features = CLOCK_EVT_FEAT_PERIODIC |
219 CLOCK_EVT_FEAT_ONESHOT, 222 CLOCK_EVT_FEAT_ONESHOT,
220 /* Should be lower than at91rm9200's system timer */ 223 /* Should be lower than at91rm9200's system timer */
@@ -330,39 +333,74 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id
330 writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); 333 writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
331} 334}
332 335
333static int __init tcb_clksrc_init(void) 336static const u8 atmel_tcb_divisors[5] = { 2, 8, 32, 128, 0, };
334{ 337
335 static char bootinfo[] __initdata 338static const struct of_device_id atmel_tcb_of_match[] = {
336 = KERN_DEBUG "%s: tc%d at %d.%03d MHz\n"; 339 { .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, },
340 { .compatible = "atmel,at91sam9x5-tcb", .data = (void *)32, },
341 { /* sentinel */ }
342};
337 343
338 struct platform_device *pdev; 344static int __init tcb_clksrc_init(struct device_node *node)
339 struct atmel_tc *tc; 345{
346 struct atmel_tc tc;
340 struct clk *t0_clk; 347 struct clk *t0_clk;
348 const struct of_device_id *match;
349 u64 (*tc_sched_clock)(void);
341 u32 rate, divided_rate = 0; 350 u32 rate, divided_rate = 0;
342 int best_divisor_idx = -1; 351 int best_divisor_idx = -1;
343 int clk32k_divisor_idx = -1; 352 int clk32k_divisor_idx = -1;
353 int bits;
344 int i; 354 int i;
345 int ret; 355 int ret;
346 356
347 tc = atmel_tc_alloc(CONFIG_ATMEL_TCB_CLKSRC_BLOCK); 357 /* Protect against multiple calls */
348 if (!tc) { 358 if (tcaddr)
349 pr_debug("can't alloc TC for clocksource\n"); 359 return 0;
350 return -ENODEV; 360
361 tc.regs = of_iomap(node->parent, 0);
362 if (!tc.regs)
363 return -ENXIO;
364
365 t0_clk = of_clk_get_by_name(node->parent, "t0_clk");
366 if (IS_ERR(t0_clk))
367 return PTR_ERR(t0_clk);
368
369 tc.slow_clk = of_clk_get_by_name(node->parent, "slow_clk");
370 if (IS_ERR(tc.slow_clk))
371 return PTR_ERR(tc.slow_clk);
372
373 tc.clk[0] = t0_clk;
374 tc.clk[1] = of_clk_get_by_name(node->parent, "t1_clk");
375 if (IS_ERR(tc.clk[1]))
376 tc.clk[1] = t0_clk;
377 tc.clk[2] = of_clk_get_by_name(node->parent, "t2_clk");
378 if (IS_ERR(tc.clk[2]))
379 tc.clk[2] = t0_clk;
380
381 tc.irq[2] = of_irq_get(node->parent, 2);
382 if (tc.irq[2] <= 0) {
383 tc.irq[2] = of_irq_get(node->parent, 0);
384 if (tc.irq[2] <= 0)
385 return -EINVAL;
351 } 386 }
352 tcaddr = tc->regs;
353 pdev = tc->pdev;
354 387
355 t0_clk = tc->clk[0]; 388 match = of_match_node(atmel_tcb_of_match, node->parent);
389 bits = (uintptr_t)match->data;
390
391 for (i = 0; i < ARRAY_SIZE(tc.irq); i++)
392 writel(ATMEL_TC_ALL_IRQ, tc.regs + ATMEL_TC_REG(i, IDR));
393
356 ret = clk_prepare_enable(t0_clk); 394 ret = clk_prepare_enable(t0_clk);
357 if (ret) { 395 if (ret) {
358 pr_debug("can't enable T0 clk\n"); 396 pr_debug("can't enable T0 clk\n");
359 goto err_free_tc; 397 return ret;
360 } 398 }
361 399
362 /* How fast will we be counting? Pick something over 5 MHz. */ 400 /* How fast will we be counting? Pick something over 5 MHz. */
363 rate = (u32) clk_get_rate(t0_clk); 401 rate = (u32) clk_get_rate(t0_clk);
364 for (i = 0; i < 5; i++) { 402 for (i = 0; i < ARRAY_SIZE(atmel_tcb_divisors); i++) {
365 unsigned divisor = atmel_tc_divisors[i]; 403 unsigned divisor = atmel_tcb_divisors[i];
366 unsigned tmp; 404 unsigned tmp;
367 405
368 /* remember 32 KiHz clock for later */ 406 /* remember 32 KiHz clock for later */
@@ -381,27 +419,31 @@ static int __init tcb_clksrc_init(void)
381 best_divisor_idx = i; 419 best_divisor_idx = i;
382 } 420 }
383 421
384 422 clksrc.name = kbasename(node->parent->full_name);
385 printk(bootinfo, clksrc.name, CONFIG_ATMEL_TCB_CLKSRC_BLOCK, 423 clkevt.clkevt.name = kbasename(node->parent->full_name);
386 divided_rate / 1000000, 424 pr_debug("%s at %d.%03d MHz\n", clksrc.name, divided_rate / 1000000,
387 ((divided_rate % 1000000) + 500) / 1000); 425 ((divided_rate % 1000000) + 500) / 1000);
388 426
389 if (tc->tcb_config && tc->tcb_config->counter_width == 32) { 427 tcaddr = tc.regs;
428
429 if (bits == 32) {
390 /* use apropriate function to read 32 bit counter */ 430 /* use apropriate function to read 32 bit counter */
391 clksrc.read = tc_get_cycles32; 431 clksrc.read = tc_get_cycles32;
392 /* setup ony channel 0 */ 432 /* setup ony channel 0 */
393 tcb_setup_single_chan(tc, best_divisor_idx); 433 tcb_setup_single_chan(&tc, best_divisor_idx);
434 tc_sched_clock = tc_sched_clock_read32;
394 } else { 435 } else {
395 /* tclib will give us three clocks no matter what the 436 /* we have three clocks no matter what the
396 * underlying platform supports. 437 * underlying platform supports.
397 */ 438 */
398 ret = clk_prepare_enable(tc->clk[1]); 439 ret = clk_prepare_enable(tc.clk[1]);
399 if (ret) { 440 if (ret) {
400 pr_debug("can't enable T1 clk\n"); 441 pr_debug("can't enable T1 clk\n");
401 goto err_disable_t0; 442 goto err_disable_t0;
402 } 443 }
403 /* setup both channel 0 & 1 */ 444 /* setup both channel 0 & 1 */
404 tcb_setup_dual_chan(tc, best_divisor_idx); 445 tcb_setup_dual_chan(&tc, best_divisor_idx);
446 tc_sched_clock = tc_sched_clock_read;
405 } 447 }
406 448
407 /* and away we go! */ 449 /* and away we go! */
@@ -410,24 +452,26 @@ static int __init tcb_clksrc_init(void)
410 goto err_disable_t1; 452 goto err_disable_t1;
411 453
412 /* channel 2: periodic and oneshot timer support */ 454 /* channel 2: periodic and oneshot timer support */
413 ret = setup_clkevents(tc, clk32k_divisor_idx); 455 ret = setup_clkevents(&tc, clk32k_divisor_idx);
414 if (ret) 456 if (ret)
415 goto err_unregister_clksrc; 457 goto err_unregister_clksrc;
416 458
459 sched_clock_register(tc_sched_clock, 32, divided_rate);
460
417 return 0; 461 return 0;
418 462
419err_unregister_clksrc: 463err_unregister_clksrc:
420 clocksource_unregister(&clksrc); 464 clocksource_unregister(&clksrc);
421 465
422err_disable_t1: 466err_disable_t1:
423 if (!tc->tcb_config || tc->tcb_config->counter_width != 32) 467 if (bits != 32)
424 clk_disable_unprepare(tc->clk[1]); 468 clk_disable_unprepare(tc.clk[1]);
425 469
426err_disable_t0: 470err_disable_t0:
427 clk_disable_unprepare(t0_clk); 471 clk_disable_unprepare(t0_clk);
428 472
429err_free_tc: 473 tcaddr = NULL;
430 atmel_tc_free(tc); 474
431 return ret; 475 return ret;
432} 476}
433arch_initcall(tcb_clksrc_init); 477TIMER_OF_DECLARE(atmel_tcb_clksrc, "atmel,tcb-timer", tcb_clksrc_init);
diff --git a/drivers/clocksource/timer-milbeaut.c b/drivers/clocksource/timer-milbeaut.c
index f2019a88e3ee..fa9fb4eacade 100644
--- a/drivers/clocksource/timer-milbeaut.c
+++ b/drivers/clocksource/timer-milbeaut.c
@@ -26,8 +26,8 @@
26#define MLB_TMR_TMCSR_CSL_DIV2 0 26#define MLB_TMR_TMCSR_CSL_DIV2 0
27#define MLB_TMR_DIV_CNT 2 27#define MLB_TMR_DIV_CNT 2
28 28
29#define MLB_TMR_SRC_CH (1) 29#define MLB_TMR_SRC_CH 1
30#define MLB_TMR_EVT_CH (0) 30#define MLB_TMR_EVT_CH 0
31 31
32#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH) 32#define MLB_TMR_SRC_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_SRC_CH)
33#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH) 33#define MLB_TMR_EVT_CH_OFS (MLB_TMR_REGSZPCH * MLB_TMR_EVT_CH)
@@ -43,6 +43,8 @@
43#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS) 43#define MLB_TMR_EVT_TMRLR2_OFS (MLB_TMR_EVT_CH_OFS + MLB_TMR_TMRLR2_OFS)
44 44
45#define MLB_TIMER_RATING 500 45#define MLB_TIMER_RATING 500
46#define MLB_TIMER_ONESHOT 0
47#define MLB_TIMER_PERIODIC 1
46 48
47static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id) 49static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id)
48{ 50{
@@ -59,27 +61,53 @@ static irqreturn_t mlb_timer_interrupt(int irq, void *dev_id)
59 return IRQ_HANDLED; 61 return IRQ_HANDLED;
60} 62}
61 63
62static int mlb_set_state_periodic(struct clock_event_device *clk) 64static void mlb_evt_timer_start(struct timer_of *to, bool periodic)
63{ 65{
64 struct timer_of *to = to_timer_of(clk);
65 u32 val = MLB_TMR_TMCSR_CSL_DIV2; 66 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
66 67
68 val |= MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE;
69 if (periodic)
70 val |= MLB_TMR_TMCSR_RELD;
67 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 71 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
72}
68 73
69 writel_relaxed(to->of_clk.period, timer_of_base(to) + 74static void mlb_evt_timer_stop(struct timer_of *to)
70 MLB_TMR_EVT_TMRLR1_OFS); 75{
71 val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | 76 u32 val = readl_relaxed(timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
72 MLB_TMR_TMCSR_TRG | MLB_TMR_TMCSR_INTE; 77
78 val &= ~MLB_TMR_TMCSR_CNTE;
73 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 79 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS);
80}
81
82static void mlb_evt_timer_register_count(struct timer_of *to, unsigned long cnt)
83{
84 writel_relaxed(cnt, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS);
85}
86
87static int mlb_set_state_periodic(struct clock_event_device *clk)
88{
89 struct timer_of *to = to_timer_of(clk);
90
91 mlb_evt_timer_stop(to);
92 mlb_evt_timer_register_count(to, to->of_clk.period);
93 mlb_evt_timer_start(to, MLB_TIMER_PERIODIC);
74 return 0; 94 return 0;
75} 95}
76 96
77static int mlb_set_state_oneshot(struct clock_event_device *clk) 97static int mlb_set_state_oneshot(struct clock_event_device *clk)
78{ 98{
79 struct timer_of *to = to_timer_of(clk); 99 struct timer_of *to = to_timer_of(clk);
80 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
81 100
82 writel_relaxed(val, timer_of_base(to) + MLB_TMR_EVT_TMCSR_OFS); 101 mlb_evt_timer_stop(to);
102 mlb_evt_timer_start(to, MLB_TIMER_ONESHOT);
103 return 0;
104}
105
106static int mlb_set_state_shutdown(struct clock_event_device *clk)
107{
108 struct timer_of *to = to_timer_of(clk);
109
110 mlb_evt_timer_stop(to);
83 return 0; 111 return 0;
84} 112}
85 113
@@ -88,22 +116,21 @@ static int mlb_clkevt_next_event(unsigned long event,
88{ 116{
89 struct timer_of *to = to_timer_of(clk); 117 struct timer_of *to = to_timer_of(clk);
90 118
91 writel_relaxed(event, timer_of_base(to) + MLB_TMR_EVT_TMRLR1_OFS); 119 mlb_evt_timer_stop(to);
92 writel_relaxed(MLB_TMR_TMCSR_CSL_DIV2 | 120 mlb_evt_timer_register_count(to, event);
93 MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_INTE | 121 mlb_evt_timer_start(to, MLB_TIMER_ONESHOT);
94 MLB_TMR_TMCSR_TRG, timer_of_base(to) +
95 MLB_TMR_EVT_TMCSR_OFS);
96 return 0; 122 return 0;
97} 123}
98 124
99static int mlb_config_clock_source(struct timer_of *to) 125static int mlb_config_clock_source(struct timer_of *to)
100{ 126{
101 writel_relaxed(0, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS); 127 u32 val = MLB_TMR_TMCSR_CSL_DIV2;
102 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMR_OFS); 128
129 writel_relaxed(val, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS);
103 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS); 130 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR1_OFS);
104 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS); 131 writel_relaxed(~0, timer_of_base(to) + MLB_TMR_SRC_TMRLR2_OFS);
105 writel_relaxed(BIT(4) | BIT(1) | BIT(0), timer_of_base(to) + 132 val |= MLB_TMR_TMCSR_RELD | MLB_TMR_TMCSR_CNTE | MLB_TMR_TMCSR_TRG;
106 MLB_TMR_SRC_TMCSR_OFS); 133 writel_relaxed(val, timer_of_base(to) + MLB_TMR_SRC_TMCSR_OFS);
107 return 0; 134 return 0;
108} 135}
109 136
@@ -123,6 +150,7 @@ static struct timer_of to = {
123 .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT, 150 .features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT,
124 .set_state_oneshot = mlb_set_state_oneshot, 151 .set_state_oneshot = mlb_set_state_oneshot,
125 .set_state_periodic = mlb_set_state_periodic, 152 .set_state_periodic = mlb_set_state_periodic,
153 .set_state_shutdown = mlb_set_state_shutdown,
126 .set_next_event = mlb_clkevt_next_event, 154 .set_next_event = mlb_clkevt_next_event,
127 }, 155 },
128 156
diff --git a/drivers/clocksource/timer-sun4i.c b/drivers/clocksource/timer-sun4i.c
index 6e0180aaf784..65f38f6ca714 100644
--- a/drivers/clocksource/timer-sun4i.c
+++ b/drivers/clocksource/timer-sun4i.c
@@ -186,7 +186,8 @@ static int __init sun4i_timer_init(struct device_node *node)
186 */ 186 */
187 if (of_machine_is_compatible("allwinner,sun4i-a10") || 187 if (of_machine_is_compatible("allwinner,sun4i-a10") ||
188 of_machine_is_compatible("allwinner,sun5i-a13") || 188 of_machine_is_compatible("allwinner,sun5i-a13") ||
189 of_machine_is_compatible("allwinner,sun5i-a10s")) 189 of_machine_is_compatible("allwinner,sun5i-a10s") ||
190 of_machine_is_compatible("allwinner,suniv-f1c100s"))
190 sched_clock_register(sun4i_timer_sched_read, 32, 191 sched_clock_register(sun4i_timer_sched_read, 32,
191 timer_of_rate(&to)); 192 timer_of_rate(&to));
192 193
@@ -218,3 +219,5 @@ static int __init sun4i_timer_init(struct device_node *node)
218} 219}
219TIMER_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer", 220TIMER_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer",
220 sun4i_timer_init); 221 sun4i_timer_init);
222TIMER_OF_DECLARE(suniv, "allwinner,suniv-f1c100s-timer",
223 sun4i_timer_init);
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c
index fdb3d795a409..919b3568c495 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -60,9 +60,6 @@
60static u32 usec_config; 60static u32 usec_config;
61static void __iomem *timer_reg_base; 61static void __iomem *timer_reg_base;
62#ifdef CONFIG_ARM 62#ifdef CONFIG_ARM
63static void __iomem *rtc_base;
64static struct timespec64 persistent_ts;
65static u64 persistent_ms, last_persistent_ms;
66static struct delay_timer tegra_delay_timer; 63static struct delay_timer tegra_delay_timer;
67#endif 64#endif
68 65
@@ -199,40 +196,30 @@ static unsigned long tegra_delay_timer_read_counter_long(void)
199 return readl(timer_reg_base + TIMERUS_CNTR_1US); 196 return readl(timer_reg_base + TIMERUS_CNTR_1US);
200} 197}
201 198
199static struct timer_of suspend_rtc_to = {
200 .flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
201};
202
202/* 203/*
203 * tegra_rtc_read - Reads the Tegra RTC registers 204 * tegra_rtc_read - Reads the Tegra RTC registers
204 * Care must be taken that this funciton is not called while the 205 * Care must be taken that this funciton is not called while the
205 * tegra_rtc driver could be executing to avoid race conditions 206 * tegra_rtc driver could be executing to avoid race conditions
206 * on the RTC shadow register 207 * on the RTC shadow register
207 */ 208 */
208static u64 tegra_rtc_read_ms(void) 209static u64 tegra_rtc_read_ms(struct clocksource *cs)
209{ 210{
210 u32 ms = readl(rtc_base + RTC_MILLISECONDS); 211 u32 ms = readl(timer_of_base(&suspend_rtc_to) + RTC_MILLISECONDS);
211 u32 s = readl(rtc_base + RTC_SHADOW_SECONDS); 212 u32 s = readl(timer_of_base(&suspend_rtc_to) + RTC_SHADOW_SECONDS);
212 return (u64)s * MSEC_PER_SEC + ms; 213 return (u64)s * MSEC_PER_SEC + ms;
213} 214}
214 215
215/* 216static struct clocksource suspend_rtc_clocksource = {
216 * tegra_read_persistent_clock64 - Return time from a persistent clock. 217 .name = "tegra_suspend_timer",
217 * 218 .rating = 200,
218 * Reads the time from a source which isn't disabled during PM, the 219 .read = tegra_rtc_read_ms,
219 * 32k sync timer. Convert the cycles elapsed since last read into 220 .mask = CLOCKSOURCE_MASK(32),
220 * nsecs and adds to a monotonically increasing timespec64. 221 .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
221 * Care must be taken that this funciton is not called while the 222};
222 * tegra_rtc driver could be executing to avoid race conditions
223 * on the RTC shadow register
224 */
225static void tegra_read_persistent_clock64(struct timespec64 *ts)
226{
227 u64 delta;
228
229 last_persistent_ms = persistent_ms;
230 persistent_ms = tegra_rtc_read_ms();
231 delta = persistent_ms - last_persistent_ms;
232
233 timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC);
234 *ts = persistent_ts;
235}
236#endif 223#endif
237 224
238static int tegra_timer_common_init(struct device_node *np, struct timer_of *to) 225static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)
@@ -385,25 +372,15 @@ out:
385 372
386static int __init tegra20_init_rtc(struct device_node *np) 373static int __init tegra20_init_rtc(struct device_node *np)
387{ 374{
388 struct clk *clk; 375 int ret;
389 376
390 rtc_base = of_iomap(np, 0); 377 ret = timer_of_init(np, &suspend_rtc_to);
391 if (!rtc_base) { 378 if (ret)
392 pr_err("Can't map RTC registers\n"); 379 return ret;
393 return -ENXIO;
394 }
395 380
396 /* 381 clocksource_register_hz(&suspend_rtc_clocksource, 1000);
397 * rtc registers are used by read_persistent_clock, keep the rtc clock
398 * enabled
399 */
400 clk = of_clk_get(np, 0);
401 if (IS_ERR(clk))
402 pr_warn("Unable to get rtc-tegra clock\n");
403 else
404 clk_prepare_enable(clk);
405 382
406 return register_persistent_clock(tegra_read_persistent_clock64); 383 return 0;
407} 384}
408TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); 385TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
409#endif 386#endif
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b80cb6af0cb4..6a0365b2332c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -59,30 +59,6 @@ config ATMEL_TCLIB
59 blocks found on many Atmel processors. This facilitates using 59 blocks found on many Atmel processors. This facilitates using
60 these blocks by different drivers despite processor differences. 60 these blocks by different drivers despite processor differences.
61 61
62config ATMEL_TCB_CLKSRC
63 bool "TC Block Clocksource"
64 depends on ATMEL_TCLIB
65 default y
66 help
67 Select this to get a high precision clocksource based on a
68 TC block with a 5+ MHz base clock rate. Two timer channels
69 are combined to make a single 32-bit timer.
70
71 When GENERIC_CLOCKEVENTS is defined, the third timer channel
72 may be used as a clock event device supporting oneshot mode
73 (delays of up to two seconds) based on the 32 KiHz clock.
74
75config ATMEL_TCB_CLKSRC_BLOCK
76 int
77 depends on ATMEL_TCB_CLKSRC
78 default 0
79 range 0 1
80 help
81 Some chips provide more than one TC block, so you have the
82 choice of which one to use for the clock framework. The other
83 TC can be used for other purposes, such as PWM generation and
84 interval timing.
85
86config DUMMY_IRQ 62config DUMMY_IRQ
87 tristate "Dummy IRQ handler" 63 tristate "Dummy IRQ handler"
88 default n 64 default n
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index ac24a4bd63f7..2c6850ef0e9c 100644
--- a/drivers/misc/atmel_tclib.c
+++ b/drivers/misc/atmel_tclib.c
@@ -1,4 +1,3 @@
1#include <linux/atmel_tc.h>
2#include <linux/clk.h> 1#include <linux/clk.h>
3#include <linux/err.h> 2#include <linux/err.h>
4#include <linux/init.h> 3#include <linux/init.h>
@@ -10,6 +9,7 @@
10#include <linux/slab.h> 9#include <linux/slab.h>
11#include <linux/export.h> 10#include <linux/export.h>
12#include <linux/of.h> 11#include <linux/of.h>
12#include <soc/at91/atmel_tcb.h>
13 13
14/* 14/*
15 * This is a thin library to solve the problem of how to portably allocate 15 * This is a thin library to solve the problem of how to portably allocate
@@ -111,6 +111,9 @@ static int __init tc_probe(struct platform_device *pdev)
111 struct resource *r; 111 struct resource *r;
112 unsigned int i; 112 unsigned int i;
113 113
114 if (of_get_child_count(pdev->dev.of_node))
115 return -EBUSY;
116
114 irq = platform_get_irq(pdev, 0); 117 irq = platform_get_irq(pdev, 0);
115 if (irq < 0) 118 if (irq < 0)
116 return -EINVAL; 119 return -EINVAL;
diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index 0d0f8376bc35..7da1fdb4d269 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -17,10 +17,10 @@
17#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/atmel_tc.h>
21#include <linux/pwm.h> 20#include <linux/pwm.h>
22#include <linux/of_device.h> 21#include <linux/of_device.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
23#include <soc/at91/atmel_tcb.h>
24 24
25#define NPWM 6 25#define NPWM 6
26 26
diff --git a/include/linux/atmel_tc.h b/include/soc/at91/atmel_tcb.h
index 468fdfa643f0..c3c7200ce151 100644
--- a/include/linux/atmel_tc.h
+++ b/include/soc/at91/atmel_tcb.h
@@ -7,8 +7,8 @@
7 * (at your option) any later version. 7 * (at your option) any later version.
8 */ 8 */
9 9
10#ifndef ATMEL_TC_H 10#ifndef __SOC_ATMEL_TCB_H
11#define ATMEL_TC_H 11#define __SOC_ATMEL_TCB_H
12 12
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/list.h> 14#include <linux/list.h>