diff options
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/Kconfig | 135 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 2 | ||||
-rw-r--r-- | drivers/clocksource/acpi_pm.c | 27 | ||||
-rw-r--r-- | drivers/clocksource/arm_global_timer.c | 21 | ||||
-rw-r--r-- | drivers/clocksource/dw_apb_timer.c | 46 | ||||
-rw-r--r-- | drivers/clocksource/dw_apb_timer_of.c | 16 | ||||
-rw-r--r-- | drivers/clocksource/h8300_timer16.c | 222 | ||||
-rw-r--r-- | drivers/clocksource/h8300_timer8.c | 264 | ||||
-rw-r--r-- | drivers/clocksource/h8300_tpu.c | 159 | ||||
-rw-r--r-- | drivers/clocksource/mtk_timer.c | 20 | ||||
-rw-r--r-- | drivers/clocksource/rockchip_timer.c | 23 | ||||
-rw-r--r-- | drivers/clocksource/tango_xtal.c | 18 | ||||
-rw-r--r-- | drivers/clocksource/tegra20_timer.c | 3 | ||||
-rw-r--r-- | drivers/clocksource/time-lpc32xx.c | 4 | ||||
-rw-r--r-- | drivers/clocksource/time-pistachio.c | 2 | ||||
-rw-r--r-- | drivers/clocksource/timer-sun5i.c | 16 | ||||
-rw-r--r-- | drivers/clocksource/vt8500_timer.c | 1 |
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 | ||
30 | config DIGICOLOR_TIMER | 30 | config 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 | ||
33 | config DW_APB_TIMER | 36 | config 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 | ||
36 | config DW_APB_TIMER_OF | 42 | config 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 | ||
41 | config ROCKCHIP_TIMER | 47 | config 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 | ||
45 | config ARMADA_370_XP_TIMER | 54 | config 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 | ||
49 | config MESON6_TIMER | 61 | config 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 | ||
53 | config ORION_TIMER | 68 | config 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 | ||
58 | config SUN4I_TIMER | 76 | config 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 | ||
62 | config SUN5I_HSTIMER | 83 | config 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 | ||
66 | config TEGRA_TIMER | 90 | config 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 | ||
69 | config VT8500_TIMER | 96 | config 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 | ||
72 | config CADENCE_TTC_TIMER | 102 | config 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 | ||
75 | config ASM9260_TIMER | 108 | config 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 | ||
80 | config CLKSRC_NOMADIK_MTU | 116 | config 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 | ||
95 | config CLKSRC_DBX500_PRCMU | 131 | config 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 | ||
118 | config CLKSRC_LPC32XX | 153 | config 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 | ||
123 | config CLKSRC_PISTACHIO | 161 | config 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 | ||
127 | config CLKSRC_TI_32K | 168 | config 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 | ||
201 | config CLKSRC_EXYNOS_MCT | 242 | config 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 | ||
207 | config CLKSRC_SAMSUNG_PWM | 248 | config 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 | ||
215 | config FSL_FTM_TIMER | 257 | config 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 | ||
228 | config MTK_TIMER | 272 | config 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 | ||
233 | config SYS_SUPPORTS_SH_MTU2 | 280 | config 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 | ||
281 | config CLKSRC_QCOM | 328 | config 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 | ||
284 | config CLKSRC_VERSATILE | 336 | config 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 | ||
300 | config CLKSRC_TANGO_XTAL | 352 | config 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 | ||
304 | config CLKSRC_PXA | 360 | config 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 | ||
368 | config 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 | |||
311 | config H8300_TMR16 | 374 | config 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 | ||
314 | config H8300_TPU | 381 | config 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 | ||
317 | config CLKSRC_IMX_GPT | 388 | config 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 | ||
322 | config CLKSRC_ST_LPC | 393 | config 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 | |||
60 | obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o | 60 | obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o |
61 | obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o | 61 | obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o |
62 | obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o | 62 | obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o |
63 | obj-$(CONFIG_H8300) += h8300_timer8.o | 63 | obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o |
64 | obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o | 64 | obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o |
65 | obj-$(CONFIG_H8300_TPU) += h8300_tpu.o | 65 | obj-$(CONFIG_H8300_TPU) += h8300_tpu.o |
66 | obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o | 66 | obj-$(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 | ||
115 | static int gt_clockevent_shutdown(struct clock_event_device *evt) | 115 | static 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 | ||
198 | static 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 | |||
198 | static struct clocksource gt_clocksource = { | 208 | static 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 | ||
52 | static unsigned long apbt_readl(struct dw_apb_timer *timer, unsigned long offs) | 52 | static 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 | ||
57 | static void apbt_writel(struct dw_apb_timer *timer, unsigned long val, | 57 | static 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 | ||
63 | static inline u32 apbt_readl_relaxed(struct dw_apb_timer *timer, unsigned long offs) | ||
64 | { | ||
65 | return readl_relaxed(timer->base + offs); | ||
66 | } | ||
67 | |||
68 | static 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 | |||
63 | static void apbt_disable_int(struct dw_apb_timer *timer) | 74 | static 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 | ||
82 | static void apbt_eoi(struct dw_apb_timer *timer) | 93 | static 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 | ||
87 | static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) | 98 | static 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 | ||
104 | static void apbt_enable_int(struct dw_apb_timer *timer) | 115 | static 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) | |||
113 | static int apbt_shutdown(struct clock_event_device *evt) | 124 | static 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) | |||
127 | static int apbt_set_oneshot(struct clock_event_device *evt) | 138 | static 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) | |||
196 | static int apbt_next_event(unsigned long delta, | 207 | static 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 | ||
339 | static cycle_t __apbt_read_clocksource(struct clocksource *cs) | 350 | static 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 | ||
135 | static unsigned long dw_apb_delay_timer_read(void) | ||
136 | { | ||
137 | return ~readl_relaxed(sched_io_base); | ||
138 | } | ||
139 | |||
140 | static struct delay_timer dw_apb_delay_timer = { | ||
141 | .read_current_timer = dw_apb_delay_timer_read, | ||
142 | }; | ||
143 | #endif | ||
144 | |||
133 | static int num_called; | 145 | static int num_called; |
134 | static void __init dw_apb_timer_init(struct device_node *timer) | 146 | static 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 | ||
49 | struct timer16_priv { | 25 | struct 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 | ||
67 | static unsigned long timer16_get_counter(struct timer16_priv *p) | 36 | static 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) | |||
105 | static cycle_t timer16_clocksource_read(struct clocksource *cs) | 75 | static 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 | ||
114 | static 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 | ||
150 | static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev) | 129 | static 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 | |||
205 | static 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; | |
221 | static 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 | ||
226 | static 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); |
230 | static 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 | ||
239 | static 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 | ||
244 | static void __exit timer16_exit(void) | 179 | unmap_comm: |
245 | { | 180 | iounmap(base[REG_COMM]); |
246 | platform_driver_unregister(&timer16_driver); | 181 | unmap_ch: |
182 | iounmap(base[REG_CH]); | ||
183 | free_clk: | ||
184 | clk_put(clk); | ||
247 | } | 185 | } |
248 | 186 | ||
249 | subsys_initcall(timer16_init); | 187 | CLOCKSOURCE_OF_DECLARE(h8300_16bit, "renesas,16bit-timer", h8300_16timer_init); |
250 | module_exit(timer16_exit); | ||
251 | MODULE_AUTHOR("Yoshinori Sato"); | ||
252 | MODULE_DESCRIPTION("H8/300H 16bit Timer Driver"); | ||
253 | MODULE_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 | ||
42 | struct timer8_priv { | 37 | struct 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 | ||
54 | static 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 | |||
75 | static irqreturn_t timer8_interrupt(int irq, void *dev_id) | 44 | static 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 | ||
93 | static void timer8_set_next(struct timer8_priv *p, unsigned long delta) | 58 | static 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 | ||
112 | static int timer8_enable(struct timer8_priv *p) | 69 | static 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 | ||
122 | static int timer8_start(struct timer8_priv *p) | 78 | static 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 | ||
142 | static void timer8_stop(struct timer8_priv *p) | 92 | static 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 | ||
153 | static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced) | 97 | static 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 | ||
158 | static void timer8_clock_event_start(struct timer8_priv *p, int periodic) | 102 | static 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 | ||
172 | static int timer8_clock_event_shutdown(struct clock_event_device *ced) | 116 | static 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 | ||
211 | static int timer8_setup(struct timer8_priv *p, | 155 | static 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 | |||
167 | static 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"); | |
267 | static 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 | |||
283 | static int timer8_remove(struct platform_device *pdev) | ||
284 | { | ||
285 | return -EBUSY; | ||
286 | } | ||
287 | |||
288 | static const struct of_device_id timer8_of_table[] __maybe_unused = { | ||
289 | { .compatible = "renesas,8bit-timer" }, | ||
290 | { } | ||
291 | }; | ||
292 | |||
293 | MODULE_DEVICE_TABLE(of, timer8_of_table); | ||
294 | static 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 | ||
303 | static 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 | ||
308 | static void __exit timer8_exit(void) | 208 | return; |
309 | { | 209 | unmap_reg: |
310 | platform_driver_unregister(&timer8_driver); | 210 | iounmap(base); |
211 | free_clk: | ||
212 | clk_put(clk); | ||
311 | } | 213 | } |
312 | 214 | ||
313 | subsys_initcall(timer8_init); | 215 | CLOCKSOURCE_OF_DECLARE(h8300_8bit, "renesas,8bit-timer", h8300_8timer_init); |
314 | module_exit(timer8_exit); | ||
315 | MODULE_AUTHOR("Yoshinori Sato"); | ||
316 | MODULE_DESCRIPTION("H8/300 8bit Timer Driver"); | ||
317 | MODULE_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 | ||
34 | struct tpu_priv { | 24 | struct 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 | ||
107 | static 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 | ||
122 | static int __init tpu_setup(struct tpu_priv *p, struct platform_device *pdev) | 122 | static 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 | |||
157 | static 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 | |||
173 | static int tpu_remove(struct platform_device *pdev) | ||
174 | { | ||
175 | return -EBUSY; | ||
176 | } | ||
177 | |||
178 | static const struct of_device_id tpu_of_table[] = { | ||
179 | { .compatible = "renesas,tpu" }, | ||
180 | { } | ||
181 | }; | ||
182 | 148 | ||
183 | static 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 | |||
192 | static int __init tpu_init(void) | ||
193 | { | ||
194 | return platform_driver_register(&tpu_driver); | ||
195 | } | ||
196 | 150 | ||
197 | static void __exit tpu_exit(void) | 151 | unmap_L: |
198 | { | 152 | iounmap(base[CH_H]); |
199 | platform_driver_unregister(&tpu_driver); | 153 | free_clk: |
154 | clk_put(clk); | ||
200 | } | 155 | } |
201 | 156 | ||
202 | subsys_initcall(tpu_init); | 157 | CLOCKSOURCE_OF_DECLARE(h8300_tpu, "renesas,tpu", h8300_tpu_init); |
203 | module_exit(tpu_exit); | ||
204 | MODULE_AUTHOR("Yoshinori Sato"); | ||
205 | MODULE_DESCRIPTION("H8S Timer Pulse Unit Driver"); | ||
206 | MODULE_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)); |
263 | err_kzalloc: | ||
264 | kfree(evt); | ||
263 | } | 265 | } |
264 | CLOCKSOURCE_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init); | 266 | CLOCKSOURCE_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 | ||
31 | struct bc_timer { | 31 | struct 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) | |||
49 | static inline void rk_timer_disable(struct clock_event_device *ce) | 49 | static 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 | ||
55 | static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) | 54 | static 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 | ||
62 | static void rk_timer_update_counter(unsigned long cycles, | 60 | static 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 | ||
70 | static void rk_timer_interrupt_clear(struct clock_event_device *ce) | 67 | static 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 | ||
76 | static inline int rk_timer_set_next_event(unsigned long cycles, | 72 | static 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 | |||
176 | CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); | 173 | CLOCKSOURCE_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 | ||
22 | static cycle_t read_clocksource(struct clocksource *cs) | ||
23 | { | ||
24 | return read_xtal_counter(); | ||
25 | } | ||
26 | |||
27 | static 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 | |||
35 | static void __init tango_clocksource_init(struct device_node *np) | 22 | static 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 | ||
90 | static u64 notrace pistachio_read_sched_clock(void) | 90 | static 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 | ||
155 | static 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 | |||
162 | static int sun5i_rate_cb_clksrc(struct notifier_block *nb, | 155 | static 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> |