aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 18:57:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 18:57:20 -0400
commit82e627eb5e07d7993216c9e63fb5550cf6ed25d7 (patch)
tree9319298431a1ee815b2590600c13d1806818c7ff
parentf1a7cd0ffe8c4ecd57a55aab7cfd4c813e0f5f3d (diff)
parent331b483f42fb4d04d52ce920ae10a71411c859a4 (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next
Pull timer core updates from Thomas Gleixner: "This time you get nothing really exciting: - A huge update to the sh* clocksource drivers - Support for two more ARM SoCs - Removal of the deprecated setup_sched_clock() API - The usual pile of fixlets all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) clocksource: Add Freescale FlexTimer Module (FTM) timer support ARM: dts: vf610: Add Freescale FlexTimer Module timer node. clocksource: ftm: Add FlexTimer Module (FTM) Timer devicetree Documentation clocksource: sh_tmu: Remove unnecessary OOM messages clocksource: sh_mtu2: Remove unnecessary OOM messages clocksource: sh_cmt: Remove unnecessary OOM messages clocksource: em_sti: Remove unnecessary OOM messages clocksource: dw_apb_timer_of: Do not trace read_sched_clock clocksource: Fix clocksource_mmio_readX_down clocksource: Fix type confusion for clocksource_mmio_readX_Y clocksource: sh_tmu: Fix channel IRQ retrieval in legacy case clocksource: qcom: Implement read_current_timer for udelay ntp: Make is_error_status() use its argument ntp: Convert simple_strtol to kstrtol timer_stats/doc: Fix /proc/timer_stats documentation sched_clock: Remove deprecated setup_sched_clock() API ARM: sun6i: a31: Add support for the High Speed Timers clocksource: sun5i: Add support for reset controller clocksource: efm32: use $vendor,$device scheme for compatible string KConfig: Vexpress: build the ARM_GLOBAL_TIMER with vexpress platform ...
-rw-r--r--Documentation/devicetree/bindings/arm/global_timer.txt7
-rw-r--r--Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt4
-rw-r--r--Documentation/devicetree/bindings/timer/energymicro,efm32-timer.txt (renamed from Documentation/devicetree/bindings/timer/efm32,timer.txt)4
-rw-r--r--Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt31
-rw-r--r--Documentation/timers/timer_stats.txt6
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi11
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca5s.dts10
-rw-r--r--arch/arm/boot/dts/vf610.dtsi13
-rw-r--r--arch/arm/mach-vexpress/Kconfig1
-rw-r--r--drivers/clocksource/Kconfig5
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/arm_global_timer.c5
-rw-r--r--drivers/clocksource/dw_apb_timer_of.c2
-rw-r--r--drivers/clocksource/em_sti.c4
-rw-r--r--drivers/clocksource/fsl_ftm_timer.c367
-rw-r--r--drivers/clocksource/mmio.c8
-rw-r--r--drivers/clocksource/qcom-timer.c13
-rw-r--r--drivers/clocksource/sh_cmt.c4
-rw-r--r--drivers/clocksource/sh_mtu2.c4
-rw-r--r--drivers/clocksource/sh_tmu.c6
-rw-r--r--drivers/clocksource/time-efm32.c3
-rw-r--r--drivers/clocksource/timer-sun5i.c6
-rw-r--r--include/linux/sched_clock.h1
-rw-r--r--kernel/time/ntp.c17
-rw-r--r--kernel/time/sched_clock.c13
25 files changed, 496 insertions, 50 deletions
diff --git a/Documentation/devicetree/bindings/arm/global_timer.txt b/Documentation/devicetree/bindings/arm/global_timer.txt
index 1e548981eda4..bdae3a818793 100644
--- a/Documentation/devicetree/bindings/arm/global_timer.txt
+++ b/Documentation/devicetree/bindings/arm/global_timer.txt
@@ -4,8 +4,11 @@
4 4
5** Timer node required properties: 5** Timer node required properties:
6 6
7- compatible : Should be "arm,cortex-a9-global-timer" 7- compatible : should contain
8 Driver supports versions r2p0 and above. 8 * "arm,cortex-a5-global-timer" for Cortex-A5 global timers.
9 * "arm,cortex-a9-global-timer" for Cortex-A9 global
10 timers or any compatible implementation. Note: driver
11 supports versions r2p0 and above.
9 12
10- interrupts : One interrupt to each core 13- interrupts : One interrupt to each core
11 14
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
index 7c26154b8bbb..27cfc7d7ccd7 100644
--- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
@@ -9,6 +9,9 @@ Required properties:
9 one) 9 one)
10- clocks: phandle to the source clock (usually the AHB clock) 10- clocks: phandle to the source clock (usually the AHB clock)
11 11
12Optionnal properties:
13- resets: phandle to a reset controller asserting the timer
14
12Example: 15Example:
13 16
14timer@01c60000 { 17timer@01c60000 {
@@ -19,4 +22,5 @@ timer@01c60000 {
19 <0 53 1>, 22 <0 53 1>,
20 <0 54 1>; 23 <0 54 1>;
21 clocks = <&ahb1_gates 19>; 24 clocks = <&ahb1_gates 19>;
25 resets = <&ahb1rst 19>;
22}; 26};
diff --git a/Documentation/devicetree/bindings/timer/efm32,timer.txt b/Documentation/devicetree/bindings/timer/energymicro,efm32-timer.txt
index 97a568f696c9..e502c11b2211 100644
--- a/Documentation/devicetree/bindings/timer/efm32,timer.txt
+++ b/Documentation/devicetree/bindings/timer/energymicro,efm32-timer.txt
@@ -6,7 +6,7 @@ channels and can be used as PWM or Quadrature Decoder. Available clock sources
6are the cpu's HFPERCLK (with a 10-bit prescaler) or an external pin. 6are the cpu's HFPERCLK (with a 10-bit prescaler) or an external pin.
7 7
8Required properties: 8Required properties:
9- compatible : Should be efm32,timer 9- compatible : Should be "energymicro,efm32-timer"
10- reg : Address and length of the register set 10- reg : Address and length of the register set
11- clocks : Should contain a reference to the HFPERCLK 11- clocks : Should contain a reference to the HFPERCLK
12 12
@@ -16,7 +16,7 @@ Optional properties:
16Example: 16Example:
17 17
18timer@40010c00 { 18timer@40010c00 {
19 compatible = "efm32,timer"; 19 compatible = "energymicro,efm32-timer";
20 reg = <0x40010c00 0x400>; 20 reg = <0x40010c00 0x400>;
21 interrupts = <14>; 21 interrupts = <14>;
22 clocks = <&cmu clk_HFPERCLKTIMER3>; 22 clocks = <&cmu clk_HFPERCLKTIMER3>;
diff --git a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
new file mode 100644
index 000000000000..aa8c40230e5e
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
@@ -0,0 +1,31 @@
1Freescale FlexTimer Module (FTM) Timer
2
3Required properties:
4
5- compatible : should be "fsl,ftm-timer"
6- reg : Specifies base physical address and size of the register sets for the
7 clock event device and clock source device.
8- interrupts : Should be the clock event device interrupt.
9- clocks : The clocks provided by the SoC to drive the timer, must contain an
10 entry for each entry in clock-names.
11- clock-names : Must include the following entries:
12 o "ftm-evt"
13 o "ftm-src"
14 o "ftm-evt-counter-en"
15 o "ftm-src-counter-en"
16- big-endian: One boolean property, the big endian mode will be in use if it is
17 present, or the little endian mode will be in use for all the device registers.
18
19Example:
20ftm: ftm@400b8000 {
21 compatible = "fsl,ftm-timer";
22 reg = <0x400b8000 0x1000 0x400b9000 0x1000>;
23 interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
24 clock-names = "ftm-evt", "ftm-src",
25 "ftm-evt-counter-en", "ftm-src-counter-en";
26 clocks = <&clks VF610_CLK_FTM2>,
27 <&clks VF610_CLK_FTM3>,
28 <&clks VF610_CLK_FTM2_EXT_FIX_EN>,
29 <&clks VF610_CLK_FTM3_EXT_FIX_EN>;
30 big-endian;
31};
diff --git a/Documentation/timers/timer_stats.txt b/Documentation/timers/timer_stats.txt
index 8abd40b22b7f..de835ee97455 100644
--- a/Documentation/timers/timer_stats.txt
+++ b/Documentation/timers/timer_stats.txt
@@ -39,9 +39,9 @@ To stop a sample period issue:
39The statistics can be retrieved by: 39The statistics can be retrieved by:
40# cat /proc/timer_stats 40# cat /proc/timer_stats
41 41
42The readout of /proc/timer_stats automatically disables sampling. The sampled 42While sampling is enabled, each readout from /proc/timer_stats will see
43information is kept until a new sample period is started. This allows multiple 43newly updated statistics. Once sampling is disabled, the sampled information
44readouts. 44is kept until a new sample period is started. This allows multiple readouts.
45 45
46Sample output of /proc/timer_stats: 46Sample output of /proc/timer_stats:
47 47
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 0f4ea4990d2c..a9dfa12eb735 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -621,6 +621,17 @@
621 status = "disabled"; 621 status = "disabled";
622 }; 622 };
623 623
624 timer@01c60000 {
625 compatible = "allwinner,sun6i-a31-hstimer", "allwinner,sun7i-a20-hstimer";
626 reg = <0x01c60000 0x1000>;
627 interrupts = <0 51 4>,
628 <0 52 4>,
629 <0 53 4>,
630 <0 54 4>;
631 clocks = <&ahb1_gates 19>;
632 resets = <&ahb1_rst 19>;
633 };
634
624 spi0: spi@01c68000 { 635 spi0: spi@01c68000 {
625 compatible = "allwinner,sun6i-a31-spi"; 636 compatible = "allwinner,sun6i-a31-spi";
626 reg = <0x01c68000 0x1000>; 637 reg = <0x01c68000 0x1000>;
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index c544a5504591..d2709b73316b 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -88,6 +88,14 @@
88 interrupts = <1 13 0x304>; 88 interrupts = <1 13 0x304>;
89 }; 89 };
90 90
91 timer@2c000200 {
92 compatible = "arm,cortex-a5-global-timer",
93 "arm,cortex-a9-global-timer";
94 reg = <0x2c000200 0x20>;
95 interrupts = <1 11 0x304>;
96 clocks = <&oscclk0>;
97 };
98
91 watchdog@2c000620 { 99 watchdog@2c000620 {
92 compatible = "arm,cortex-a5-twd-wdt"; 100 compatible = "arm,cortex-a5-twd-wdt";
93 reg = <0x2c000620 0x20>; 101 reg = <0x2c000620 0x20>;
@@ -120,7 +128,7 @@
120 compatible = "arm,vexpress,config-bus"; 128 compatible = "arm,vexpress,config-bus";
121 arm,vexpress,config-bridge = <&v2m_sysreg>; 129 arm,vexpress,config-bridge = <&v2m_sysreg>;
122 130
123 osc@0 { 131 oscclk0: osc@0 {
124 /* CPU and internal AXI reference clock */ 132 /* CPU and internal AXI reference clock */
125 compatible = "arm,vexpress-osc"; 133 compatible = "arm,vexpress-osc";
126 arm,vexpress-sysreg,func = <1 0>; 134 arm,vexpress-sysreg,func = <1 0>;
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 73355ddc5186..6cc314e7b8fb 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -371,6 +371,19 @@
371 status = "disabled"; 371 status = "disabled";
372 }; 372 };
373 373
374 ftm: ftm@400b8000 {
375 compatible = "fsl,ftm-timer";
376 reg = <0x400b8000 0x1000 0x400b9000 0x1000>;
377 interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
378 clock-names = "ftm-evt", "ftm-src",
379 "ftm-evt-counter-en", "ftm-src-counter-en";
380 clocks = <&clks VF610_CLK_FTM2>,
381 <&clks VF610_CLK_FTM3>,
382 <&clks VF610_CLK_FTM2_EXT_FIX_EN>,
383 <&clks VF610_CLK_FTM3_EXT_FIX_EN>;
384 status = "disabled";
385 };
386
374 fec0: ethernet@400d0000 { 387 fec0: ethernet@400d0000 {
375 compatible = "fsl,mvf600-fec"; 388 compatible = "fsl,mvf600-fec";
376 reg = <0x400d0000 0x1000>; 389 reg = <0x400d0000 0x1000>;
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index b8ac752fd24b..90249cfc37b3 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -4,6 +4,7 @@ config ARCH_VEXPRESS
4 select ARCH_SUPPORTS_BIG_ENDIAN 4 select ARCH_SUPPORTS_BIG_ENDIAN
5 select ARM_AMBA 5 select ARM_AMBA
6 select ARM_GIC 6 select ARM_GIC
7 select ARM_GLOBAL_TIMER
7 select ARM_TIMER_SP804 8 select ARM_TIMER_SP804
8 select COMMON_CLK_VERSATILE 9 select COMMON_CLK_VERSATILE
9 select HAVE_ARM_SCU if SMP 10 select HAVE_ARM_SCU if SMP
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 43f1acf0d1d2..065131cbfcc0 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -136,6 +136,11 @@ config CLKSRC_SAMSUNG_PWM
136 for all devicetree enabled platforms. This driver will be 136 for all devicetree enabled platforms. This driver will be
137 needed only on systems that do not have the Exynos MCT available. 137 needed only on systems that do not have the Exynos MCT available.
138 138
139config FSL_FTM_TIMER
140 bool
141 help
142 Support for Freescale FlexTimer Module (FTM) timer.
143
139config VF_PIT_TIMER 144config VF_PIT_TIMER
140 bool 145 bool
141 help 146 help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 6f25bdffc176..800b1303c236 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
31obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o 31obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
32obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o 32obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
33obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o 33obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
34obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
34obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o 35obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
35obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o 36obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
36 37
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 0fc31d029e52..60e5a170c4d2 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -246,11 +246,12 @@ static void __init global_timer_of_register(struct device_node *np)
246 int err = 0; 246 int err = 0;
247 247
248 /* 248 /*
249 * In r2p0 the comparators for each processor with the global timer 249 * In A9 r2p0 the comparators for each processor with the global timer
250 * fire when the timer value is greater than or equal to. In previous 250 * fire when the timer value is greater than or equal to. In previous
251 * revisions the comparators fired when the timer value was equal to. 251 * revisions the comparators fired when the timer value was equal to.
252 */ 252 */
253 if ((read_cpuid_id() & 0xf0000f) < 0x200000) { 253 if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9
254 && (read_cpuid_id() & 0xf0000f) < 0x200000) {
254 pr_warn("global-timer: non support for this cpu version.\n"); 255 pr_warn("global-timer: non support for this cpu version.\n");
255 return; 256 return;
256 } 257 }
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
index 2a2ea2717f3a..d305fb089767 100644
--- a/drivers/clocksource/dw_apb_timer_of.c
+++ b/drivers/clocksource/dw_apb_timer_of.c
@@ -106,7 +106,7 @@ static void __init add_clocksource(struct device_node *source_timer)
106 sched_rate = rate; 106 sched_rate = rate;
107} 107}
108 108
109static u64 read_sched_clock(void) 109static u64 notrace read_sched_clock(void)
110{ 110{
111 return ~__raw_readl(sched_io_base); 111 return ~__raw_readl(sched_io_base);
112} 112}
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
index 9d170834fcf3..d0a7bd66b8b9 100644
--- a/drivers/clocksource/em_sti.c
+++ b/drivers/clocksource/em_sti.c
@@ -318,10 +318,8 @@ static int em_sti_probe(struct platform_device *pdev)
318 int irq; 318 int irq;
319 319
320 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 320 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
321 if (p == NULL) { 321 if (p == NULL)
322 dev_err(&pdev->dev, "failed to allocate driver data\n");
323 return -ENOMEM; 322 return -ENOMEM;
324 }
325 323
326 p->pdev = pdev; 324 p->pdev = pdev;
327 platform_set_drvdata(pdev, p); 325 platform_set_drvdata(pdev, p);
diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c
new file mode 100644
index 000000000000..454227d4f895
--- /dev/null
+++ b/drivers/clocksource/fsl_ftm_timer.c
@@ -0,0 +1,367 @@
1/*
2 * Freescale FlexTimer Module (FTM) timer driver.
3 *
4 * Copyright 2014 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 */
11
12#include <linux/clk.h>
13#include <linux/clockchips.h>
14#include <linux/clocksource.h>
15#include <linux/err.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/of_address.h>
19#include <linux/of_irq.h>
20#include <linux/sched_clock.h>
21#include <linux/slab.h>
22
23#define FTM_SC 0x00
24#define FTM_SC_CLK_SHIFT 3
25#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
26#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
27#define FTM_SC_PS_MASK 0x7
28#define FTM_SC_TOIE BIT(6)
29#define FTM_SC_TOF BIT(7)
30
31#define FTM_CNT 0x04
32#define FTM_MOD 0x08
33#define FTM_CNTIN 0x4C
34
35#define FTM_PS_MAX 7
36
37struct ftm_clock_device {
38 void __iomem *clksrc_base;
39 void __iomem *clkevt_base;
40 unsigned long periodic_cyc;
41 unsigned long ps;
42 bool big_endian;
43};
44
45static struct ftm_clock_device *priv;
46
47static inline u32 ftm_readl(void __iomem *addr)
48{
49 if (priv->big_endian)
50 return ioread32be(addr);
51 else
52 return ioread32(addr);
53}
54
55static inline void ftm_writel(u32 val, void __iomem *addr)
56{
57 if (priv->big_endian)
58 iowrite32be(val, addr);
59 else
60 iowrite32(val, addr);
61}
62
63static inline void ftm_counter_enable(void __iomem *base)
64{
65 u32 val;
66
67 /* select and enable counter clock source */
68 val = ftm_readl(base + FTM_SC);
69 val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
70 val |= priv->ps | FTM_SC_CLK(1);
71 ftm_writel(val, base + FTM_SC);
72}
73
74static inline void ftm_counter_disable(void __iomem *base)
75{
76 u32 val;
77
78 /* disable counter clock source */
79 val = ftm_readl(base + FTM_SC);
80 val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
81 ftm_writel(val, base + FTM_SC);
82}
83
84static inline void ftm_irq_acknowledge(void __iomem *base)
85{
86 u32 val;
87
88 val = ftm_readl(base + FTM_SC);
89 val &= ~FTM_SC_TOF;
90 ftm_writel(val, base + FTM_SC);
91}
92
93static inline void ftm_irq_enable(void __iomem *base)
94{
95 u32 val;
96
97 val = ftm_readl(base + FTM_SC);
98 val |= FTM_SC_TOIE;
99 ftm_writel(val, base + FTM_SC);
100}
101
102static inline void ftm_irq_disable(void __iomem *base)
103{
104 u32 val;
105
106 val = ftm_readl(base + FTM_SC);
107 val &= ~FTM_SC_TOIE;
108 ftm_writel(val, base + FTM_SC);
109}
110
111static inline void ftm_reset_counter(void __iomem *base)
112{
113 /*
114 * The CNT register contains the FTM counter value.
115 * Reset clears the CNT register. Writing any value to COUNT
116 * updates the counter with its initial value, CNTIN.
117 */
118 ftm_writel(0x00, base + FTM_CNT);
119}
120
121static u64 ftm_read_sched_clock(void)
122{
123 return ftm_readl(priv->clksrc_base + FTM_CNT);
124}
125
126static int ftm_set_next_event(unsigned long delta,
127 struct clock_event_device *unused)
128{
129 /*
130 * The CNNIN and MOD are all double buffer registers, writing
131 * to the MOD register latches the value into a buffer. The MOD
132 * register is updated with the value of its write buffer with
133 * the following scenario:
134 * a, the counter source clock is diabled.
135 */
136 ftm_counter_disable(priv->clkevt_base);
137
138 /* Force the value of CNTIN to be loaded into the FTM counter */
139 ftm_reset_counter(priv->clkevt_base);
140
141 /*
142 * The counter increments until the value of MOD is reached,
143 * at which point the counter is reloaded with the value of CNTIN.
144 * The TOF (the overflow flag) bit is set when the FTM counter
145 * changes from MOD to CNTIN. So we should using the delta - 1.
146 */
147 ftm_writel(delta - 1, priv->clkevt_base + FTM_MOD);
148
149 ftm_counter_enable(priv->clkevt_base);
150
151 ftm_irq_enable(priv->clkevt_base);
152
153 return 0;
154}
155
156static void ftm_set_mode(enum clock_event_mode mode,
157 struct clock_event_device *evt)
158{
159 switch (mode) {
160 case CLOCK_EVT_MODE_PERIODIC:
161 ftm_set_next_event(priv->periodic_cyc, evt);
162 break;
163 case CLOCK_EVT_MODE_ONESHOT:
164 ftm_counter_disable(priv->clkevt_base);
165 break;
166 default:
167 return;
168 }
169}
170
171static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id)
172{
173 struct clock_event_device *evt = dev_id;
174
175 ftm_irq_acknowledge(priv->clkevt_base);
176
177 if (likely(evt->mode == CLOCK_EVT_MODE_ONESHOT)) {
178 ftm_irq_disable(priv->clkevt_base);
179 ftm_counter_disable(priv->clkevt_base);
180 }
181
182 evt->event_handler(evt);
183
184 return IRQ_HANDLED;
185}
186
187static struct clock_event_device ftm_clockevent = {
188 .name = "Freescale ftm timer",
189 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
190 .set_mode = ftm_set_mode,
191 .set_next_event = ftm_set_next_event,
192 .rating = 300,
193};
194
195static struct irqaction ftm_timer_irq = {
196 .name = "Freescale ftm timer",
197 .flags = IRQF_TIMER | IRQF_IRQPOLL,
198 .handler = ftm_evt_interrupt,
199 .dev_id = &ftm_clockevent,
200};
201
202static int __init ftm_clockevent_init(unsigned long freq, int irq)
203{
204 int err;
205
206 ftm_writel(0x00, priv->clkevt_base + FTM_CNTIN);
207 ftm_writel(~0UL, priv->clkevt_base + FTM_MOD);
208
209 ftm_reset_counter(priv->clkevt_base);
210
211 err = setup_irq(irq, &ftm_timer_irq);
212 if (err) {
213 pr_err("ftm: setup irq failed: %d\n", err);
214 return err;
215 }
216
217 ftm_clockevent.cpumask = cpumask_of(0);
218 ftm_clockevent.irq = irq;
219
220 clockevents_config_and_register(&ftm_clockevent,
221 freq / (1 << priv->ps),
222 1, 0xffff);
223
224 ftm_counter_enable(priv->clkevt_base);
225
226 return 0;
227}
228
229static int __init ftm_clocksource_init(unsigned long freq)
230{
231 int err;
232
233 ftm_writel(0x00, priv->clksrc_base + FTM_CNTIN);
234 ftm_writel(~0UL, priv->clksrc_base + FTM_MOD);
235
236 ftm_reset_counter(priv->clksrc_base);
237
238 sched_clock_register(ftm_read_sched_clock, 16, freq / (1 << priv->ps));
239 err = clocksource_mmio_init(priv->clksrc_base + FTM_CNT, "fsl-ftm",
240 freq / (1 << priv->ps), 300, 16,
241 clocksource_mmio_readl_up);
242 if (err) {
243 pr_err("ftm: init clock source mmio failed: %d\n", err);
244 return err;
245 }
246
247 ftm_counter_enable(priv->clksrc_base);
248
249 return 0;
250}
251
252static int __init __ftm_clk_init(struct device_node *np, char *cnt_name,
253 char *ftm_name)
254{
255 struct clk *clk;
256 int err;
257
258 clk = of_clk_get_by_name(np, cnt_name);
259 if (IS_ERR(clk)) {
260 pr_err("ftm: Cannot get \"%s\": %ld\n", cnt_name, PTR_ERR(clk));
261 return PTR_ERR(clk);
262 }
263 err = clk_prepare_enable(clk);
264 if (err) {
265 pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n",
266 cnt_name, err);
267 return err;
268 }
269
270 clk = of_clk_get_by_name(np, ftm_name);
271 if (IS_ERR(clk)) {
272 pr_err("ftm: Cannot get \"%s\": %ld\n", ftm_name, PTR_ERR(clk));
273 return PTR_ERR(clk);
274 }
275 err = clk_prepare_enable(clk);
276 if (err)
277 pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n",
278 ftm_name, err);
279
280 return clk_get_rate(clk);
281}
282
283static unsigned long __init ftm_clk_init(struct device_node *np)
284{
285 unsigned long freq;
286
287 freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt");
288 if (freq <= 0)
289 return 0;
290
291 freq = __ftm_clk_init(np, "ftm-src-counter-en", "ftm-src");
292 if (freq <= 0)
293 return 0;
294
295 return freq;
296}
297
298static int __init ftm_calc_closest_round_cyc(unsigned long freq)
299{
300 priv->ps = 0;
301
302 /* The counter register is only using the lower 16 bits, and
303 * if the 'freq' value is to big here, then the periodic_cyc
304 * may exceed 0xFFFF.
305 */
306 do {
307 priv->periodic_cyc = DIV_ROUND_CLOSEST(freq,
308 HZ * (1 << priv->ps++));
309 } while (priv->periodic_cyc > 0xFFFF);
310
311 if (priv->ps > FTM_PS_MAX) {
312 pr_err("ftm: the prescaler is %lu > %d\n",
313 priv->ps, FTM_PS_MAX);
314 return -EINVAL;
315 }
316
317 return 0;
318}
319
320static void __init ftm_timer_init(struct device_node *np)
321{
322 unsigned long freq;
323 int irq;
324
325 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
326 if (!priv)
327 return;
328
329 priv->clkevt_base = of_iomap(np, 0);
330 if (!priv->clkevt_base) {
331 pr_err("ftm: unable to map event timer registers\n");
332 goto err;
333 }
334
335 priv->clksrc_base = of_iomap(np, 1);
336 if (!priv->clksrc_base) {
337 pr_err("ftm: unable to map source timer registers\n");
338 goto err;
339 }
340
341 irq = irq_of_parse_and_map(np, 0);
342 if (irq <= 0) {
343 pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
344 goto err;
345 }
346
347 priv->big_endian = of_property_read_bool(np, "big-endian");
348
349 freq = ftm_clk_init(np);
350 if (!freq)
351 goto err;
352
353 if (ftm_calc_closest_round_cyc(freq))
354 goto err;
355
356 if (ftm_clocksource_init(freq))
357 goto err;
358
359 if (ftm_clockevent_init(freq, irq))
360 goto err;
361
362 return;
363
364err:
365 kfree(priv);
366}
367CLOCKSOURCE_OF_DECLARE(flextimer, "fsl,ftm-timer", ftm_timer_init);
diff --git a/drivers/clocksource/mmio.c b/drivers/clocksource/mmio.c
index c0e25125a55e..1593ade2a815 100644
--- a/drivers/clocksource/mmio.c
+++ b/drivers/clocksource/mmio.c
@@ -22,22 +22,22 @@ static inline struct clocksource_mmio *to_mmio_clksrc(struct clocksource *c)
22 22
23cycle_t clocksource_mmio_readl_up(struct clocksource *c) 23cycle_t clocksource_mmio_readl_up(struct clocksource *c)
24{ 24{
25 return readl_relaxed(to_mmio_clksrc(c)->reg); 25 return (cycle_t)readl_relaxed(to_mmio_clksrc(c)->reg);
26} 26}
27 27
28cycle_t clocksource_mmio_readl_down(struct clocksource *c) 28cycle_t clocksource_mmio_readl_down(struct clocksource *c)
29{ 29{
30 return ~readl_relaxed(to_mmio_clksrc(c)->reg); 30 return ~(cycle_t)readl_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
31} 31}
32 32
33cycle_t clocksource_mmio_readw_up(struct clocksource *c) 33cycle_t clocksource_mmio_readw_up(struct clocksource *c)
34{ 34{
35 return readw_relaxed(to_mmio_clksrc(c)->reg); 35 return (cycle_t)readw_relaxed(to_mmio_clksrc(c)->reg);
36} 36}
37 37
38cycle_t clocksource_mmio_readw_down(struct clocksource *c) 38cycle_t clocksource_mmio_readw_down(struct clocksource *c)
39{ 39{
40 return ~(unsigned)readw_relaxed(to_mmio_clksrc(c)->reg); 40 return ~(cycle_t)readw_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
41} 41}
42 42
43/** 43/**
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
index e807acf4c665..8d115db1e651 100644
--- a/drivers/clocksource/qcom-timer.c
+++ b/drivers/clocksource/qcom-timer.c
@@ -26,6 +26,8 @@
26#include <linux/of_irq.h> 26#include <linux/of_irq.h>
27#include <linux/sched_clock.h> 27#include <linux/sched_clock.h>
28 28
29#include <asm/delay.h>
30
29#define TIMER_MATCH_VAL 0x0000 31#define TIMER_MATCH_VAL 0x0000
30#define TIMER_COUNT_VAL 0x0004 32#define TIMER_COUNT_VAL 0x0004
31#define TIMER_ENABLE 0x0008 33#define TIMER_ENABLE 0x0008
@@ -179,6 +181,15 @@ static u64 notrace msm_sched_clock_read(void)
179 return msm_clocksource.read(&msm_clocksource); 181 return msm_clocksource.read(&msm_clocksource);
180} 182}
181 183
184static unsigned long msm_read_current_timer(void)
185{
186 return msm_clocksource.read(&msm_clocksource);
187}
188
189static struct delay_timer msm_delay_timer = {
190 .read_current_timer = msm_read_current_timer,
191};
192
182static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, 193static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
183 bool percpu) 194 bool percpu)
184{ 195{
@@ -217,6 +228,8 @@ err:
217 if (res) 228 if (res)
218 pr_err("clocksource_register failed\n"); 229 pr_err("clocksource_register failed\n");
219 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); 230 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
231 msm_delay_timer.freq = dgt_hz;
232 register_current_timer_delay(&msm_delay_timer);
220} 233}
221 234
222#ifdef CONFIG_ARCH_QCOM 235#ifdef CONFIG_ARCH_QCOM
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index bc8d025ce861..dfa780396b91 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -1106,10 +1106,8 @@ static int sh_cmt_probe(struct platform_device *pdev)
1106 } 1106 }
1107 1107
1108 cmt = kzalloc(sizeof(*cmt), GFP_KERNEL); 1108 cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
1109 if (cmt == NULL) { 1109 if (cmt == NULL)
1110 dev_err(&pdev->dev, "failed to allocate driver data\n");
1111 return -ENOMEM; 1110 return -ENOMEM;
1112 }
1113 1111
1114 ret = sh_cmt_setup(cmt, pdev); 1112 ret = sh_cmt_setup(cmt, pdev);
1115 if (ret) { 1113 if (ret) {
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index f2c1c36139e1..188d4e092efc 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -533,10 +533,8 @@ static int sh_mtu2_probe(struct platform_device *pdev)
533 } 533 }
534 534
535 mtu = kzalloc(sizeof(*mtu), GFP_KERNEL); 535 mtu = kzalloc(sizeof(*mtu), GFP_KERNEL);
536 if (mtu == NULL) { 536 if (mtu == NULL)
537 dev_err(&pdev->dev, "failed to allocate driver data\n");
538 return -ENOMEM; 537 return -ENOMEM;
539 }
540 538
541 ret = sh_mtu2_setup(mtu, pdev); 539 ret = sh_mtu2_setup(mtu, pdev);
542 if (ret) { 540 if (ret) {
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 4ba2c0fea580..6bd17a8f3dd4 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -498,7 +498,7 @@ static int sh_tmu_channel_setup(struct sh_tmu_channel *ch, unsigned int index,
498 ch->base = tmu->mapbase + 8 + ch->index * 12; 498 ch->base = tmu->mapbase + 8 + ch->index * 12;
499 } 499 }
500 500
501 ch->irq = platform_get_irq(tmu->pdev, ch->index); 501 ch->irq = platform_get_irq(tmu->pdev, index);
502 if (ch->irq < 0) { 502 if (ch->irq < 0) {
503 dev_err(&tmu->pdev->dev, "ch%u: failed to get irq\n", 503 dev_err(&tmu->pdev->dev, "ch%u: failed to get irq\n",
504 ch->index); 504 ch->index);
@@ -644,10 +644,8 @@ static int sh_tmu_probe(struct platform_device *pdev)
644 } 644 }
645 645
646 tmu = kzalloc(sizeof(*tmu), GFP_KERNEL); 646 tmu = kzalloc(sizeof(*tmu), GFP_KERNEL);
647 if (tmu == NULL) { 647 if (tmu == NULL)
648 dev_err(&pdev->dev, "failed to allocate driver data\n");
649 return -ENOMEM; 648 return -ENOMEM;
650 }
651 649
652 ret = sh_tmu_setup(tmu, pdev); 650 ret = sh_tmu_setup(tmu, pdev);
653 if (ret) { 651 if (ret) {
diff --git a/drivers/clocksource/time-efm32.c b/drivers/clocksource/time-efm32.c
index 1a6205b7bed3..bba62f9deefb 100644
--- a/drivers/clocksource/time-efm32.c
+++ b/drivers/clocksource/time-efm32.c
@@ -272,4 +272,5 @@ static void __init efm32_timer_init(struct device_node *np)
272 } 272 }
273 } 273 }
274} 274}
275CLOCKSOURCE_OF_DECLARE(efm32, "efm32,timer", efm32_timer_init); 275CLOCKSOURCE_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init);
276CLOCKSOURCE_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init);
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
index deebcd6469fc..02268448dc85 100644
--- a/drivers/clocksource/timer-sun5i.c
+++ b/drivers/clocksource/timer-sun5i.c
@@ -16,6 +16,7 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/irq.h> 17#include <linux/irq.h>
18#include <linux/irqreturn.h> 18#include <linux/irqreturn.h>
19#include <linux/reset.h>
19#include <linux/sched_clock.h> 20#include <linux/sched_clock.h>
20#include <linux/of.h> 21#include <linux/of.h>
21#include <linux/of_address.h> 22#include <linux/of_address.h>
@@ -143,6 +144,7 @@ static u64 sun5i_timer_sched_read(void)
143 144
144static void __init sun5i_timer_init(struct device_node *node) 145static void __init sun5i_timer_init(struct device_node *node)
145{ 146{
147 struct reset_control *rstc;
146 unsigned long rate; 148 unsigned long rate;
147 struct clk *clk; 149 struct clk *clk;
148 int ret, irq; 150 int ret, irq;
@@ -162,6 +164,10 @@ static void __init sun5i_timer_init(struct device_node *node)
162 clk_prepare_enable(clk); 164 clk_prepare_enable(clk);
163 rate = clk_get_rate(clk); 165 rate = clk_get_rate(clk);
164 166
167 rstc = of_reset_control_get(node, NULL);
168 if (!IS_ERR(rstc))
169 reset_control_deassert(rstc);
170
165 writel(~0, timer_base + TIMER_INTVAL_LO_REG(1)); 171 writel(~0, timer_base + TIMER_INTVAL_LO_REG(1));
166 writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, 172 writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
167 timer_base + TIMER_CTL_REG(1)); 173 timer_base + TIMER_CTL_REG(1));
diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index cddf0c2940b6..efa931c5cef1 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -14,7 +14,6 @@ extern void sched_clock_postinit(void);
14static inline void sched_clock_postinit(void) { } 14static inline void sched_clock_postinit(void) { }
15#endif 15#endif
16 16
17extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
18extern void sched_clock_register(u64 (*read)(void), int bits, 17extern void sched_clock_register(u64 (*read)(void), int bits,
19 unsigned long rate); 18 unsigned long rate);
20 19
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 419a52cecd20..c8780cdaf852 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -165,21 +165,21 @@ static inline void pps_set_freq(s64 freq)
165 165
166static inline int is_error_status(int status) 166static inline int is_error_status(int status)
167{ 167{
168 return (time_status & (STA_UNSYNC|STA_CLOCKERR)) 168 return (status & (STA_UNSYNC|STA_CLOCKERR))
169 /* PPS signal lost when either PPS time or 169 /* PPS signal lost when either PPS time or
170 * PPS frequency synchronization requested 170 * PPS frequency synchronization requested
171 */ 171 */
172 || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) 172 || ((status & (STA_PPSFREQ|STA_PPSTIME))
173 && !(time_status & STA_PPSSIGNAL)) 173 && !(status & STA_PPSSIGNAL))
174 /* PPS jitter exceeded when 174 /* PPS jitter exceeded when
175 * PPS time synchronization requested */ 175 * PPS time synchronization requested */
176 || ((time_status & (STA_PPSTIME|STA_PPSJITTER)) 176 || ((status & (STA_PPSTIME|STA_PPSJITTER))
177 == (STA_PPSTIME|STA_PPSJITTER)) 177 == (STA_PPSTIME|STA_PPSJITTER))
178 /* PPS wander exceeded or calibration error when 178 /* PPS wander exceeded or calibration error when
179 * PPS frequency synchronization requested 179 * PPS frequency synchronization requested
180 */ 180 */
181 || ((time_status & STA_PPSFREQ) 181 || ((status & STA_PPSFREQ)
182 && (time_status & (STA_PPSWANDER|STA_PPSERROR))); 182 && (status & (STA_PPSWANDER|STA_PPSERROR)));
183} 183}
184 184
185static inline void pps_fill_timex(struct timex *txc) 185static inline void pps_fill_timex(struct timex *txc)
@@ -923,7 +923,10 @@ void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
923 923
924static int __init ntp_tick_adj_setup(char *str) 924static int __init ntp_tick_adj_setup(char *str)
925{ 925{
926 ntp_tick_adj = simple_strtol(str, NULL, 0); 926 int rc = kstrtol(str, 0, (long *)&ntp_tick_adj);
927
928 if (rc)
929 return rc;
927 ntp_tick_adj <<= NTP_SCALE_SHIFT; 930 ntp_tick_adj <<= NTP_SCALE_SHIFT;
928 931
929 return 1; 932 return 1;
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index 4d23dc4d8139..445106d2c729 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -49,13 +49,6 @@ static u64 notrace jiffy_sched_clock_read(void)
49 return (u64)(jiffies - INITIAL_JIFFIES); 49 return (u64)(jiffies - INITIAL_JIFFIES);
50} 50}
51 51
52static u32 __read_mostly (*read_sched_clock_32)(void);
53
54static u64 notrace read_sched_clock_32_wrapper(void)
55{
56 return read_sched_clock_32();
57}
58
59static u64 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; 52static u64 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
60 53
61static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift) 54static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift)
@@ -176,12 +169,6 @@ void __init sched_clock_register(u64 (*read)(void), int bits,
176 pr_debug("Registered %pF as sched_clock source\n", read); 169 pr_debug("Registered %pF as sched_clock source\n", read);
177} 170}
178 171
179void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
180{
181 read_sched_clock_32 = read;
182 sched_clock_register(read_sched_clock_32_wrapper, bits, rate);
183}
184
185void __init sched_clock_postinit(void) 172void __init sched_clock_postinit(void)
186{ 173{
187 /* 174 /*