aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/Kconfig135
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/acpi_pm.c27
-rw-r--r--drivers/clocksource/arm_global_timer.c21
-rw-r--r--drivers/clocksource/dw_apb_timer.c46
-rw-r--r--drivers/clocksource/dw_apb_timer_of.c16
-rw-r--r--drivers/clocksource/h8300_timer16.c222
-rw-r--r--drivers/clocksource/h8300_timer8.c264
-rw-r--r--drivers/clocksource/h8300_tpu.c159
-rw-r--r--drivers/clocksource/mtk_timer.c20
-rw-r--r--drivers/clocksource/rockchip_timer.c23
-rw-r--r--drivers/clocksource/tango_xtal.c18
-rw-r--r--drivers/clocksource/tegra20_timer.c3
-rw-r--r--drivers/clocksource/time-lpc32xx.c4
-rw-r--r--drivers/clocksource/time-pistachio.c2
-rw-r--r--drivers/clocksource/timer-sun5i.c16
-rw-r--r--drivers/clocksource/vt8500_timer.c1
17 files changed, 420 insertions, 559 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 2eb5f0efae90..56777f04d2d9 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -28,10 +28,16 @@ config CLKSRC_MMIO
28 bool 28 bool
29 29
30config DIGICOLOR_TIMER 30config DIGICOLOR_TIMER
31 bool 31 bool "Digicolor timer driver" if COMPILE_TEST
32 depends on GENERIC_CLOCKEVENTS
33 help
34 Enables the support for the digicolor timer driver.
32 35
33config DW_APB_TIMER 36config DW_APB_TIMER
34 bool 37 bool "DW APB timer driver" if COMPILE_TEST
38 depends on GENERIC_CLOCKEVENTS
39 help
40 Enables the support for the dw_apb timer.
35 41
36config DW_APB_TIMER_OF 42config DW_APB_TIMER_OF
37 bool 43 bool
@@ -39,47 +45,77 @@ config DW_APB_TIMER_OF
39 select CLKSRC_OF 45 select CLKSRC_OF
40 46
41config ROCKCHIP_TIMER 47config ROCKCHIP_TIMER
42 bool 48 bool "Rockchip timer driver" if COMPILE_TEST
49 depends on ARM || ARM64
43 select CLKSRC_OF 50 select CLKSRC_OF
51 help
52 Enables the support for the rockchip timer driver.
44 53
45config ARMADA_370_XP_TIMER 54config ARMADA_370_XP_TIMER
46 bool 55 bool "Armada 370 and XP timer driver" if COMPILE_TEST
56 depends on ARM
47 select CLKSRC_OF 57 select CLKSRC_OF
58 help
59 Enables the support for the Armada 370 and XP timer driver.
48 60
49config MESON6_TIMER 61config MESON6_TIMER
50 bool 62 bool "Meson6 timer driver" if COMPILE_TEST
63 depends on GENERIC_CLOCKEVENTS
51 select CLKSRC_MMIO 64 select CLKSRC_MMIO
65 help
66 Enables the support for the Meson6 timer driver.
52 67
53config ORION_TIMER 68config ORION_TIMER
69 bool "Orion timer driver" if COMPILE_TEST
70 depends on ARM
54 select CLKSRC_OF 71 select CLKSRC_OF
55 select CLKSRC_MMIO 72 select CLKSRC_MMIO
56 bool 73 help
74 Enables the support for the Orion timer driver
57 75
58config SUN4I_TIMER 76config SUN4I_TIMER
77 bool "Sun4i timer driver" if COMPILE_TEST
78 depends on GENERIC_CLOCKEVENTS
59 select CLKSRC_MMIO 79 select CLKSRC_MMIO
60 bool 80 help
81 Enables support for the Sun4i timer.
61 82
62config SUN5I_HSTIMER 83config SUN5I_HSTIMER
84 bool "Sun5i timer driver" if COMPILE_TEST
63 select CLKSRC_MMIO 85 select CLKSRC_MMIO
64 bool 86 depends on COMMON_CLK
87 help
88 Enables support the Sun5i timer.
65 89
66config TEGRA_TIMER 90config TEGRA_TIMER
67 bool 91 bool "Tegra timer driver" if COMPILE_TEST
92 depends on ARM
93 help
94 Enables support for the Tegra driver.
68 95
69config VT8500_TIMER 96config VT8500_TIMER
70 bool 97 bool "VT8500 timer driver" if COMPILE_TEST
98 depends on GENERIC_CLOCKEVENTS
99 help
100 Enables support for the VT8500 driver.
71 101
72config CADENCE_TTC_TIMER 102config CADENCE_TTC_TIMER
73 bool 103 bool "Cadence TTC timer driver" if COMPILE_TEST
104 depends on COMMON_CLK
105 help
106 Enables support for the cadence ttc driver.
74 107
75config ASM9260_TIMER 108config ASM9260_TIMER
76 bool 109 bool "ASM9260 timer driver" if COMPILE_TEST
110 depends on GENERIC_CLOCKEVENTS
77 select CLKSRC_MMIO 111 select CLKSRC_MMIO
78 select CLKSRC_OF 112 select CLKSRC_OF
113 help
114 Enables support for the ASM9260 timer.
79 115
80config CLKSRC_NOMADIK_MTU 116config CLKSRC_NOMADIK_MTU
81 bool 117 bool "Nomakdik clocksource driver" if COMPILE_TEST
82 depends on (ARCH_NOMADIK || ARCH_U8500) 118 depends on ARM
83 select CLKSRC_MMIO 119 select CLKSRC_MMIO
84 help 120 help
85 Support for Multi Timer Unit. MTU provides access 121 Support for Multi Timer Unit. MTU provides access
@@ -93,9 +129,8 @@ config CLKSRC_NOMADIK_MTU_SCHED_CLOCK
93 Use the Multi Timer Unit as the sched_clock. 129 Use the Multi Timer Unit as the sched_clock.
94 130
95config CLKSRC_DBX500_PRCMU 131config CLKSRC_DBX500_PRCMU
96 bool "Clocksource PRCMU Timer" 132 bool "Clocksource PRCMU Timer" if COMPILE_TEST
97 depends on UX500_SOC_DB8500 133 depends on GENERIC_CLOCKEVENTS
98 default y
99 help 134 help
100 Use the always on PRCMU Timer as clocksource 135 Use the always on PRCMU Timer as clocksource
101 136
@@ -116,13 +151,19 @@ config CLKSRC_EFM32
116 event device. 151 event device.
117 152
118config CLKSRC_LPC32XX 153config CLKSRC_LPC32XX
119 bool 154 bool "Clocksource for LPC32XX" if COMPILE_TEST
155 depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
120 select CLKSRC_MMIO 156 select CLKSRC_MMIO
121 select CLKSRC_OF 157 select CLKSRC_OF
158 help
159 Support for the LPC32XX clocksource.
122 160
123config CLKSRC_PISTACHIO 161config CLKSRC_PISTACHIO
124 bool 162 bool "Clocksource for Pistachio SoC" if COMPILE_TEST
163 depends on HAS_IOMEM
125 select CLKSRC_OF 164 select CLKSRC_OF
165 help
166 Enables the clocksource for the Pistachio SoC.
126 167
127config CLKSRC_TI_32K 168config CLKSRC_TI_32K
128 bool "Texas Instruments 32.768 Hz Clocksource" if COMPILE_TEST 169 bool "Texas Instruments 32.768 Hz Clocksource" if COMPILE_TEST
@@ -199,13 +240,14 @@ config CLKSRC_METAG_GENERIC
199 This option enables support for the Meta per-thread timers. 240 This option enables support for the Meta per-thread timers.
200 241
201config CLKSRC_EXYNOS_MCT 242config CLKSRC_EXYNOS_MCT
202 def_bool y if ARCH_EXYNOS 243 bool "Exynos multi core timer driver" if COMPILE_TEST
203 depends on !ARM64 244 depends on ARM
204 help 245 help
205 Support for Multi Core Timer controller on Exynos SoCs. 246 Support for Multi Core Timer controller on Exynos SoCs.
206 247
207config CLKSRC_SAMSUNG_PWM 248config CLKSRC_SAMSUNG_PWM
208 bool 249 bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST
250 depends on GENERIC_CLOCKEVENTS
209 help 251 help
210 This is a new clocksource driver for the PWM timer found in 252 This is a new clocksource driver for the PWM timer found in
211 Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver 253 Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
@@ -213,7 +255,9 @@ config CLKSRC_SAMSUNG_PWM
213 needed only on systems that do not have the Exynos MCT available. 255 needed only on systems that do not have the Exynos MCT available.
214 256
215config FSL_FTM_TIMER 257config FSL_FTM_TIMER
216 bool 258 bool "Freescale FlexTimer Module driver" if COMPILE_TEST
259 depends on GENERIC_CLOCKEVENTS
260 select CLKSRC_MMIO
217 help 261 help
218 Support for Freescale FlexTimer Module (FTM) timer. 262 Support for Freescale FlexTimer Module (FTM) timer.
219 263
@@ -226,9 +270,12 @@ config SYS_SUPPORTS_SH_CMT
226 bool 270 bool
227 271
228config MTK_TIMER 272config MTK_TIMER
273 bool "Mediatek timer driver" if COMPILE_TEST
274 depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
229 select CLKSRC_OF 275 select CLKSRC_OF
230 select CLKSRC_MMIO 276 select CLKSRC_MMIO
231 bool 277 help
278 Support for Mediatek timer driver.
232 279
233config SYS_SUPPORTS_SH_MTU2 280config SYS_SUPPORTS_SH_MTU2
234 bool 281 bool
@@ -279,7 +326,12 @@ config EM_TIMER_STI
279 such as EMEV2 from former NEC Electronics. 326 such as EMEV2 from former NEC Electronics.
280 327
281config CLKSRC_QCOM 328config CLKSRC_QCOM
282 bool 329 bool "Qualcomm MSM timer" if COMPILE_TEST
330 depends on ARM
331 select CLKSRC_OF
332 help
333 This enables the clocksource and the per CPU clockevent driver for the
334 Qualcomm SoCs.
283 335
284config CLKSRC_VERSATILE 336config CLKSRC_VERSATILE
285 bool "ARM Versatile (Express) reference platforms clock source" 337 bool "ARM Versatile (Express) reference platforms clock source"
@@ -298,21 +350,40 @@ config CLKSRC_MIPS_GIC
298 select CLKSRC_OF 350 select CLKSRC_OF
299 351
300config CLKSRC_TANGO_XTAL 352config CLKSRC_TANGO_XTAL
301 bool 353 bool "Clocksource for Tango SoC" if COMPILE_TEST
354 depends on ARM
302 select CLKSRC_OF 355 select CLKSRC_OF
356 select CLKSRC_MMIO
357 help
358 This enables the clocksource for Tango SoC
303 359
304config CLKSRC_PXA 360config CLKSRC_PXA
305 def_bool y if ARCH_PXA || ARCH_SA1100 361 bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST
306 select CLKSRC_OF if OF 362 depends on GENERIC_CLOCKEVENTS
363 select CLKSRC_MMIO
307 help 364 help
308 This enables OST0 support available on PXA and SA-11x0 365 This enables OST0 support available on PXA and SA-11x0
309 platforms. 366 platforms.
310 367
368config H8300_TMR8
369 bool "Clockevent timer for the H8300 platform" if COMPILE_TEST
370 depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
371 help
372 This enables the 8 bits timer for the H8300 platform.
373
311config H8300_TMR16 374config H8300_TMR16
312 bool 375 bool "Clockevent timer for the H83069 platform" if COMPILE_TEST
376 depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
377 help
378 This enables the 16 bits timer for the H8300 platform with the
379 H83069 cpu.
313 380
314config H8300_TPU 381config H8300_TPU
315 bool 382 bool "Clocksource for the H8300 platform" if COMPILE_TEST
383 depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
384 help
385 This enables the clocksource for the H8300 platform with the
386 H8S2678 cpu.
316 387
317config CLKSRC_IMX_GPT 388config CLKSRC_IMX_GPT
318 bool "Clocksource using i.MX GPT" if COMPILE_TEST 389 bool "Clocksource using i.MX GPT" if COMPILE_TEST
@@ -320,9 +391,9 @@ config CLKSRC_IMX_GPT
320 select CLKSRC_MMIO 391 select CLKSRC_MMIO
321 392
322config CLKSRC_ST_LPC 393config CLKSRC_ST_LPC
323 bool 394 bool "Low power clocksource found in the LPC" if COMPILE_TEST
324 depends on ARCH_STI
325 select CLKSRC_OF if OF 395 select CLKSRC_OF if OF
396 depends on HAS_IOMEM
326 help 397 help
327 Enable this option to use the Low Power controller timer 398 Enable this option to use the Low Power controller timer
328 as clocksource. 399 as clocksource.
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 56bd16e77ae3..dc2b8997f6e6 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -60,7 +60,7 @@ obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
60obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o 60obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o
61obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o 61obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o
62obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o 62obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
63obj-$(CONFIG_H8300) += h8300_timer8.o 63obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o
64obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o 64obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
65obj-$(CONFIG_H8300_TPU) += h8300_tpu.o 65obj-$(CONFIG_H8300_TPU) += h8300_tpu.o
66obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o 66obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 6eab88985670..28037d0b8dcd 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -109,10 +109,8 @@ static void acpi_pm_check_blacklist(struct pci_dev *dev)
109 109
110 /* the bug has been fixed in PIIX4M */ 110 /* the bug has been fixed in PIIX4M */
111 if (dev->revision < 3) { 111 if (dev->revision < 3) {
112 printk(KERN_WARNING "* Found PM-Timer Bug on the chipset." 112 pr_warn("* Found PM-Timer Bug on the chipset. Due to workarounds for a bug,\n"
113 " Due to workarounds for a bug,\n" 113 "* this clock source is slow. Consider trying other clock sources\n");
114 "* this clock source is slow. Consider trying"
115 " other clock sources\n");
116 114
117 acpi_pm_need_workaround(); 115 acpi_pm_need_workaround();
118 } 116 }
@@ -125,12 +123,9 @@ static void acpi_pm_check_graylist(struct pci_dev *dev)
125 if (acpi_pm_good) 123 if (acpi_pm_good)
126 return; 124 return;
127 125
128 printk(KERN_WARNING "* The chipset may have PM-Timer Bug. Due to" 126 pr_warn("* The chipset may have PM-Timer Bug. Due to workarounds for a bug,\n"
129 " workarounds for a bug,\n" 127 "* this clock source is slow. If you are sure your timer does not have\n"
130 "* this clock source is slow. If you are sure your timer" 128 "* this bug, please use \"acpi_pm_good\" to disable the workaround\n");
131 " does not have\n"
132 "* this bug, please use \"acpi_pm_good\" to disable the"
133 " workaround\n");
134 129
135 acpi_pm_need_workaround(); 130 acpi_pm_need_workaround();
136} 131}
@@ -162,8 +157,7 @@ static int verify_pmtmr_rate(void)
162 /* Check that the PMTMR delta is within 5% of what we expect */ 157 /* Check that the PMTMR delta is within 5% of what we expect */
163 if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 || 158 if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
164 delta > (PMTMR_EXPECTED_RATE * 21) / 20) { 159 delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
165 printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% " 160 pr_info("PM-Timer running at invalid rate: %lu%% of normal - aborting.\n",
166 "of normal - aborting.\n",
167 100UL * delta / PMTMR_EXPECTED_RATE); 161 100UL * delta / PMTMR_EXPECTED_RATE);
168 return -1; 162 return -1;
169 } 163 }
@@ -199,15 +193,14 @@ static int __init init_acpi_pm_clocksource(void)
199 break; 193 break;
200 if ((value2 < value1) && ((value2) < 0xFFF)) 194 if ((value2 < value1) && ((value2) < 0xFFF))
201 break; 195 break;
202 printk(KERN_INFO "PM-Timer had inconsistent results:" 196 pr_info("PM-Timer had inconsistent results: %#llx, %#llx - aborting.\n",
203 " %#llx, %#llx - aborting.\n", 197 value1, value2);
204 value1, value2);
205 pmtmr_ioport = 0; 198 pmtmr_ioport = 0;
206 return -EINVAL; 199 return -EINVAL;
207 } 200 }
208 if (i == ACPI_PM_READ_CHECKS) { 201 if (i == ACPI_PM_READ_CHECKS) {
209 printk(KERN_INFO "PM-Timer failed consistency check " 202 pr_info("PM-Timer failed consistency check (%#llx) - aborting.\n",
210 " (%#llx) - aborting.\n", value1); 203 value1);
211 pmtmr_ioport = 0; 204 pmtmr_ioport = 0;
212 return -ENODEV; 205 return -ENODEV;
213 } 206 }
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index a2cb6fae9295..d189d8cb69f7 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -99,17 +99,17 @@ static void gt_compare_set(unsigned long delta, int periodic)
99 99
100 counter += delta; 100 counter += delta;
101 ctrl = GT_CONTROL_TIMER_ENABLE; 101 ctrl = GT_CONTROL_TIMER_ENABLE;
102 writel(ctrl, gt_base + GT_CONTROL); 102 writel_relaxed(ctrl, gt_base + GT_CONTROL);
103 writel(lower_32_bits(counter), gt_base + GT_COMP0); 103 writel_relaxed(lower_32_bits(counter), gt_base + GT_COMP0);
104 writel(upper_32_bits(counter), gt_base + GT_COMP1); 104 writel_relaxed(upper_32_bits(counter), gt_base + GT_COMP1);
105 105
106 if (periodic) { 106 if (periodic) {
107 writel(delta, gt_base + GT_AUTO_INC); 107 writel_relaxed(delta, gt_base + GT_AUTO_INC);
108 ctrl |= GT_CONTROL_AUTO_INC; 108 ctrl |= GT_CONTROL_AUTO_INC;
109 } 109 }
110 110
111 ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE; 111 ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE;
112 writel(ctrl, gt_base + GT_CONTROL); 112 writel_relaxed(ctrl, gt_base + GT_CONTROL);
113} 113}
114 114
115static int gt_clockevent_shutdown(struct clock_event_device *evt) 115static int gt_clockevent_shutdown(struct clock_event_device *evt)
@@ -195,12 +195,23 @@ static cycle_t gt_clocksource_read(struct clocksource *cs)
195 return gt_counter_read(); 195 return gt_counter_read();
196} 196}
197 197
198static void gt_resume(struct clocksource *cs)
199{
200 unsigned long ctrl;
201
202 ctrl = readl(gt_base + GT_CONTROL);
203 if (!(ctrl & GT_CONTROL_TIMER_ENABLE))
204 /* re-enable timer on resume */
205 writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
206}
207
198static struct clocksource gt_clocksource = { 208static struct clocksource gt_clocksource = {
199 .name = "arm_global_timer", 209 .name = "arm_global_timer",
200 .rating = 300, 210 .rating = 300,
201 .read = gt_clocksource_read, 211 .read = gt_clocksource_read,
202 .mask = CLOCKSOURCE_MASK(64), 212 .mask = CLOCKSOURCE_MASK(64),
203 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 213 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
214 .resume = gt_resume,
204}; 215};
205 216
206#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK 217#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c
index c76c75006ea6..63345260244d 100644
--- a/drivers/clocksource/dw_apb_timer.c
+++ b/drivers/clocksource/dw_apb_timer.c
@@ -49,20 +49,31 @@ clocksource_to_dw_apb_clocksource(struct clocksource *cs)
49 return container_of(cs, struct dw_apb_clocksource, cs); 49 return container_of(cs, struct dw_apb_clocksource, cs);
50} 50}
51 51
52static unsigned long apbt_readl(struct dw_apb_timer *timer, unsigned long offs) 52static inline u32 apbt_readl(struct dw_apb_timer *timer, unsigned long offs)
53{ 53{
54 return readl(timer->base + offs); 54 return readl(timer->base + offs);
55} 55}
56 56
57static void apbt_writel(struct dw_apb_timer *timer, unsigned long val, 57static inline void apbt_writel(struct dw_apb_timer *timer, u32 val,
58 unsigned long offs) 58 unsigned long offs)
59{ 59{
60 writel(val, timer->base + offs); 60 writel(val, timer->base + offs);
61} 61}
62 62
63static inline u32 apbt_readl_relaxed(struct dw_apb_timer *timer, unsigned long offs)
64{
65 return readl_relaxed(timer->base + offs);
66}
67
68static inline void apbt_writel_relaxed(struct dw_apb_timer *timer, u32 val,
69 unsigned long offs)
70{
71 writel_relaxed(val, timer->base + offs);
72}
73
63static void apbt_disable_int(struct dw_apb_timer *timer) 74static void apbt_disable_int(struct dw_apb_timer *timer)
64{ 75{
65 unsigned long ctrl = apbt_readl(timer, APBTMR_N_CONTROL); 76 u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL);
66 77
67 ctrl |= APBTMR_CONTROL_INT; 78 ctrl |= APBTMR_CONTROL_INT;
68 apbt_writel(timer, ctrl, APBTMR_N_CONTROL); 79 apbt_writel(timer, ctrl, APBTMR_N_CONTROL);
@@ -81,7 +92,7 @@ void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced)
81 92
82static void apbt_eoi(struct dw_apb_timer *timer) 93static void apbt_eoi(struct dw_apb_timer *timer)
83{ 94{
84 apbt_readl(timer, APBTMR_N_EOI); 95 apbt_readl_relaxed(timer, APBTMR_N_EOI);
85} 96}
86 97
87static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) 98static irqreturn_t dw_apb_clockevent_irq(int irq, void *data)
@@ -103,7 +114,7 @@ static irqreturn_t dw_apb_clockevent_irq(int irq, void *data)
103 114
104static void apbt_enable_int(struct dw_apb_timer *timer) 115static void apbt_enable_int(struct dw_apb_timer *timer)
105{ 116{
106 unsigned long ctrl = apbt_readl(timer, APBTMR_N_CONTROL); 117 u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL);
107 /* clear pending intr */ 118 /* clear pending intr */
108 apbt_readl(timer, APBTMR_N_EOI); 119 apbt_readl(timer, APBTMR_N_EOI);
109 ctrl &= ~APBTMR_CONTROL_INT; 120 ctrl &= ~APBTMR_CONTROL_INT;
@@ -113,7 +124,7 @@ static void apbt_enable_int(struct dw_apb_timer *timer)
113static int apbt_shutdown(struct clock_event_device *evt) 124static int apbt_shutdown(struct clock_event_device *evt)
114{ 125{
115 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 126 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
116 unsigned long ctrl; 127 u32 ctrl;
117 128
118 pr_debug("%s CPU %d state=shutdown\n", __func__, 129 pr_debug("%s CPU %d state=shutdown\n", __func__,
119 cpumask_first(evt->cpumask)); 130 cpumask_first(evt->cpumask));
@@ -127,7 +138,7 @@ static int apbt_shutdown(struct clock_event_device *evt)
127static int apbt_set_oneshot(struct clock_event_device *evt) 138static int apbt_set_oneshot(struct clock_event_device *evt)
128{ 139{
129 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 140 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
130 unsigned long ctrl; 141 u32 ctrl;
131 142
132 pr_debug("%s CPU %d state=oneshot\n", __func__, 143 pr_debug("%s CPU %d state=oneshot\n", __func__,
133 cpumask_first(evt->cpumask)); 144 cpumask_first(evt->cpumask));
@@ -160,7 +171,7 @@ static int apbt_set_periodic(struct clock_event_device *evt)
160{ 171{
161 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 172 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
162 unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); 173 unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ);
163 unsigned long ctrl; 174 u32 ctrl;
164 175
165 pr_debug("%s CPU %d state=periodic\n", __func__, 176 pr_debug("%s CPU %d state=periodic\n", __func__,
166 cpumask_first(evt->cpumask)); 177 cpumask_first(evt->cpumask));
@@ -196,17 +207,17 @@ static int apbt_resume(struct clock_event_device *evt)
196static int apbt_next_event(unsigned long delta, 207static int apbt_next_event(unsigned long delta,
197 struct clock_event_device *evt) 208 struct clock_event_device *evt)
198{ 209{
199 unsigned long ctrl; 210 u32 ctrl;
200 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 211 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
201 212
202 /* Disable timer */ 213 /* Disable timer */
203 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 214 ctrl = apbt_readl_relaxed(&dw_ced->timer, APBTMR_N_CONTROL);
204 ctrl &= ~APBTMR_CONTROL_ENABLE; 215 ctrl &= ~APBTMR_CONTROL_ENABLE;
205 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 216 apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
206 /* write new count */ 217 /* write new count */
207 apbt_writel(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT); 218 apbt_writel_relaxed(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT);
208 ctrl |= APBTMR_CONTROL_ENABLE; 219 ctrl |= APBTMR_CONTROL_ENABLE;
209 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 220 apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
210 221
211 return 0; 222 return 0;
212} 223}
@@ -323,7 +334,7 @@ void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
323 * start count down from 0xffff_ffff. this is done by toggling the 334 * start count down from 0xffff_ffff. this is done by toggling the
324 * enable bit then load initial load count to ~0. 335 * enable bit then load initial load count to ~0.
325 */ 336 */
326 unsigned long ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL); 337 u32 ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL);
327 338
328 ctrl &= ~APBTMR_CONTROL_ENABLE; 339 ctrl &= ~APBTMR_CONTROL_ENABLE;
329 apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); 340 apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL);
@@ -338,11 +349,12 @@ void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
338 349
339static cycle_t __apbt_read_clocksource(struct clocksource *cs) 350static cycle_t __apbt_read_clocksource(struct clocksource *cs)
340{ 351{
341 unsigned long current_count; 352 u32 current_count;
342 struct dw_apb_clocksource *dw_cs = 353 struct dw_apb_clocksource *dw_cs =
343 clocksource_to_dw_apb_clocksource(cs); 354 clocksource_to_dw_apb_clocksource(cs);
344 355
345 current_count = apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); 356 current_count = apbt_readl_relaxed(&dw_cs->timer,
357 APBTMR_N_CURRENT_VALUE);
346 358
347 return (cycle_t)~current_count; 359 return (cycle_t)~current_count;
348} 360}
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
index a19a3f619cc7..860843cef572 100644
--- a/drivers/clocksource/dw_apb_timer_of.c
+++ b/drivers/clocksource/dw_apb_timer_of.c
@@ -16,6 +16,7 @@
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19#include <linux/delay.h>
19#include <linux/dw_apb_timer.h> 20#include <linux/dw_apb_timer.h>
20#include <linux/of.h> 21#include <linux/of.h>
21#include <linux/of_address.h> 22#include <linux/of_address.h>
@@ -130,6 +131,17 @@ static void __init init_sched_clock(void)
130 sched_clock_register(read_sched_clock, 32, sched_rate); 131 sched_clock_register(read_sched_clock, 32, sched_rate);
131} 132}
132 133
134#ifdef CONFIG_ARM
135static unsigned long dw_apb_delay_timer_read(void)
136{
137 return ~readl_relaxed(sched_io_base);
138}
139
140static struct delay_timer dw_apb_delay_timer = {
141 .read_current_timer = dw_apb_delay_timer_read,
142};
143#endif
144
133static int num_called; 145static int num_called;
134static void __init dw_apb_timer_init(struct device_node *timer) 146static void __init dw_apb_timer_init(struct device_node *timer)
135{ 147{
@@ -142,6 +154,10 @@ static void __init dw_apb_timer_init(struct device_node *timer)
142 pr_debug("%s: found clocksource timer\n", __func__); 154 pr_debug("%s: found clocksource timer\n", __func__);
143 add_clocksource(timer); 155 add_clocksource(timer);
144 init_sched_clock(); 156 init_sched_clock();
157#ifdef CONFIG_ARM
158 dw_apb_delay_timer.freq = sched_rate;
159 register_current_timer_delay(&dw_apb_delay_timer);
160#endif
145 break; 161 break;
146 default: 162 default:
147 break; 163 break;
diff --git a/drivers/clocksource/h8300_timer16.c b/drivers/clocksource/h8300_timer16.c
index 0e076c6fc006..75c44079b345 100644
--- a/drivers/clocksource/h8300_timer16.c
+++ b/drivers/clocksource/h8300_timer16.c
@@ -4,85 +4,56 @@
4 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp> 4 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp>
5 */ 5 */
6 6
7#include <linux/errno.h>
8#include <linux/kernel.h>
9#include <linux/param.h>
10#include <linux/string.h>
11#include <linux/slab.h>
12#include <linux/interrupt.h> 7#include <linux/interrupt.h>
13#include <linux/init.h> 8#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/clocksource.h> 9#include <linux/clocksource.h>
16#include <linux/module.h>
17#include <linux/clk.h> 10#include <linux/clk.h>
18#include <linux/io.h> 11#include <linux/io.h>
19#include <linux/of.h> 12#include <linux/of.h>
20 13#include <linux/of_address.h>
21#include <asm/segment.h> 14#include <linux/of_irq.h>
22#include <asm/irq.h>
23 15
24#define TSTR 0 16#define TSTR 0
25#define TSNC 1
26#define TMDR 2
27#define TOLR 3
28#define TISRA 4
29#define TISRB 5
30#define TISRC 6 17#define TISRC 6
31 18
32#define TCR 0 19#define TCR 0
33#define TIOR 1
34#define TCNT 2 20#define TCNT 2
35#define GRA 4
36#define GRB 6
37
38#define FLAG_REPROGRAM (1 << 0)
39#define FLAG_SKIPEVENT (1 << 1)
40#define FLAG_IRQCONTEXT (1 << 2)
41#define FLAG_STARTED (1 << 3)
42 21
43#define ONESHOT 0 22#define bset(b, a) iowrite8(ioread8(a) | (1 << (b)), (a))
44#define PERIODIC 1 23#define bclr(b, a) iowrite8(ioread8(a) & ~(1 << (b)), (a))
45
46#define RELATIVE 0
47#define ABSOLUTE 1
48 24
49struct timer16_priv { 25struct timer16_priv {
50 struct platform_device *pdev;
51 struct clocksource cs; 26 struct clocksource cs;
52 struct irqaction irqaction;
53 unsigned long total_cycles; 27 unsigned long total_cycles;
54 unsigned long mapbase; 28 void __iomem *mapbase;
55 unsigned long mapcommon; 29 void __iomem *mapcommon;
56 unsigned long flags;
57 unsigned short gra;
58 unsigned short cs_enabled; 30 unsigned short cs_enabled;
59 unsigned char enb; 31 unsigned char enb;
60 unsigned char imfa;
61 unsigned char imiea;
62 unsigned char ovf; 32 unsigned char ovf;
63 raw_spinlock_t lock; 33 unsigned char ovie;
64 struct clk *clk;
65}; 34};
66 35
67static unsigned long timer16_get_counter(struct timer16_priv *p) 36static unsigned long timer16_get_counter(struct timer16_priv *p)
68{ 37{
69 unsigned long v1, v2, v3; 38 unsigned short v1, v2, v3;
70 int o1, o2; 39 unsigned char o1, o2;
71 40
72 o1 = ctrl_inb(p->mapcommon + TISRC) & p->ovf; 41 o1 = ioread8(p->mapcommon + TISRC) & p->ovf;
73 42
74 /* Make sure the timer value is stable. Stolen from acpi_pm.c */ 43 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
75 do { 44 do {
76 o2 = o1; 45 o2 = o1;
77 v1 = ctrl_inw(p->mapbase + TCNT); 46 v1 = ioread16be(p->mapbase + TCNT);
78 v2 = ctrl_inw(p->mapbase + TCNT); 47 v2 = ioread16be(p->mapbase + TCNT);
79 v3 = ctrl_inw(p->mapbase + TCNT); 48 v3 = ioread16be(p->mapbase + TCNT);
80 o1 = ctrl_inb(p->mapcommon + TISRC) & p->ovf; 49 o1 = ioread8(p->mapcommon + TISRC) & p->ovf;
81 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) 50 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
82 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); 51 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
83 52
84 v2 |= 0x10000; 53 if (likely(!o1))
85 return v2; 54 return v2;
55 else
56 return v2 + 0x10000;
86} 57}
87 58
88 59
@@ -90,8 +61,7 @@ static irqreturn_t timer16_interrupt(int irq, void *dev_id)
90{ 61{
91 struct timer16_priv *p = (struct timer16_priv *)dev_id; 62 struct timer16_priv *p = (struct timer16_priv *)dev_id;
92 63
93 ctrl_outb(ctrl_inb(p->mapcommon + TISRA) & ~p->imfa, 64 bclr(p->ovf, p->mapcommon + TISRC);
94 p->mapcommon + TISRA);
95 p->total_cycles += 0x10000; 65 p->total_cycles += 0x10000;
96 66
97 return IRQ_HANDLED; 67 return IRQ_HANDLED;
@@ -105,13 +75,10 @@ static inline struct timer16_priv *cs_to_priv(struct clocksource *cs)
105static cycle_t timer16_clocksource_read(struct clocksource *cs) 75static cycle_t timer16_clocksource_read(struct clocksource *cs)
106{ 76{
107 struct timer16_priv *p = cs_to_priv(cs); 77 struct timer16_priv *p = cs_to_priv(cs);
108 unsigned long flags, raw; 78 unsigned long raw, value;
109 unsigned long value;
110 79
111 raw_spin_lock_irqsave(&p->lock, flags);
112 value = p->total_cycles; 80 value = p->total_cycles;
113 raw = timer16_get_counter(p); 81 raw = timer16_get_counter(p);
114 raw_spin_unlock_irqrestore(&p->lock, flags);
115 82
116 return value + raw; 83 return value + raw;
117} 84}
@@ -123,10 +90,10 @@ static int timer16_enable(struct clocksource *cs)
123 WARN_ON(p->cs_enabled); 90 WARN_ON(p->cs_enabled);
124 91
125 p->total_cycles = 0; 92 p->total_cycles = 0;
126 ctrl_outw(0x0000, p->mapbase + TCNT); 93 iowrite16be(0x0000, p->mapbase + TCNT);
127 ctrl_outb(0x83, p->mapbase + TCR); 94 iowrite8(0x83, p->mapbase + TCR);
128 ctrl_outb(ctrl_inb(p->mapcommon + TSTR) | p->enb, 95 bset(p->ovie, p->mapcommon + TISRC);
129 p->mapcommon + TSTR); 96 bset(p->enb, p->mapcommon + TSTR);
130 97
131 p->cs_enabled = true; 98 p->cs_enabled = true;
132 return 0; 99 return 0;
@@ -138,116 +105,83 @@ static void timer16_disable(struct clocksource *cs)
138 105
139 WARN_ON(!p->cs_enabled); 106 WARN_ON(!p->cs_enabled);
140 107
141 ctrl_outb(ctrl_inb(p->mapcommon + TSTR) & ~p->enb, 108 bclr(p->ovie, p->mapcommon + TISRC);
142 p->mapcommon + TSTR); 109 bclr(p->enb, p->mapcommon + TSTR);
143 110
144 p->cs_enabled = false; 111 p->cs_enabled = false;
145} 112}
146 113
114static struct timer16_priv timer16_priv = {
115 .cs = {
116 .name = "h8300_16timer",
117 .rating = 200,
118 .read = timer16_clocksource_read,
119 .enable = timer16_enable,
120 .disable = timer16_disable,
121 .mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8),
122 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
123 },
124};
125
147#define REG_CH 0 126#define REG_CH 0
148#define REG_COMM 1 127#define REG_COMM 1
149 128
150static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev) 129static void __init h8300_16timer_init(struct device_node *node)
151{ 130{
152 struct resource *res[2]; 131 void __iomem *base[2];
153 int ret, irq; 132 int ret, irq;
154 unsigned int ch; 133 unsigned int ch;
134 struct clk *clk;
155 135
156 p->pdev = pdev; 136 clk = of_clk_get(node, 0);
157 137 if (IS_ERR(clk)) {
158 res[REG_CH] = platform_get_resource(p->pdev, 138 pr_err("failed to get clock for clocksource\n");
159 IORESOURCE_MEM, REG_CH); 139 return;
160 res[REG_COMM] = platform_get_resource(p->pdev,
161 IORESOURCE_MEM, REG_COMM);
162 if (!res[REG_CH] || !res[REG_COMM]) {
163 dev_err(&p->pdev->dev, "failed to get I/O memory\n");
164 return -ENXIO;
165 }
166 irq = platform_get_irq(p->pdev, 0);
167 if (irq < 0) {
168 dev_err(&p->pdev->dev, "failed to get irq\n");
169 return irq;
170 } 140 }
171 141
172 p->clk = clk_get(&p->pdev->dev, "fck"); 142 base[REG_CH] = of_iomap(node, 0);
173 if (IS_ERR(p->clk)) { 143 if (!base[REG_CH]) {
174 dev_err(&p->pdev->dev, "can't get clk\n"); 144 pr_err("failed to map registers for clocksource\n");
175 return PTR_ERR(p->clk); 145 goto free_clk;
176 } 146 }
177 of_property_read_u32(p->pdev->dev.of_node, "renesas,channel", &ch);
178
179 p->pdev = pdev;
180 p->mapbase = res[REG_CH]->start;
181 p->mapcommon = res[REG_COMM]->start;
182 p->enb = 1 << ch;
183 p->imfa = 1 << ch;
184 p->imiea = 1 << (4 + ch);
185 p->cs.name = pdev->name;
186 p->cs.rating = 200;
187 p->cs.read = timer16_clocksource_read;
188 p->cs.enable = timer16_enable;
189 p->cs.disable = timer16_disable;
190 p->cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
191 p->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
192 147
193 ret = request_irq(irq, timer16_interrupt, 148 base[REG_COMM] = of_iomap(node, 1);
194 IRQF_TIMER, pdev->name, p); 149 if (!base[REG_COMM]) {
195 if (ret < 0) { 150 pr_err("failed to map registers for clocksource\n");
196 dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); 151 goto unmap_ch;
197 return ret;
198 } 152 }
199 153
200 clocksource_register_hz(&p->cs, clk_get_rate(p->clk) / 8); 154 irq = irq_of_parse_and_map(node, 0);
201 155 if (!irq) {
202 return 0; 156 pr_err("failed to get irq for clockevent\n");
203} 157 goto unmap_comm;
204
205static int timer16_probe(struct platform_device *pdev)
206{
207 struct timer16_priv *p = platform_get_drvdata(pdev);
208
209 if (p) {
210 dev_info(&pdev->dev, "kept as earlytimer\n");
211 return 0;
212 } 158 }
213 159
214 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 160 of_property_read_u32(node, "renesas,channel", &ch);
215 if (!p)
216 return -ENOMEM;
217 161
218 return timer16_setup(p, pdev); 162 timer16_priv.mapbase = base[REG_CH];
219} 163 timer16_priv.mapcommon = base[REG_COMM];
220 164 timer16_priv.enb = ch;
221static int timer16_remove(struct platform_device *pdev) 165 timer16_priv.ovf = ch;
222{ 166 timer16_priv.ovie = 4 + ch;
223 return -EBUSY;
224}
225 167
226static const struct of_device_id timer16_of_table[] = { 168 ret = request_irq(irq, timer16_interrupt,
227 { .compatible = "renesas,16bit-timer" }, 169 IRQF_TIMER, timer16_priv.cs.name, &timer16_priv);
228 { } 170 if (ret < 0) {
229}; 171 pr_err("failed to request irq %d of clocksource\n", irq);
230static struct platform_driver timer16_driver = { 172 goto unmap_comm;
231 .probe = timer16_probe,
232 .remove = timer16_remove,
233 .driver = {
234 .name = "h8300h-16timer",
235 .of_match_table = of_match_ptr(timer16_of_table),
236 } 173 }
237};
238 174
239static int __init timer16_init(void) 175 clocksource_register_hz(&timer16_priv.cs,
240{ 176 clk_get_rate(clk) / 8);
241 return platform_driver_register(&timer16_driver); 177 return;
242}
243 178
244static void __exit timer16_exit(void) 179unmap_comm:
245{ 180 iounmap(base[REG_COMM]);
246 platform_driver_unregister(&timer16_driver); 181unmap_ch:
182 iounmap(base[REG_CH]);
183free_clk:
184 clk_put(clk);
247} 185}
248 186
249subsys_initcall(timer16_init); 187CLOCKSOURCE_OF_DECLARE(h8300_16bit, "renesas,16bit-timer", h8300_16timer_init);
250module_exit(timer16_exit);
251MODULE_AUTHOR("Yoshinori Sato");
252MODULE_DESCRIPTION("H8/300H 16bit Timer Driver");
253MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c
index 44375d8b9bc4..c151941e1956 100644
--- a/drivers/clocksource/h8300_timer8.c
+++ b/drivers/clocksource/h8300_timer8.c
@@ -8,19 +8,15 @@
8 */ 8 */
9 9
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/sched.h>
12#include <linux/kernel.h> 11#include <linux/kernel.h>
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/clockchips.h> 14#include <linux/clockchips.h>
18#include <linux/module.h>
19#include <linux/clk.h> 15#include <linux/clk.h>
20#include <linux/io.h> 16#include <linux/io.h>
21#include <linux/of.h> 17#include <linux/of.h>
22 18#include <linux/of_address.h>
23#include <asm/irq.h> 19#include <linux/of_irq.h>
24 20
25#define _8TCR 0 21#define _8TCR 0
26#define _8TCSR 2 22#define _8TCSR 2
@@ -28,126 +24,74 @@
28#define TCORB 6 24#define TCORB 6
29#define _8TCNT 8 25#define _8TCNT 8
30 26
31#define FLAG_REPROGRAM (1 << 0) 27#define CMIEA 6
32#define FLAG_SKIPEVENT (1 << 1) 28#define CMFA 6
33#define FLAG_IRQCONTEXT (1 << 2) 29
34#define FLAG_STARTED (1 << 3) 30#define FLAG_STARTED (1 << 3)
35 31
36#define ONESHOT 0 32#define SCALE 64
37#define PERIODIC 1
38 33
39#define RELATIVE 0 34#define bset(b, a) iowrite8(ioread8(a) | (1 << (b)), (a))
40#define ABSOLUTE 1 35#define bclr(b, a) iowrite8(ioread8(a) & ~(1 << (b)), (a))
41 36
42struct timer8_priv { 37struct timer8_priv {
43 struct platform_device *pdev;
44 struct clock_event_device ced; 38 struct clock_event_device ced;
45 struct irqaction irqaction; 39 void __iomem *mapbase;
46 unsigned long mapbase;
47 raw_spinlock_t lock;
48 unsigned long flags; 40 unsigned long flags;
49 unsigned int rate; 41 unsigned int rate;
50 unsigned int tcora;
51 struct clk *pclk;
52}; 42};
53 43
54static unsigned long timer8_get_counter(struct timer8_priv *p)
55{
56 unsigned long v1, v2, v3;
57 int o1, o2;
58
59 o1 = ctrl_inb(p->mapbase + _8TCSR) & 0x20;
60
61 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
62 do {
63 o2 = o1;
64 v1 = ctrl_inw(p->mapbase + _8TCNT);
65 v2 = ctrl_inw(p->mapbase + _8TCNT);
66 v3 = ctrl_inw(p->mapbase + _8TCNT);
67 o1 = ctrl_inb(p->mapbase + _8TCSR) & 0x20;
68 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
69 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
70
71 v2 |= o1 << 10;
72 return v2;
73}
74
75static irqreturn_t timer8_interrupt(int irq, void *dev_id) 44static irqreturn_t timer8_interrupt(int irq, void *dev_id)
76{ 45{
77 struct timer8_priv *p = dev_id; 46 struct timer8_priv *p = dev_id;
78 47
79 ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x40, 48 if (clockevent_state_oneshot(&p->ced))
80 p->mapbase + _8TCSR); 49 iowrite16be(0x0000, p->mapbase + _8TCR);
81 p->flags |= FLAG_IRQCONTEXT; 50
82 ctrl_outw(p->tcora, p->mapbase + TCORA); 51 p->ced.event_handler(&p->ced);
83 if (!(p->flags & FLAG_SKIPEVENT)) { 52
84 if (clockevent_state_oneshot(&p->ced)) 53 bclr(CMFA, p->mapbase + _8TCSR);
85 ctrl_outw(0x0000, p->mapbase + _8TCR);
86 p->ced.event_handler(&p->ced);
87 }
88 p->flags &= ~(FLAG_SKIPEVENT | FLAG_IRQCONTEXT);
89 54
90 return IRQ_HANDLED; 55 return IRQ_HANDLED;
91} 56}
92 57
93static void timer8_set_next(struct timer8_priv *p, unsigned long delta) 58static void timer8_set_next(struct timer8_priv *p, unsigned long delta)
94{ 59{
95 unsigned long flags;
96 unsigned long now;
97
98 raw_spin_lock_irqsave(&p->lock, flags);
99 if (delta >= 0x10000) 60 if (delta >= 0x10000)
100 dev_warn(&p->pdev->dev, "delta out of range\n"); 61 pr_warn("delta out of range\n");
101 now = timer8_get_counter(p); 62 bclr(CMIEA, p->mapbase + _8TCR);
102 p->tcora = delta; 63 iowrite16be(delta, p->mapbase + TCORA);
103 ctrl_outb(ctrl_inb(p->mapbase + _8TCR) | 0x40, p->mapbase + _8TCR); 64 iowrite16be(0x0000, p->mapbase + _8TCNT);
104 if (delta > now) 65 bclr(CMFA, p->mapbase + _8TCSR);
105 ctrl_outw(delta, p->mapbase + TCORA); 66 bset(CMIEA, p->mapbase + _8TCR);
106 else
107 ctrl_outw(now + 1, p->mapbase + TCORA);
108
109 raw_spin_unlock_irqrestore(&p->lock, flags);
110} 67}
111 68
112static int timer8_enable(struct timer8_priv *p) 69static int timer8_enable(struct timer8_priv *p)
113{ 70{
114 p->rate = clk_get_rate(p->pclk) / 64; 71 iowrite16be(0xffff, p->mapbase + TCORA);
115 ctrl_outw(0xffff, p->mapbase + TCORA); 72 iowrite16be(0x0000, p->mapbase + _8TCNT);
116 ctrl_outw(0x0000, p->mapbase + _8TCNT); 73 iowrite16be(0x0c02, p->mapbase + _8TCR);
117 ctrl_outw(0x0c02, p->mapbase + _8TCR);
118 74
119 return 0; 75 return 0;
120} 76}
121 77
122static int timer8_start(struct timer8_priv *p) 78static int timer8_start(struct timer8_priv *p)
123{ 79{
124 int ret = 0; 80 int ret;
125 unsigned long flags;
126
127 raw_spin_lock_irqsave(&p->lock, flags);
128
129 if (!(p->flags & FLAG_STARTED))
130 ret = timer8_enable(p);
131 81
132 if (ret) 82 if ((p->flags & FLAG_STARTED))
133 goto out; 83 return 0;
134 p->flags |= FLAG_STARTED;
135 84
136 out: 85 ret = timer8_enable(p);
137 raw_spin_unlock_irqrestore(&p->lock, flags); 86 if (!ret)
87 p->flags |= FLAG_STARTED;
138 88
139 return ret; 89 return ret;
140} 90}
141 91
142static void timer8_stop(struct timer8_priv *p) 92static void timer8_stop(struct timer8_priv *p)
143{ 93{
144 unsigned long flags; 94 iowrite16be(0x0000, p->mapbase + _8TCR);
145
146 raw_spin_lock_irqsave(&p->lock, flags);
147
148 ctrl_outw(0x0000, p->mapbase + _8TCR);
149
150 raw_spin_unlock_irqrestore(&p->lock, flags);
151} 95}
152 96
153static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced) 97static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced)
@@ -155,7 +99,7 @@ static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced)
155 return container_of(ced, struct timer8_priv, ced); 99 return container_of(ced, struct timer8_priv, ced);
156} 100}
157 101
158static void timer8_clock_event_start(struct timer8_priv *p, int periodic) 102static void timer8_clock_event_start(struct timer8_priv *p, unsigned long delta)
159{ 103{
160 struct clock_event_device *ced = &p->ced; 104 struct clock_event_device *ced = &p->ced;
161 105
@@ -166,7 +110,7 @@ static void timer8_clock_event_start(struct timer8_priv *p, int periodic)
166 ced->max_delta_ns = clockevent_delta2ns(0xffff, ced); 110 ced->max_delta_ns = clockevent_delta2ns(0xffff, ced);
167 ced->min_delta_ns = clockevent_delta2ns(0x0001, ced); 111 ced->min_delta_ns = clockevent_delta2ns(0x0001, ced);
168 112
169 timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000); 113 timer8_set_next(p, delta);
170} 114}
171 115
172static int timer8_clock_event_shutdown(struct clock_event_device *ced) 116static int timer8_clock_event_shutdown(struct clock_event_device *ced)
@@ -179,9 +123,9 @@ static int timer8_clock_event_periodic(struct clock_event_device *ced)
179{ 123{
180 struct timer8_priv *p = ced_to_priv(ced); 124 struct timer8_priv *p = ced_to_priv(ced);
181 125
182 dev_info(&p->pdev->dev, "used for periodic clock events\n"); 126 pr_info("%s: used for periodic clock events\n", ced->name);
183 timer8_stop(p); 127 timer8_stop(p);
184 timer8_clock_event_start(p, PERIODIC); 128 timer8_clock_event_start(p, (p->rate + HZ/2) / HZ);
185 129
186 return 0; 130 return 0;
187} 131}
@@ -190,9 +134,9 @@ static int timer8_clock_event_oneshot(struct clock_event_device *ced)
190{ 134{
191 struct timer8_priv *p = ced_to_priv(ced); 135 struct timer8_priv *p = ced_to_priv(ced);
192 136
193 dev_info(&p->pdev->dev, "used for oneshot clock events\n"); 137 pr_info("%s: used for oneshot clock events\n", ced->name);
194 timer8_stop(p); 138 timer8_stop(p);
195 timer8_clock_event_start(p, ONESHOT); 139 timer8_clock_event_start(p, 0x10000);
196 140
197 return 0; 141 return 0;
198} 142}
@@ -208,110 +152,64 @@ static int timer8_clock_event_next(unsigned long delta,
208 return 0; 152 return 0;
209} 153}
210 154
211static int timer8_setup(struct timer8_priv *p, 155static struct timer8_priv timer8_priv = {
212 struct platform_device *pdev) 156 .ced = {
157 .name = "h8300_8timer",
158 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
159 .rating = 200,
160 .set_next_event = timer8_clock_event_next,
161 .set_state_shutdown = timer8_clock_event_shutdown,
162 .set_state_periodic = timer8_clock_event_periodic,
163 .set_state_oneshot = timer8_clock_event_oneshot,
164 },
165};
166
167static void __init h8300_8timer_init(struct device_node *node)
213{ 168{
214 struct resource *res; 169 void __iomem *base;
215 int irq; 170 int irq;
216 int ret; 171 struct clk *clk;
217 172
218 p->pdev = pdev; 173 clk = of_clk_get(node, 0);
219 174 if (IS_ERR(clk)) {
220 res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); 175 pr_err("failed to get clock for clockevent\n");
221 if (!res) { 176 return;
222 dev_err(&p->pdev->dev, "failed to get I/O memory\n");
223 return -ENXIO;
224 } 177 }
225 178
226 irq = platform_get_irq(p->pdev, 0); 179 base = of_iomap(node, 0);
227 if (irq < 0) { 180 if (!base) {
228 dev_err(&p->pdev->dev, "failed to get irq\n"); 181 pr_err("failed to map registers for clockevent\n");
229 return -ENXIO; 182 goto free_clk;
230 } 183 }
231 184
232 p->mapbase = res->start; 185 irq = irq_of_parse_and_map(node, 0);
233 186 if (!irq) {
234 p->irqaction.name = dev_name(&p->pdev->dev); 187 pr_err("failed to get irq for clockevent\n");
235 p->irqaction.handler = timer8_interrupt; 188 goto unmap_reg;
236 p->irqaction.dev_id = p;
237 p->irqaction.flags = IRQF_TIMER;
238
239 p->pclk = clk_get(&p->pdev->dev, "fck");
240 if (IS_ERR(p->pclk)) {
241 dev_err(&p->pdev->dev, "can't get clk\n");
242 return PTR_ERR(p->pclk);
243 } 189 }
244 190
245 p->ced.name = pdev->name; 191 timer8_priv.mapbase = base;
246 p->ced.features = CLOCK_EVT_FEAT_PERIODIC |
247 CLOCK_EVT_FEAT_ONESHOT;
248 p->ced.rating = 200;
249 p->ced.cpumask = cpumask_of(0);
250 p->ced.set_next_event = timer8_clock_event_next;
251 p->ced.set_state_shutdown = timer8_clock_event_shutdown;
252 p->ced.set_state_periodic = timer8_clock_event_periodic;
253 p->ced.set_state_oneshot = timer8_clock_event_oneshot;
254
255 ret = setup_irq(irq, &p->irqaction);
256 if (ret < 0) {
257 dev_err(&p->pdev->dev,
258 "failed to request irq %d\n", irq);
259 return ret;
260 }
261 clockevents_register_device(&p->ced);
262 platform_set_drvdata(pdev, p);
263 192
264 return 0; 193 timer8_priv.rate = clk_get_rate(clk) / SCALE;
265} 194 if (!timer8_priv.rate) {
266 195 pr_err("Failed to get rate for the clocksource\n");
267static int timer8_probe(struct platform_device *pdev) 196 goto unmap_reg;
268{
269 struct timer8_priv *p = platform_get_drvdata(pdev);
270
271 if (p) {
272 dev_info(&pdev->dev, "kept as earlytimer\n");
273 return 0;
274 } 197 }
275 198
276 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 199 if (request_irq(irq, timer8_interrupt, IRQF_TIMER,
277 if (!p) 200 timer8_priv.ced.name, &timer8_priv) < 0) {
278 return -ENOMEM; 201 pr_err("failed to request irq %d for clockevent\n", irq);
279 202 goto unmap_reg;
280 return timer8_setup(p, pdev);
281}
282
283static int timer8_remove(struct platform_device *pdev)
284{
285 return -EBUSY;
286}
287
288static const struct of_device_id timer8_of_table[] __maybe_unused = {
289 { .compatible = "renesas,8bit-timer" },
290 { }
291};
292
293MODULE_DEVICE_TABLE(of, timer8_of_table);
294static struct platform_driver timer8_driver = {
295 .probe = timer8_probe,
296 .remove = timer8_remove,
297 .driver = {
298 .name = "h8300-8timer",
299 .of_match_table = of_match_ptr(timer8_of_table),
300 } 203 }
301};
302 204
303static int __init timer8_init(void) 205 clockevents_config_and_register(&timer8_priv.ced,
304{ 206 timer8_priv.rate, 1, 0x0000ffff);
305 return platform_driver_register(&timer8_driver);
306}
307 207
308static void __exit timer8_exit(void) 208 return;
309{ 209unmap_reg:
310 platform_driver_unregister(&timer8_driver); 210 iounmap(base);
211free_clk:
212 clk_put(clk);
311} 213}
312 214
313subsys_initcall(timer8_init); 215CLOCKSOURCE_OF_DECLARE(h8300_8bit, "renesas,8bit-timer", h8300_8timer_init);
314module_exit(timer8_exit);
315MODULE_AUTHOR("Yoshinori Sato");
316MODULE_DESCRIPTION("H8/300 8bit Timer Driver");
317MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/h8300_tpu.c b/drivers/clocksource/h8300_tpu.c
index 5487410bfabb..d4c1a287c262 100644
--- a/drivers/clocksource/h8300_tpu.c
+++ b/drivers/clocksource/h8300_tpu.c
@@ -1,42 +1,30 @@
1/* 1/*
2 * H8/300 TPU Driver 2 * H8S TPU Driver
3 * 3 *
4 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp> 4 * Copyright 2015 Yoshinori Sato <ysato@users.sourcefoge.jp>
5 * 5 *
6 */ 6 */
7 7
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/sched.h>
10#include <linux/kernel.h> 9#include <linux/kernel.h>
11#include <linux/interrupt.h>
12#include <linux/init.h> 10#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/slab.h>
15#include <linux/clocksource.h> 11#include <linux/clocksource.h>
16#include <linux/module.h>
17#include <linux/clk.h> 12#include <linux/clk.h>
18#include <linux/io.h> 13#include <linux/io.h>
19#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/of_irq.h>
20 17
21#include <asm/irq.h> 18#define TCR 0x0
19#define TSR 0x5
20#define TCNT 0x6
22 21
23#define TCR 0 22#define TCFV 0x10
24#define TMDR 1
25#define TIOR 2
26#define TER 4
27#define TSR 5
28#define TCNT 6
29#define TGRA 8
30#define TGRB 10
31#define TGRC 12
32#define TGRD 14
33 23
34struct tpu_priv { 24struct tpu_priv {
35 struct platform_device *pdev;
36 struct clocksource cs; 25 struct clocksource cs;
37 struct clk *clk; 26 void __iomem *mapbase1;
38 unsigned long mapbase1; 27 void __iomem *mapbase2;
39 unsigned long mapbase2;
40 raw_spinlock_t lock; 28 raw_spinlock_t lock;
41 unsigned int cs_enabled; 29 unsigned int cs_enabled;
42}; 30};
@@ -45,8 +33,8 @@ static inline unsigned long read_tcnt32(struct tpu_priv *p)
45{ 33{
46 unsigned long tcnt; 34 unsigned long tcnt;
47 35
48 tcnt = ctrl_inw(p->mapbase1 + TCNT) << 16; 36 tcnt = ioread16be(p->mapbase1 + TCNT) << 16;
49 tcnt |= ctrl_inw(p->mapbase2 + TCNT); 37 tcnt |= ioread16be(p->mapbase2 + TCNT);
50 return tcnt; 38 return tcnt;
51} 39}
52 40
@@ -55,7 +43,7 @@ static int tpu_get_counter(struct tpu_priv *p, unsigned long long *val)
55 unsigned long v1, v2, v3; 43 unsigned long v1, v2, v3;
56 int o1, o2; 44 int o1, o2;
57 45
58 o1 = ctrl_inb(p->mapbase1 + TSR) & 0x10; 46 o1 = ioread8(p->mapbase1 + TSR) & TCFV;
59 47
60 /* Make sure the timer value is stable. Stolen from acpi_pm.c */ 48 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
61 do { 49 do {
@@ -63,7 +51,7 @@ static int tpu_get_counter(struct tpu_priv *p, unsigned long long *val)
63 v1 = read_tcnt32(p); 51 v1 = read_tcnt32(p);
64 v2 = read_tcnt32(p); 52 v2 = read_tcnt32(p);
65 v3 = read_tcnt32(p); 53 v3 = read_tcnt32(p);
66 o1 = ctrl_inb(p->mapbase1 + TSR) & 0x10; 54 o1 = ioread8(p->mapbase1 + TSR) & TCFV;
67 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) 55 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
68 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); 56 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
69 57
@@ -96,10 +84,10 @@ static int tpu_clocksource_enable(struct clocksource *cs)
96 84
97 WARN_ON(p->cs_enabled); 85 WARN_ON(p->cs_enabled);
98 86
99 ctrl_outw(0, p->mapbase1 + TCNT); 87 iowrite16be(0, p->mapbase1 + TCNT);
100 ctrl_outw(0, p->mapbase2 + TCNT); 88 iowrite16be(0, p->mapbase2 + TCNT);
101 ctrl_outb(0x0f, p->mapbase1 + TCR); 89 iowrite8(0x0f, p->mapbase1 + TCR);
102 ctrl_outb(0x03, p->mapbase2 + TCR); 90 iowrite8(0x03, p->mapbase2 + TCR);
103 91
104 p->cs_enabled = true; 92 p->cs_enabled = true;
105 return 0; 93 return 0;
@@ -111,96 +99,59 @@ static void tpu_clocksource_disable(struct clocksource *cs)
111 99
112 WARN_ON(!p->cs_enabled); 100 WARN_ON(!p->cs_enabled);
113 101
114 ctrl_outb(0, p->mapbase1 + TCR); 102 iowrite8(0, p->mapbase1 + TCR);
115 ctrl_outb(0, p->mapbase2 + TCR); 103 iowrite8(0, p->mapbase2 + TCR);
116 p->cs_enabled = false; 104 p->cs_enabled = false;
117} 105}
118 106
107static struct tpu_priv tpu_priv = {
108 .cs = {
109 .name = "H8S_TPU",
110 .rating = 200,
111 .read = tpu_clocksource_read,
112 .enable = tpu_clocksource_enable,
113 .disable = tpu_clocksource_disable,
114 .mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8),
115 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
116 },
117};
118
119#define CH_L 0 119#define CH_L 0
120#define CH_H 1 120#define CH_H 1
121 121
122static int __init tpu_setup(struct tpu_priv *p, struct platform_device *pdev) 122static void __init h8300_tpu_init(struct device_node *node)
123{ 123{
124 struct resource *res[2]; 124 void __iomem *base[2];
125 125 struct clk *clk;
126 p->pdev = pdev;
127 126
128 res[CH_L] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_L); 127 clk = of_clk_get(node, 0);
129 res[CH_H] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_H); 128 if (IS_ERR(clk)) {
130 if (!res[CH_L] || !res[CH_H]) { 129 pr_err("failed to get clock for clocksource\n");
131 dev_err(&p->pdev->dev, "failed to get I/O memory\n"); 130 return;
132 return -ENXIO;
133 } 131 }
134 132
135 p->clk = clk_get(&p->pdev->dev, "fck"); 133 base[CH_L] = of_iomap(node, CH_L);
136 if (IS_ERR(p->clk)) { 134 if (!base[CH_L]) {
137 dev_err(&p->pdev->dev, "can't get clk\n"); 135 pr_err("failed to map registers for clocksource\n");
138 return PTR_ERR(p->clk); 136 goto free_clk;
139 } 137 }
140 138 base[CH_H] = of_iomap(node, CH_H);
141 p->mapbase1 = res[CH_L]->start; 139 if (!base[CH_H]) {
142 p->mapbase2 = res[CH_H]->start; 140 pr_err("failed to map registers for clocksource\n");
143 141 goto unmap_L;
144 p->cs.name = pdev->name;
145 p->cs.rating = 200;
146 p->cs.read = tpu_clocksource_read;
147 p->cs.enable = tpu_clocksource_enable;
148 p->cs.disable = tpu_clocksource_disable;
149 p->cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
150 p->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
151 clocksource_register_hz(&p->cs, clk_get_rate(p->clk) / 64);
152 platform_set_drvdata(pdev, p);
153
154 return 0;
155}
156
157static int tpu_probe(struct platform_device *pdev)
158{
159 struct tpu_priv *p = platform_get_drvdata(pdev);
160
161 if (p) {
162 dev_info(&pdev->dev, "kept as earlytimer\n");
163 return 0;
164 } 142 }
165 143
166 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 144 tpu_priv.mapbase1 = base[CH_L];
167 if (!p) 145 tpu_priv.mapbase2 = base[CH_H];
168 return -ENOMEM;
169 146
170 return tpu_setup(p, pdev); 147 clocksource_register_hz(&tpu_priv.cs, clk_get_rate(clk) / 64);
171}
172
173static int tpu_remove(struct platform_device *pdev)
174{
175 return -EBUSY;
176}
177
178static const struct of_device_id tpu_of_table[] = {
179 { .compatible = "renesas,tpu" },
180 { }
181};
182 148
183static struct platform_driver tpu_driver = { 149 return;
184 .probe = tpu_probe,
185 .remove = tpu_remove,
186 .driver = {
187 .name = "h8s-tpu",
188 .of_match_table = of_match_ptr(tpu_of_table),
189 }
190};
191
192static int __init tpu_init(void)
193{
194 return platform_driver_register(&tpu_driver);
195}
196 150
197static void __exit tpu_exit(void) 151unmap_L:
198{ 152 iounmap(base[CH_H]);
199 platform_driver_unregister(&tpu_driver); 153free_clk:
154 clk_put(clk);
200} 155}
201 156
202subsys_initcall(tpu_init); 157CLOCKSOURCE_OF_DECLARE(h8300_tpu, "renesas,tpu", h8300_tpu_init);
203module_exit(tpu_exit);
204MODULE_AUTHOR("Yoshinori Sato");
205MODULE_DESCRIPTION("H8S Timer Pulse Unit Driver");
206MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index fbfc74685e6a..d67bc356488f 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -16,6 +16,8 @@
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 */ 17 */
18 18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
19#include <linux/clk.h> 21#include <linux/clk.h>
20#include <linux/clockchips.h> 22#include <linux/clockchips.h>
21#include <linux/interrupt.h> 23#include <linux/interrupt.h>
@@ -187,10 +189,8 @@ static void __init mtk_timer_init(struct device_node *node)
187 struct clk *clk; 189 struct clk *clk;
188 190
189 evt = kzalloc(sizeof(*evt), GFP_KERNEL); 191 evt = kzalloc(sizeof(*evt), GFP_KERNEL);
190 if (!evt) { 192 if (!evt)
191 pr_warn("Can't allocate mtk clock event driver struct");
192 return; 193 return;
193 }
194 194
195 evt->dev.name = "mtk_tick"; 195 evt->dev.name = "mtk_tick";
196 evt->dev.rating = 300; 196 evt->dev.rating = 300;
@@ -204,31 +204,31 @@ static void __init mtk_timer_init(struct device_node *node)
204 204
205 evt->gpt_base = of_io_request_and_map(node, 0, "mtk-timer"); 205 evt->gpt_base = of_io_request_and_map(node, 0, "mtk-timer");
206 if (IS_ERR(evt->gpt_base)) { 206 if (IS_ERR(evt->gpt_base)) {
207 pr_warn("Can't get resource\n"); 207 pr_err("Can't get resource\n");
208 return; 208 goto err_kzalloc;
209 } 209 }
210 210
211 evt->dev.irq = irq_of_parse_and_map(node, 0); 211 evt->dev.irq = irq_of_parse_and_map(node, 0);
212 if (evt->dev.irq <= 0) { 212 if (evt->dev.irq <= 0) {
213 pr_warn("Can't parse IRQ"); 213 pr_err("Can't parse IRQ\n");
214 goto err_mem; 214 goto err_mem;
215 } 215 }
216 216
217 clk = of_clk_get(node, 0); 217 clk = of_clk_get(node, 0);
218 if (IS_ERR(clk)) { 218 if (IS_ERR(clk)) {
219 pr_warn("Can't get timer clock"); 219 pr_err("Can't get timer clock\n");
220 goto err_irq; 220 goto err_irq;
221 } 221 }
222 222
223 if (clk_prepare_enable(clk)) { 223 if (clk_prepare_enable(clk)) {
224 pr_warn("Can't prepare clock"); 224 pr_err("Can't prepare clock\n");
225 goto err_clk_put; 225 goto err_clk_put;
226 } 226 }
227 rate = clk_get_rate(clk); 227 rate = clk_get_rate(clk);
228 228
229 if (request_irq(evt->dev.irq, mtk_timer_interrupt, 229 if (request_irq(evt->dev.irq, mtk_timer_interrupt,
230 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) { 230 IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
231 pr_warn("failed to setup irq %d\n", evt->dev.irq); 231 pr_err("failed to setup irq %d\n", evt->dev.irq);
232 goto err_clk_disable; 232 goto err_clk_disable;
233 } 233 }
234 234
@@ -260,5 +260,7 @@ err_mem:
260 iounmap(evt->gpt_base); 260 iounmap(evt->gpt_base);
261 of_address_to_resource(node, 0, &res); 261 of_address_to_resource(node, 0, &res);
262 release_mem_region(res.start, resource_size(&res)); 262 release_mem_region(res.start, resource_size(&res));
263err_kzalloc:
264 kfree(evt);
263} 265}
264CLOCKSOURCE_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init); 266CLOCKSOURCE_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init);
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index d3c1742ded1a..8c77a529d0d4 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -17,16 +17,16 @@
17 17
18#define TIMER_NAME "rk_timer" 18#define TIMER_NAME "rk_timer"
19 19
20#define TIMER_LOAD_COUNT0 0x00 20#define TIMER_LOAD_COUNT0 0x00
21#define TIMER_LOAD_COUNT1 0x04 21#define TIMER_LOAD_COUNT1 0x04
22#define TIMER_CONTROL_REG 0x10 22#define TIMER_CONTROL_REG 0x10
23#define TIMER_INT_STATUS 0x18 23#define TIMER_INT_STATUS 0x18
24 24
25#define TIMER_DISABLE 0x0 25#define TIMER_DISABLE 0x0
26#define TIMER_ENABLE 0x1 26#define TIMER_ENABLE 0x1
27#define TIMER_MODE_FREE_RUNNING (0 << 1) 27#define TIMER_MODE_FREE_RUNNING (0 << 1)
28#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1) 28#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
29#define TIMER_INT_UNMASK (1 << 2) 29#define TIMER_INT_UNMASK (1 << 2)
30 30
31struct bc_timer { 31struct bc_timer {
32 struct clock_event_device ce; 32 struct clock_event_device ce;
@@ -49,14 +49,12 @@ static inline void __iomem *rk_base(struct clock_event_device *ce)
49static inline void rk_timer_disable(struct clock_event_device *ce) 49static inline void rk_timer_disable(struct clock_event_device *ce)
50{ 50{
51 writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG); 51 writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG);
52 dsb();
53} 52}
54 53
55static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) 54static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags)
56{ 55{
57 writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, 56 writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags,
58 rk_base(ce) + TIMER_CONTROL_REG); 57 rk_base(ce) + TIMER_CONTROL_REG);
59 dsb();
60} 58}
61 59
62static void rk_timer_update_counter(unsigned long cycles, 60static void rk_timer_update_counter(unsigned long cycles,
@@ -64,13 +62,11 @@ static void rk_timer_update_counter(unsigned long cycles,
64{ 62{
65 writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0); 63 writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0);
66 writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1); 64 writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1);
67 dsb();
68} 65}
69 66
70static void rk_timer_interrupt_clear(struct clock_event_device *ce) 67static void rk_timer_interrupt_clear(struct clock_event_device *ce)
71{ 68{
72 writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS); 69 writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS);
73 dsb();
74} 70}
75 71
76static inline int rk_timer_set_next_event(unsigned long cycles, 72static inline int rk_timer_set_next_event(unsigned long cycles,
@@ -173,4 +169,5 @@ static void __init rk_timer_init(struct device_node *np)
173 169
174 clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); 170 clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX);
175} 171}
172
176CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); 173CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init);
diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c
index d297b30d2bc0..2bcecafdeaea 100644
--- a/drivers/clocksource/tango_xtal.c
+++ b/drivers/clocksource/tango_xtal.c
@@ -19,19 +19,6 @@ static u64 notrace read_sched_clock(void)
19 return read_xtal_counter(); 19 return read_xtal_counter();
20} 20}
21 21
22static cycle_t read_clocksource(struct clocksource *cs)
23{
24 return read_xtal_counter();
25}
26
27static struct clocksource tango_xtal = {
28 .name = "tango-xtal",
29 .rating = 350,
30 .read = read_clocksource,
31 .mask = CLOCKSOURCE_MASK(32),
32 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
33};
34
35static void __init tango_clocksource_init(struct device_node *np) 22static void __init tango_clocksource_init(struct device_node *np)
36{ 23{
37 struct clk *clk; 24 struct clk *clk;
@@ -53,8 +40,9 @@ static void __init tango_clocksource_init(struct device_node *np)
53 delay_timer.freq = xtal_freq; 40 delay_timer.freq = xtal_freq;
54 delay_timer.read_current_timer = read_xtal_counter; 41 delay_timer.read_current_timer = read_xtal_counter;
55 42
56 ret = clocksource_register_hz(&tango_xtal, xtal_freq); 43 ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350,
57 if (ret != 0) { 44 32, clocksource_mmio_readl_up);
45 if (!ret) {
58 pr_err("%s: registration failed\n", np->full_name); 46 pr_err("%s: registration failed\n", np->full_name);
59 return; 47 return;
60 } 48 }
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index 6ebda1177e79..38333aba3055 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -96,7 +96,8 @@ static struct clock_event_device tegra_clockevent = {
96 .name = "timer0", 96 .name = "timer0",
97 .rating = 300, 97 .rating = 300,
98 .features = CLOCK_EVT_FEAT_ONESHOT | 98 .features = CLOCK_EVT_FEAT_ONESHOT |
99 CLOCK_EVT_FEAT_PERIODIC, 99 CLOCK_EVT_FEAT_PERIODIC |
100 CLOCK_EVT_FEAT_DYNIRQ,
100 .set_next_event = tegra_timer_set_next_event, 101 .set_next_event = tegra_timer_set_next_event,
101 .set_state_shutdown = tegra_timer_shutdown, 102 .set_state_shutdown = tegra_timer_shutdown,
102 .set_state_periodic = tegra_timer_set_periodic, 103 .set_state_periodic = tegra_timer_set_periodic,
diff --git a/drivers/clocksource/time-lpc32xx.c b/drivers/clocksource/time-lpc32xx.c
index a1c06a2bc77c..1316876b487a 100644
--- a/drivers/clocksource/time-lpc32xx.c
+++ b/drivers/clocksource/time-lpc32xx.c
@@ -125,7 +125,7 @@ static int __init lpc32xx_clocksource_init(struct device_node *np)
125 125
126 clk = of_clk_get_by_name(np, "timerclk"); 126 clk = of_clk_get_by_name(np, "timerclk");
127 if (IS_ERR(clk)) { 127 if (IS_ERR(clk)) {
128 pr_err("clock get failed (%lu)\n", PTR_ERR(clk)); 128 pr_err("clock get failed (%ld)\n", PTR_ERR(clk));
129 return PTR_ERR(clk); 129 return PTR_ERR(clk);
130 } 130 }
131 131
@@ -184,7 +184,7 @@ static int __init lpc32xx_clockevent_init(struct device_node *np)
184 184
185 clk = of_clk_get_by_name(np, "timerclk"); 185 clk = of_clk_get_by_name(np, "timerclk");
186 if (IS_ERR(clk)) { 186 if (IS_ERR(clk)) {
187 pr_err("clock get failed (%lu)\n", PTR_ERR(clk)); 187 pr_err("clock get failed (%ld)\n", PTR_ERR(clk));
188 return PTR_ERR(clk); 188 return PTR_ERR(clk);
189 } 189 }
190 190
diff --git a/drivers/clocksource/time-pistachio.c b/drivers/clocksource/time-pistachio.c
index bba679900054..3269d9ef7a18 100644
--- a/drivers/clocksource/time-pistachio.c
+++ b/drivers/clocksource/time-pistachio.c
@@ -84,7 +84,7 @@ pistachio_clocksource_read_cycles(struct clocksource *cs)
84 counter = gpt_readl(pcs->base, TIMER_CURRENT_VALUE, 0); 84 counter = gpt_readl(pcs->base, TIMER_CURRENT_VALUE, 0);
85 raw_spin_unlock_irqrestore(&pcs->lock, flags); 85 raw_spin_unlock_irqrestore(&pcs->lock, flags);
86 86
87 return ~(cycle_t)counter; 87 return (cycle_t)~counter;
88} 88}
89 89
90static u64 notrace pistachio_read_sched_clock(void) 90static u64 notrace pistachio_read_sched_clock(void)
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
index bca9573e036a..24c83f9efd87 100644
--- a/drivers/clocksource/timer-sun5i.c
+++ b/drivers/clocksource/timer-sun5i.c
@@ -152,13 +152,6 @@ static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
152 return IRQ_HANDLED; 152 return IRQ_HANDLED;
153} 153}
154 154
155static cycle_t sun5i_clksrc_read(struct clocksource *clksrc)
156{
157 struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
158
159 return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
160}
161
162static int sun5i_rate_cb_clksrc(struct notifier_block *nb, 155static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
163 unsigned long event, void *data) 156 unsigned long event, void *data)
164{ 157{
@@ -217,13 +210,8 @@ static int __init sun5i_setup_clocksource(struct device_node *node,
217 writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, 210 writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
218 base + TIMER_CTL_REG(1)); 211 base + TIMER_CTL_REG(1));
219 212
220 cs->clksrc.name = node->name; 213 ret = clocksource_mmio_init(base + TIMER_CNTVAL_LO_REG(1), node->name,
221 cs->clksrc.rating = 340; 214 rate, 340, 32, clocksource_mmio_readl_down);
222 cs->clksrc.read = sun5i_clksrc_read;
223 cs->clksrc.mask = CLOCKSOURCE_MASK(32);
224 cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
225
226 ret = clocksource_register_hz(&cs->clksrc, rate);
227 if (ret) { 215 if (ret) {
228 pr_err("Couldn't register clock source.\n"); 216 pr_err("Couldn't register clock source.\n");
229 goto err_remove_notifier; 217 goto err_remove_notifier;
diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c
index dfc3bb410b00..ddb409274f45 100644
--- a/drivers/clocksource/vt8500_timer.c
+++ b/drivers/clocksource/vt8500_timer.c
@@ -30,7 +30,6 @@
30#include <linux/clocksource.h> 30#include <linux/clocksource.h>
31#include <linux/clockchips.h> 31#include <linux/clockchips.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <asm/mach/time.h>
34 33
35#include <linux/of.h> 34#include <linux/of.h>
36#include <linux/of_address.h> 35#include <linux/of_address.h>