diff options
79 files changed, 1628 insertions, 621 deletions
diff --git a/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt b/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt new file mode 100644 index 000000000000..3ca89cd1caef --- /dev/null +++ b/Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | Oxford Semiconductor OXNAS SoCs Family RPS Timer | ||
2 | ================================================ | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: Should be "oxsemi,ox810se-rps-timer" | ||
6 | - reg : Specifies base physical address and size of the registers. | ||
7 | - interrupts : The interrupts of the two timers | ||
8 | - clocks : The phandle of the timer clock source | ||
9 | |||
10 | example: | ||
11 | |||
12 | timer0: timer@200 { | ||
13 | compatible = "oxsemi,ox810se-rps-timer"; | ||
14 | reg = <0x200 0x40>; | ||
15 | clocks = <&rpsclk>; | ||
16 | interrupts = <4 5>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt index 87f0b0042bae..a41b184d5538 100644 --- a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt +++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt | |||
@@ -1,7 +1,9 @@ | |||
1 | Rockchip rk3288 timer | 1 | Rockchip rk timer |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: shall be "rockchip,rk3288-timer" | 4 | - compatible: shall be one of: |
5 | "rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368 | ||
6 | "rockchip,rk3399-timer" - for rk3399 | ||
5 | - reg: base address of the timer register starting with TIMERS CONTROL register | 7 | - reg: base address of the timer register starting with TIMERS CONTROL register |
6 | - interrupts: should contain the interrupts for Timer0 | 8 | - interrupts: should contain the interrupts for Timer0 |
7 | - clocks : must contain an entry for each entry in clock-names | 9 | - clocks : must contain an entry for each entry in clock-names |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..2c92f1df7c69 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -687,6 +687,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
687 | [SPARC64] tick | 687 | [SPARC64] tick |
688 | [X86-64] hpet,tsc | 688 | [X86-64] hpet,tsc |
689 | 689 | ||
690 | clocksource.arm_arch_timer.evtstrm= | ||
691 | [ARM,ARM64] | ||
692 | Format: <bool> | ||
693 | Enable/disable the eventstream feature of the ARM | ||
694 | architected timer so that code using WFE-based polling | ||
695 | loops can be debugged more effectively on production | ||
696 | systems. | ||
697 | |||
690 | clearcpuid=BITNUM [X86] | 698 | clearcpuid=BITNUM [X86] |
691 | Disable CPUID feature X for the kernel. See | 699 | Disable CPUID feature X for the kernel. See |
692 | arch/x86/include/asm/cpufeatures.h for the valid bit | 700 | arch/x86/include/asm/cpufeatures.h for the valid bit |
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 4549ab255dd1..98f22d2eb563 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c | |||
@@ -116,19 +116,19 @@ static struct clocksource arc_counter_gfrc = { | |||
116 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 116 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | static void __init arc_cs_setup_gfrc(struct device_node *node) | 119 | static int __init arc_cs_setup_gfrc(struct device_node *node) |
120 | { | 120 | { |
121 | int exists = cpuinfo_arc700[0].extn.gfrc; | 121 | int exists = cpuinfo_arc700[0].extn.gfrc; |
122 | int ret; | 122 | int ret; |
123 | 123 | ||
124 | if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) | 124 | if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) |
125 | return; | 125 | return -ENXIO; |
126 | 126 | ||
127 | ret = arc_get_timer_clk(node); | 127 | ret = arc_get_timer_clk(node); |
128 | if (ret) | 128 | if (ret) |
129 | return; | 129 | return ret; |
130 | 130 | ||
131 | clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); | 131 | return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); |
132 | } | 132 | } |
133 | CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); | 133 | CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); |
134 | 134 | ||
@@ -172,25 +172,25 @@ static struct clocksource arc_counter_rtc = { | |||
172 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 172 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
173 | }; | 173 | }; |
174 | 174 | ||
175 | static void __init arc_cs_setup_rtc(struct device_node *node) | 175 | static int __init arc_cs_setup_rtc(struct device_node *node) |
176 | { | 176 | { |
177 | int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; | 177 | int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; |
178 | int ret; | 178 | int ret; |
179 | 179 | ||
180 | if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) | 180 | if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) |
181 | return; | 181 | return -ENXIO; |
182 | 182 | ||
183 | /* Local to CPU hence not usable in SMP */ | 183 | /* Local to CPU hence not usable in SMP */ |
184 | if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) | 184 | if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) |
185 | return; | 185 | return -EINVAL; |
186 | 186 | ||
187 | ret = arc_get_timer_clk(node); | 187 | ret = arc_get_timer_clk(node); |
188 | if (ret) | 188 | if (ret) |
189 | return; | 189 | return ret; |
190 | 190 | ||
191 | write_aux_reg(AUX_RTC_CTRL, 1); | 191 | write_aux_reg(AUX_RTC_CTRL, 1); |
192 | 192 | ||
193 | clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); | 193 | return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); |
194 | } | 194 | } |
195 | CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); | 195 | CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); |
196 | 196 | ||
@@ -213,23 +213,23 @@ static struct clocksource arc_counter_timer1 = { | |||
213 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 213 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
214 | }; | 214 | }; |
215 | 215 | ||
216 | static void __init arc_cs_setup_timer1(struct device_node *node) | 216 | static int __init arc_cs_setup_timer1(struct device_node *node) |
217 | { | 217 | { |
218 | int ret; | 218 | int ret; |
219 | 219 | ||
220 | /* Local to CPU hence not usable in SMP */ | 220 | /* Local to CPU hence not usable in SMP */ |
221 | if (IS_ENABLED(CONFIG_SMP)) | 221 | if (IS_ENABLED(CONFIG_SMP)) |
222 | return; | 222 | return -EINVAL; |
223 | 223 | ||
224 | ret = arc_get_timer_clk(node); | 224 | ret = arc_get_timer_clk(node); |
225 | if (ret) | 225 | if (ret) |
226 | return; | 226 | return ret; |
227 | 227 | ||
228 | write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); | 228 | write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); |
229 | write_aux_reg(ARC_REG_TIMER1_CNT, 0); | 229 | write_aux_reg(ARC_REG_TIMER1_CNT, 0); |
230 | write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); | 230 | write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); |
231 | 231 | ||
232 | clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); | 232 | return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); |
233 | } | 233 | } |
234 | 234 | ||
235 | /********** Clock Event Device *********/ | 235 | /********** Clock Event Device *********/ |
@@ -324,20 +324,28 @@ static struct notifier_block arc_timer_cpu_nb = { | |||
324 | /* | 324 | /* |
325 | * clockevent setup for boot CPU | 325 | * clockevent setup for boot CPU |
326 | */ | 326 | */ |
327 | static void __init arc_clockevent_setup(struct device_node *node) | 327 | static int __init arc_clockevent_setup(struct device_node *node) |
328 | { | 328 | { |
329 | struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); | 329 | struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); |
330 | int ret; | 330 | int ret; |
331 | 331 | ||
332 | register_cpu_notifier(&arc_timer_cpu_nb); | 332 | ret = register_cpu_notifier(&arc_timer_cpu_nb); |
333 | if (ret) { | ||
334 | pr_err("Failed to register cpu notifier"); | ||
335 | return ret; | ||
336 | } | ||
333 | 337 | ||
334 | arc_timer_irq = irq_of_parse_and_map(node, 0); | 338 | arc_timer_irq = irq_of_parse_and_map(node, 0); |
335 | if (arc_timer_irq <= 0) | 339 | if (arc_timer_irq <= 0) { |
336 | panic("clockevent: missing irq"); | 340 | pr_err("clockevent: missing irq"); |
341 | return -EINVAL; | ||
342 | } | ||
337 | 343 | ||
338 | ret = arc_get_timer_clk(node); | 344 | ret = arc_get_timer_clk(node); |
339 | if (ret) | 345 | if (ret) { |
340 | panic("clockevent: missing clk"); | 346 | pr_err("clockevent: missing clk"); |
347 | return ret; | ||
348 | } | ||
341 | 349 | ||
342 | evt->irq = arc_timer_irq; | 350 | evt->irq = arc_timer_irq; |
343 | evt->cpumask = cpumask_of(smp_processor_id()); | 351 | evt->cpumask = cpumask_of(smp_processor_id()); |
@@ -347,22 +355,29 @@ static void __init arc_clockevent_setup(struct device_node *node) | |||
347 | /* Needs apriori irq_set_percpu_devid() done in intc map function */ | 355 | /* Needs apriori irq_set_percpu_devid() done in intc map function */ |
348 | ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, | 356 | ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, |
349 | "Timer0 (per-cpu-tick)", evt); | 357 | "Timer0 (per-cpu-tick)", evt); |
350 | if (ret) | 358 | if (ret) { |
351 | panic("clockevent: unable to request irq\n"); | 359 | pr_err("clockevent: unable to request irq\n"); |
360 | return ret; | ||
361 | } | ||
352 | 362 | ||
353 | enable_percpu_irq(arc_timer_irq, 0); | 363 | enable_percpu_irq(arc_timer_irq, 0); |
364 | |||
365 | return 0; | ||
354 | } | 366 | } |
355 | 367 | ||
356 | static void __init arc_of_timer_init(struct device_node *np) | 368 | static int __init arc_of_timer_init(struct device_node *np) |
357 | { | 369 | { |
358 | static int init_count = 0; | 370 | static int init_count = 0; |
371 | int ret; | ||
359 | 372 | ||
360 | if (!init_count) { | 373 | if (!init_count) { |
361 | init_count = 1; | 374 | init_count = 1; |
362 | arc_clockevent_setup(np); | 375 | ret = arc_clockevent_setup(np); |
363 | } else { | 376 | } else { |
364 | arc_cs_setup_timer1(np); | 377 | ret = arc_cs_setup_timer1(np); |
365 | } | 378 | } |
379 | |||
380 | return ret; | ||
366 | } | 381 | } |
367 | CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); | 382 | CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); |
368 | 383 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 90542db1220d..f0636ec94903 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -358,10 +358,10 @@ config ARCH_CLPS711X | |||
358 | bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" | 358 | bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" |
359 | select ARCH_REQUIRE_GPIOLIB | 359 | select ARCH_REQUIRE_GPIOLIB |
360 | select AUTO_ZRELADDR | 360 | select AUTO_ZRELADDR |
361 | select CLKSRC_MMIO | ||
362 | select COMMON_CLK | 361 | select COMMON_CLK |
363 | select CPU_ARM720T | 362 | select CPU_ARM720T |
364 | select GENERIC_CLOCKEVENTS | 363 | select GENERIC_CLOCKEVENTS |
364 | select CLPS711X_TIMER | ||
365 | select MFD_SYSCON | 365 | select MFD_SYSCON |
366 | select SOC_BUS | 366 | select SOC_BUS |
367 | help | 367 | help |
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 1bfa7a7f5533..b6ec65e68009 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c | |||
@@ -390,7 +390,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt) | |||
390 | } | 390 | } |
391 | 391 | ||
392 | #ifdef CONFIG_OF | 392 | #ifdef CONFIG_OF |
393 | static void __init twd_local_timer_of_register(struct device_node *np) | 393 | static int __init twd_local_timer_of_register(struct device_node *np) |
394 | { | 394 | { |
395 | int err; | 395 | int err; |
396 | 396 | ||
@@ -410,6 +410,7 @@ static void __init twd_local_timer_of_register(struct device_node *np) | |||
410 | 410 | ||
411 | out: | 411 | out: |
412 | WARN(err, "twd_local_timer_of_register failed (%d)\n", err); | 412 | WARN(err, "twd_local_timer_of_register failed (%d)\n", err); |
413 | return err; | ||
413 | } | 414 | } |
414 | CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register); | 415 | CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register); |
415 | CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register); | 416 | CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register); |
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 68ab6412392a..4f1709b31822 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig | |||
@@ -89,6 +89,7 @@ config ARCH_BCM_MOBILE | |||
89 | select HAVE_ARM_ARCH_TIMER | 89 | select HAVE_ARM_ARCH_TIMER |
90 | select PINCTRL | 90 | select PINCTRL |
91 | select ARCH_BCM_MOBILE_SMP if SMP | 91 | select ARCH_BCM_MOBILE_SMP if SMP |
92 | select BCM_KONA_TIMER | ||
92 | help | 93 | help |
93 | This enables support for systems based on Broadcom mobile SoCs. | 94 | This enables support for systems based on Broadcom mobile SoCs. |
94 | 95 | ||
@@ -143,6 +144,7 @@ config ARCH_BCM2835 | |||
143 | select ARM_TIMER_SP804 | 144 | select ARM_TIMER_SP804 |
144 | select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 | 145 | select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 |
145 | select CLKSRC_OF | 146 | select CLKSRC_OF |
147 | select BCM2835_TIMER | ||
146 | select PINCTRL | 148 | select PINCTRL |
147 | select PINCTRL_BCM2835 | 149 | select PINCTRL_BCM2835 |
148 | help | 150 | help |
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index b2a85ba13f08..291262e5aeaf 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig | |||
@@ -20,7 +20,7 @@ if ARCH_INTEGRATOR | |||
20 | 20 | ||
21 | config ARCH_INTEGRATOR_AP | 21 | config ARCH_INTEGRATOR_AP |
22 | bool "Support Integrator/AP and Integrator/PP2 platforms" | 22 | bool "Support Integrator/AP and Integrator/PP2 platforms" |
23 | select CLKSRC_MMIO | 23 | select INTEGRATOR_AP_TIMER |
24 | select MIGHT_HAVE_PCI | 24 | select MIGHT_HAVE_PCI |
25 | select SERIAL_AMBA_PL010 if TTY | 25 | select SERIAL_AMBA_PL010 if TTY |
26 | select SERIAL_AMBA_PL010_CONSOLE if TTY | 26 | select SERIAL_AMBA_PL010_CONSOLE if TTY |
diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig index ea955f6db8b7..bac577badc7e 100644 --- a/arch/arm/mach-keystone/Kconfig +++ b/arch/arm/mach-keystone/Kconfig | |||
@@ -4,7 +4,7 @@ config ARCH_KEYSTONE | |||
4 | depends on ARM_PATCH_PHYS_VIRT | 4 | depends on ARM_PATCH_PHYS_VIRT |
5 | select ARM_GIC | 5 | select ARM_GIC |
6 | select HAVE_ARM_ARCH_TIMER | 6 | select HAVE_ARM_ARCH_TIMER |
7 | select CLKSRC_MMIO | 7 | select KEYSTONE_TIMER |
8 | select ARM_ERRATA_798181 if SMP | 8 | select ARM_ERRATA_798181 if SMP |
9 | select COMMON_CLK_KEYSTONE | 9 | select COMMON_CLK_KEYSTONE |
10 | select ARCH_SUPPORTS_BIG_ENDIAN | 10 | select ARCH_SUPPORTS_BIG_ENDIAN |
diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig index 180d9d216719..ddc79cea32d3 100644 --- a/arch/arm/mach-moxart/Kconfig +++ b/arch/arm/mach-moxart/Kconfig | |||
@@ -3,7 +3,7 @@ menuconfig ARCH_MOXART | |||
3 | depends on ARCH_MULTI_V4 | 3 | depends on ARCH_MULTI_V4 |
4 | select CPU_FA526 | 4 | select CPU_FA526 |
5 | select ARM_DMA_MEM_BUFFERABLE | 5 | select ARM_DMA_MEM_BUFFERABLE |
6 | select CLKSRC_MMIO | 6 | select MOXART_TIMER |
7 | select GENERIC_IRQ_CHIP | 7 | select GENERIC_IRQ_CHIP |
8 | select ARCH_REQUIRE_GPIOLIB | 8 | select ARCH_REQUIRE_GPIOLIB |
9 | select PHYLIB if NETDEVICES | 9 | select PHYLIB if NETDEVICES |
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index 84794137b175..68a3a9ec605d 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig | |||
@@ -16,7 +16,7 @@ config ARCH_MXS | |||
16 | bool "Freescale MXS (i.MX23, i.MX28) support" | 16 | bool "Freescale MXS (i.MX23, i.MX28) support" |
17 | depends on ARCH_MULTI_V5 | 17 | depends on ARCH_MULTI_V5 |
18 | select ARCH_REQUIRE_GPIOLIB | 18 | select ARCH_REQUIRE_GPIOLIB |
19 | select CLKSRC_MMIO | 19 | select MXS_TIMER |
20 | select PINCTRL | 20 | select PINCTRL |
21 | select SOC_BUS | 21 | select SOC_BUS |
22 | select SOC_IMX23 | 22 | select SOC_IMX23 |
diff --git a/arch/arm/mach-nspire/Kconfig b/arch/arm/mach-nspire/Kconfig index bc41f26c1a12..d4985305cab2 100644 --- a/arch/arm/mach-nspire/Kconfig +++ b/arch/arm/mach-nspire/Kconfig | |||
@@ -7,5 +7,6 @@ config ARCH_NSPIRE | |||
7 | select ARM_AMBA | 7 | select ARM_AMBA |
8 | select ARM_VIC | 8 | select ARM_VIC |
9 | select ARM_TIMER_SP804 | 9 | select ARM_TIMER_SP804 |
10 | select NSPIRE_TIMER | ||
10 | help | 11 | help |
11 | This enables support for systems using the TI-NSPIRE CPU | 12 | This enables support for systems using the TI-NSPIRE CPU |
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index 0cf4426183cf..9e938f2961cf 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig | |||
@@ -28,6 +28,7 @@ config ARCH_ATLAS7 | |||
28 | default y | 28 | default y |
29 | select ARM_GIC | 29 | select ARM_GIC |
30 | select CPU_V7 | 30 | select CPU_V7 |
31 | select ATLAS7_TIMER | ||
31 | select HAVE_ARM_SCU if SMP | 32 | select HAVE_ARM_SCU if SMP |
32 | select HAVE_SMP | 33 | select HAVE_SMP |
33 | help | 34 | help |
@@ -38,6 +39,7 @@ config ARCH_PRIMA2 | |||
38 | default y | 39 | default y |
39 | select SIRF_IRQ | 40 | select SIRF_IRQ |
40 | select ZONE_DMA | 41 | select ZONE_DMA |
42 | select PRIMA2_TIMER | ||
41 | help | 43 | help |
42 | Support for CSR SiRFSoC ARM Cortex A9 Platform | 44 | Support for CSR SiRFSoC ARM Cortex A9 Platform |
43 | 45 | ||
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 301a98498453..4fdc3425ffbd 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig | |||
@@ -4,7 +4,7 @@ menuconfig ARCH_U300 | |||
4 | select ARCH_REQUIRE_GPIOLIB | 4 | select ARCH_REQUIRE_GPIOLIB |
5 | select ARM_AMBA | 5 | select ARM_AMBA |
6 | select ARM_VIC | 6 | select ARM_VIC |
7 | select CLKSRC_MMIO | 7 | select U300_TIMER |
8 | select CPU_ARM926T | 8 | select CPU_ARM926T |
9 | select HAVE_TCM | 9 | select HAVE_TCM |
10 | select PINCTRL | 10 | select PINCTRL |
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index d7f8e06910bc..188bbeab92b9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi | |||
@@ -492,6 +492,14 @@ | |||
492 | interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; | 492 | interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; |
493 | }; | 493 | }; |
494 | 494 | ||
495 | rktimer: rktimer@ff850000 { | ||
496 | compatible = "rockchip,rk3399-timer"; | ||
497 | reg = <0x0 0xff850000 0x0 0x1000>; | ||
498 | interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; | ||
499 | clocks = <&cru PCLK_TIMER0>, <&cru SCLK_TIMER00>; | ||
500 | clock-names = "pclk", "timer"; | ||
501 | }; | ||
502 | |||
495 | spdif: spdif@ff870000 { | 503 | spdif: spdif@ff870000 { |
496 | compatible = "rockchip,rk3399-spdif"; | 504 | compatible = "rockchip,rk3399-spdif"; |
497 | reg = <0x0 0xff870000 0x0 0x1000>; | 505 | reg = <0x0 0xff870000 0x0 0x1000>; |
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 67e2ef48d2d0..5bbf38b916ef 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c | |||
@@ -170,7 +170,7 @@ static struct irqaction timer_irqaction = { | |||
170 | .dev_id = &clockevent_xilinx_timer, | 170 | .dev_id = &clockevent_xilinx_timer, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static __init void xilinx_clockevent_init(void) | 173 | static __init int xilinx_clockevent_init(void) |
174 | { | 174 | { |
175 | clockevent_xilinx_timer.mult = | 175 | clockevent_xilinx_timer.mult = |
176 | div_sc(timer_clock_freq, NSEC_PER_SEC, | 176 | div_sc(timer_clock_freq, NSEC_PER_SEC, |
@@ -181,6 +181,8 @@ static __init void xilinx_clockevent_init(void) | |||
181 | clockevent_delta2ns(1, &clockevent_xilinx_timer); | 181 | clockevent_delta2ns(1, &clockevent_xilinx_timer); |
182 | clockevent_xilinx_timer.cpumask = cpumask_of(0); | 182 | clockevent_xilinx_timer.cpumask = cpumask_of(0); |
183 | clockevents_register_device(&clockevent_xilinx_timer); | 183 | clockevents_register_device(&clockevent_xilinx_timer); |
184 | |||
185 | return 0; | ||
184 | } | 186 | } |
185 | 187 | ||
186 | static u64 xilinx_clock_read(void) | 188 | static u64 xilinx_clock_read(void) |
@@ -229,8 +231,14 @@ static struct clocksource clocksource_microblaze = { | |||
229 | 231 | ||
230 | static int __init xilinx_clocksource_init(void) | 232 | static int __init xilinx_clocksource_init(void) |
231 | { | 233 | { |
232 | if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq)) | 234 | int ret; |
233 | panic("failed to register clocksource"); | 235 | |
236 | ret = clocksource_register_hz(&clocksource_microblaze, | ||
237 | timer_clock_freq); | ||
238 | if (ret) { | ||
239 | pr_err("failed to register clocksource"); | ||
240 | return ret; | ||
241 | } | ||
234 | 242 | ||
235 | /* stop timer1 */ | 243 | /* stop timer1 */ |
236 | write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT, | 244 | write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT, |
@@ -239,16 +247,16 @@ static int __init xilinx_clocksource_init(void) | |||
239 | write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1); | 247 | write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1); |
240 | 248 | ||
241 | /* register timecounter - for ftrace support */ | 249 | /* register timecounter - for ftrace support */ |
242 | init_xilinx_timecounter(); | 250 | return init_xilinx_timecounter(); |
243 | return 0; | ||
244 | } | 251 | } |
245 | 252 | ||
246 | static void __init xilinx_timer_init(struct device_node *timer) | 253 | static int __init xilinx_timer_init(struct device_node *timer) |
247 | { | 254 | { |
248 | struct clk *clk; | 255 | struct clk *clk; |
249 | static int initialized; | 256 | static int initialized; |
250 | u32 irq; | 257 | u32 irq; |
251 | u32 timer_num = 1; | 258 | u32 timer_num = 1; |
259 | int ret; | ||
252 | 260 | ||
253 | if (initialized) | 261 | if (initialized) |
254 | return; | 262 | return; |
@@ -258,7 +266,7 @@ static void __init xilinx_timer_init(struct device_node *timer) | |||
258 | timer_baseaddr = of_iomap(timer, 0); | 266 | timer_baseaddr = of_iomap(timer, 0); |
259 | if (!timer_baseaddr) { | 267 | if (!timer_baseaddr) { |
260 | pr_err("ERROR: invalid timer base address\n"); | 268 | pr_err("ERROR: invalid timer base address\n"); |
261 | BUG(); | 269 | return -ENXIO; |
262 | } | 270 | } |
263 | 271 | ||
264 | write_fn = timer_write32; | 272 | write_fn = timer_write32; |
@@ -271,11 +279,15 @@ static void __init xilinx_timer_init(struct device_node *timer) | |||
271 | } | 279 | } |
272 | 280 | ||
273 | irq = irq_of_parse_and_map(timer, 0); | 281 | irq = irq_of_parse_and_map(timer, 0); |
282 | if (irq <= 0) { | ||
283 | pr_err("Failed to parse and map irq"); | ||
284 | return -EINVAL; | ||
285 | } | ||
274 | 286 | ||
275 | of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num); | 287 | of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num); |
276 | if (timer_num) { | 288 | if (timer_num) { |
277 | pr_emerg("Please enable two timers in HW\n"); | 289 | pr_err("Please enable two timers in HW\n"); |
278 | BUG(); | 290 | return -EINVAL; |
279 | } | 291 | } |
280 | 292 | ||
281 | pr_info("%s: irq=%d\n", timer->full_name, irq); | 293 | pr_info("%s: irq=%d\n", timer->full_name, irq); |
@@ -297,14 +309,27 @@ static void __init xilinx_timer_init(struct device_node *timer) | |||
297 | 309 | ||
298 | freq_div_hz = timer_clock_freq / HZ; | 310 | freq_div_hz = timer_clock_freq / HZ; |
299 | 311 | ||
300 | setup_irq(irq, &timer_irqaction); | 312 | ret = setup_irq(irq, &timer_irqaction); |
313 | if (ret) { | ||
314 | pr_err("Failed to setup IRQ"); | ||
315 | return ret; | ||
316 | } | ||
317 | |||
301 | #ifdef CONFIG_HEART_BEAT | 318 | #ifdef CONFIG_HEART_BEAT |
302 | microblaze_setup_heartbeat(); | 319 | microblaze_setup_heartbeat(); |
303 | #endif | 320 | #endif |
304 | xilinx_clocksource_init(); | 321 | |
305 | xilinx_clockevent_init(); | 322 | ret = xilinx_clocksource_init(); |
323 | if (ret) | ||
324 | return ret; | ||
325 | |||
326 | ret = xilinx_clockevent_init(); | ||
327 | if (ret) | ||
328 | return ret; | ||
306 | 329 | ||
307 | sched_clock_register(xilinx_clock_read, 32, timer_clock_freq); | 330 | sched_clock_register(xilinx_clock_read, 32, timer_clock_freq); |
331 | |||
332 | return 0; | ||
308 | } | 333 | } |
309 | 334 | ||
310 | CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a", | 335 | CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a", |
diff --git a/arch/mips/ralink/cevt-rt3352.c b/arch/mips/ralink/cevt-rt3352.c index 3ad0b0794f7d..f24eee04e16a 100644 --- a/arch/mips/ralink/cevt-rt3352.c +++ b/arch/mips/ralink/cevt-rt3352.c | |||
@@ -117,11 +117,13 @@ static int systick_set_oneshot(struct clock_event_device *evt) | |||
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
120 | static void __init ralink_systick_init(struct device_node *np) | 120 | static int __init ralink_systick_init(struct device_node *np) |
121 | { | 121 | { |
122 | int ret; | ||
123 | |||
122 | systick.membase = of_iomap(np, 0); | 124 | systick.membase = of_iomap(np, 0); |
123 | if (!systick.membase) | 125 | if (!systick.membase) |
124 | return; | 126 | return -ENXIO; |
125 | 127 | ||
126 | systick_irqaction.name = np->name; | 128 | systick_irqaction.name = np->name; |
127 | systick.dev.name = np->name; | 129 | systick.dev.name = np->name; |
@@ -131,16 +133,21 @@ static void __init ralink_systick_init(struct device_node *np) | |||
131 | systick.dev.irq = irq_of_parse_and_map(np, 0); | 133 | systick.dev.irq = irq_of_parse_and_map(np, 0); |
132 | if (!systick.dev.irq) { | 134 | if (!systick.dev.irq) { |
133 | pr_err("%s: request_irq failed", np->name); | 135 | pr_err("%s: request_irq failed", np->name); |
134 | return; | 136 | return -EINVAL; |
135 | } | 137 | } |
136 | 138 | ||
137 | clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, | 139 | ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, |
138 | SYSTICK_FREQ, 301, 16, clocksource_mmio_readl_up); | 140 | SYSTICK_FREQ, 301, 16, |
141 | clocksource_mmio_readl_up); | ||
142 | if (ret) | ||
143 | return ret; | ||
139 | 144 | ||
140 | clockevents_register_device(&systick.dev); | 145 | clockevents_register_device(&systick.dev); |
141 | 146 | ||
142 | pr_info("%s: running - mult: %d, shift: %d\n", | 147 | pr_info("%s: running - mult: %d, shift: %d\n", |
143 | np->name, systick.dev.mult, systick.dev.shift); | 148 | np->name, systick.dev.mult, systick.dev.shift); |
149 | |||
150 | return 0; | ||
144 | } | 151 | } |
145 | 152 | ||
146 | CLOCKSOURCE_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init); | 153 | CLOCKSOURCE_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init); |
diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c index e835dda2bfe2..d9563ddb337e 100644 --- a/arch/nios2/kernel/time.c +++ b/arch/nios2/kernel/time.c | |||
@@ -206,15 +206,21 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
206 | return IRQ_HANDLED; | 206 | return IRQ_HANDLED; |
207 | } | 207 | } |
208 | 208 | ||
209 | static void __init nios2_timer_get_base_and_freq(struct device_node *np, | 209 | static int __init nios2_timer_get_base_and_freq(struct device_node *np, |
210 | void __iomem **base, u32 *freq) | 210 | void __iomem **base, u32 *freq) |
211 | { | 211 | { |
212 | *base = of_iomap(np, 0); | 212 | *base = of_iomap(np, 0); |
213 | if (!*base) | 213 | if (!*base) { |
214 | panic("Unable to map reg for %s\n", np->name); | 214 | pr_crit("Unable to map reg for %s\n", np->name); |
215 | return -ENXIO; | ||
216 | } | ||
217 | |||
218 | if (of_property_read_u32(np, "clock-frequency", freq)) { | ||
219 | pr_crit("Unable to get %s clock frequency\n", np->name); | ||
220 | return -EINVAL; | ||
221 | } | ||
215 | 222 | ||
216 | if (of_property_read_u32(np, "clock-frequency", freq)) | 223 | return 0; |
217 | panic("Unable to get %s clock frequency\n", np->name); | ||
218 | } | 224 | } |
219 | 225 | ||
220 | static struct nios2_clockevent_dev nios2_ce = { | 226 | static struct nios2_clockevent_dev nios2_ce = { |
@@ -231,17 +237,21 @@ static struct nios2_clockevent_dev nios2_ce = { | |||
231 | }, | 237 | }, |
232 | }; | 238 | }; |
233 | 239 | ||
234 | static __init void nios2_clockevent_init(struct device_node *timer) | 240 | static __init int nios2_clockevent_init(struct device_node *timer) |
235 | { | 241 | { |
236 | void __iomem *iobase; | 242 | void __iomem *iobase; |
237 | u32 freq; | 243 | u32 freq; |
238 | int irq; | 244 | int irq, ret; |
239 | 245 | ||
240 | nios2_timer_get_base_and_freq(timer, &iobase, &freq); | 246 | ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq); |
247 | if (ret) | ||
248 | return ret; | ||
241 | 249 | ||
242 | irq = irq_of_parse_and_map(timer, 0); | 250 | irq = irq_of_parse_and_map(timer, 0); |
243 | if (!irq) | 251 | if (!irq) { |
244 | panic("Unable to parse timer irq\n"); | 252 | pr_crit("Unable to parse timer irq\n"); |
253 | return -EINVAL; | ||
254 | } | ||
245 | 255 | ||
246 | nios2_ce.timer.base = iobase; | 256 | nios2_ce.timer.base = iobase; |
247 | nios2_ce.timer.freq = freq; | 257 | nios2_ce.timer.freq = freq; |
@@ -253,25 +263,35 @@ static __init void nios2_clockevent_init(struct device_node *timer) | |||
253 | /* clear pending interrupt */ | 263 | /* clear pending interrupt */ |
254 | timer_writew(&nios2_ce.timer, 0, ALTERA_TIMER_STATUS_REG); | 264 | timer_writew(&nios2_ce.timer, 0, ALTERA_TIMER_STATUS_REG); |
255 | 265 | ||
256 | if (request_irq(irq, timer_interrupt, IRQF_TIMER, timer->name, | 266 | ret = request_irq(irq, timer_interrupt, IRQF_TIMER, timer->name, |
257 | &nios2_ce.ced)) | 267 | &nios2_ce.ced); |
258 | panic("Unable to setup timer irq\n"); | 268 | if (ret) { |
269 | pr_crit("Unable to setup timer irq\n"); | ||
270 | return ret; | ||
271 | } | ||
259 | 272 | ||
260 | clockevents_config_and_register(&nios2_ce.ced, freq, 1, ULONG_MAX); | 273 | clockevents_config_and_register(&nios2_ce.ced, freq, 1, ULONG_MAX); |
274 | |||
275 | return 0; | ||
261 | } | 276 | } |
262 | 277 | ||
263 | static __init void nios2_clocksource_init(struct device_node *timer) | 278 | static __init int nios2_clocksource_init(struct device_node *timer) |
264 | { | 279 | { |
265 | unsigned int ctrl; | 280 | unsigned int ctrl; |
266 | void __iomem *iobase; | 281 | void __iomem *iobase; |
267 | u32 freq; | 282 | u32 freq; |
283 | int ret; | ||
268 | 284 | ||
269 | nios2_timer_get_base_and_freq(timer, &iobase, &freq); | 285 | ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq); |
286 | if (ret) | ||
287 | return ret; | ||
270 | 288 | ||
271 | nios2_cs.timer.base = iobase; | 289 | nios2_cs.timer.base = iobase; |
272 | nios2_cs.timer.freq = freq; | 290 | nios2_cs.timer.freq = freq; |
273 | 291 | ||
274 | clocksource_register_hz(&nios2_cs.cs, freq); | 292 | ret = clocksource_register_hz(&nios2_cs.cs, freq); |
293 | if (ret) | ||
294 | return ret; | ||
275 | 295 | ||
276 | timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODL_REG); | 296 | timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODL_REG); |
277 | timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODH_REG); | 297 | timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODH_REG); |
@@ -282,6 +302,8 @@ static __init void nios2_clocksource_init(struct device_node *timer) | |||
282 | 302 | ||
283 | /* Calibrate the delay loop directly */ | 303 | /* Calibrate the delay loop directly */ |
284 | lpj_fine = freq / HZ; | 304 | lpj_fine = freq / HZ; |
305 | |||
306 | return 0; | ||
285 | } | 307 | } |
286 | 308 | ||
287 | /* | 309 | /* |
@@ -289,22 +311,25 @@ static __init void nios2_clocksource_init(struct device_node *timer) | |||
289 | * more instances, the second one gets used as clocksource and all | 311 | * more instances, the second one gets used as clocksource and all |
290 | * others are unused. | 312 | * others are unused. |
291 | */ | 313 | */ |
292 | static void __init nios2_time_init(struct device_node *timer) | 314 | static int __init nios2_time_init(struct device_node *timer) |
293 | { | 315 | { |
294 | static int num_called; | 316 | static int num_called; |
317 | int ret; | ||
295 | 318 | ||
296 | switch (num_called) { | 319 | switch (num_called) { |
297 | case 0: | 320 | case 0: |
298 | nios2_clockevent_init(timer); | 321 | ret = nios2_clockevent_init(timer); |
299 | break; | 322 | break; |
300 | case 1: | 323 | case 1: |
301 | nios2_clocksource_init(timer); | 324 | ret = nios2_clocksource_init(timer); |
302 | break; | 325 | break; |
303 | default: | 326 | default: |
304 | break; | 327 | break; |
305 | } | 328 | } |
306 | 329 | ||
307 | num_called++; | 330 | num_called++; |
331 | |||
332 | return ret; | ||
308 | } | 333 | } |
309 | 334 | ||
310 | void read_persistent_clock(struct timespec *ts) | 335 | void read_persistent_clock(struct timespec *ts) |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 47352d25c15e..567788664723 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -27,6 +27,20 @@ config CLKBLD_I8253 | |||
27 | config CLKSRC_MMIO | 27 | config CLKSRC_MMIO |
28 | bool | 28 | bool |
29 | 29 | ||
30 | config BCM2835_TIMER | ||
31 | bool "BCM2835 timer driver" if COMPILE_TEST | ||
32 | depends on GENERIC_CLOCKEVENTS | ||
33 | select CLKSRC_MMIO | ||
34 | help | ||
35 | Enables the support for the BCM2835 timer driver. | ||
36 | |||
37 | config BCM_KONA_TIMER | ||
38 | bool "BCM mobile timer driver" if COMPILE_TEST | ||
39 | depends on GENERIC_CLOCKEVENTS | ||
40 | select CLKSRC_MMIO | ||
41 | help | ||
42 | Enables the support for the BCM Kona mobile timer driver. | ||
43 | |||
30 | config DIGICOLOR_TIMER | 44 | config DIGICOLOR_TIMER |
31 | bool "Digicolor timer driver" if COMPILE_TEST | 45 | bool "Digicolor timer driver" if COMPILE_TEST |
32 | depends on GENERIC_CLOCKEVENTS | 46 | depends on GENERIC_CLOCKEVENTS |
@@ -141,6 +155,72 @@ config CLKSRC_DBX500_PRCMU | |||
141 | help | 155 | help |
142 | Use the always on PRCMU Timer as clocksource | 156 | Use the always on PRCMU Timer as clocksource |
143 | 157 | ||
158 | config CLPS711X_TIMER | ||
159 | bool "Cirrus logic timer driver" if COMPILE_TEST | ||
160 | depends on GENERIC_CLOCKEVENTS | ||
161 | select CLKSRC_MMIO | ||
162 | help | ||
163 | Enables support for the Cirrus Logic PS711 timer. | ||
164 | |||
165 | config ATLAS7_TIMER | ||
166 | bool "Atlas7 timer driver" if COMPILE_TEST | ||
167 | depends on GENERIC_CLOCKEVENTS | ||
168 | select CLKSRC_MMIO | ||
169 | help | ||
170 | Enables support for the Atlas7 timer. | ||
171 | |||
172 | config MOXART_TIMER | ||
173 | bool "Moxart timer driver" if COMPILE_TEST | ||
174 | depends on GENERIC_CLOCKEVENTS | ||
175 | select CLKSRC_MMIO | ||
176 | help | ||
177 | Enables support for the Moxart timer. | ||
178 | |||
179 | config MXS_TIMER | ||
180 | bool "Mxs timer driver" if COMPILE_TEST | ||
181 | depends on GENERIC_CLOCKEVENTS | ||
182 | select CLKSRC_MMIO | ||
183 | select STMP_DEVICE | ||
184 | help | ||
185 | Enables support for the Mxs timer. | ||
186 | |||
187 | config PRIMA2_TIMER | ||
188 | bool "Prima2 timer driver" if COMPILE_TEST | ||
189 | depends on GENERIC_CLOCKEVENTS | ||
190 | select CLKSRC_MMIO | ||
191 | help | ||
192 | Enables support for the Prima2 timer. | ||
193 | |||
194 | config U300_TIMER | ||
195 | bool "U300 timer driver" if COMPILE_TEST | ||
196 | depends on GENERIC_CLOCKEVENTS | ||
197 | depends on ARM | ||
198 | select CLKSRC_MMIO | ||
199 | help | ||
200 | Enables support for the U300 timer. | ||
201 | |||
202 | config NSPIRE_TIMER | ||
203 | bool "NSpire timer driver" if COMPILE_TEST | ||
204 | depends on GENERIC_CLOCKEVENTS | ||
205 | select CLKSRC_MMIO | ||
206 | help | ||
207 | Enables support for the Nspire timer. | ||
208 | |||
209 | config KEYSTONE_TIMER | ||
210 | bool "Keystone timer driver" if COMPILE_TEST | ||
211 | depends on GENERIC_CLOCKEVENTS | ||
212 | depends on ARM || ARM64 | ||
213 | select CLKSRC_MMIO | ||
214 | help | ||
215 | Enables support for the Keystone timer. | ||
216 | |||
217 | config INTEGRATOR_AP_TIMER | ||
218 | bool "Integrator-ap timer driver" if COMPILE_TEST | ||
219 | depends on GENERIC_CLOCKEVENTS | ||
220 | select CLKSRC_MMIO | ||
221 | help | ||
222 | Enables support for the Integrator-ap timer. | ||
223 | |||
144 | config CLKSRC_DBX500_PRCMU_SCHED_CLOCK | 224 | config CLKSRC_DBX500_PRCMU_SCHED_CLOCK |
145 | bool "Clocksource PRCMU Timer sched_clock" | 225 | bool "Clocksource PRCMU Timer sched_clock" |
146 | depends on (CLKSRC_DBX500_PRCMU && !CLKSRC_NOMADIK_MTU_SCHED_CLOCK) | 226 | depends on (CLKSRC_DBX500_PRCMU && !CLKSRC_NOMADIK_MTU_SCHED_CLOCK) |
@@ -208,14 +288,16 @@ config ARM_ARCH_TIMER | |||
208 | select CLKSRC_ACPI if ACPI | 288 | select CLKSRC_ACPI if ACPI |
209 | 289 | ||
210 | config ARM_ARCH_TIMER_EVTSTREAM | 290 | config ARM_ARCH_TIMER_EVTSTREAM |
211 | bool "Support for ARM architected timer event stream generation" | 291 | bool "Enable ARM architected timer event stream generation by default" |
212 | default y if ARM_ARCH_TIMER | 292 | default y if ARM_ARCH_TIMER |
213 | depends on ARM_ARCH_TIMER | 293 | depends on ARM_ARCH_TIMER |
214 | help | 294 | help |
215 | This option enables support for event stream generation based on | 295 | This option enables support by default for event stream generation |
216 | the ARM architected timer. It is used for waking up CPUs executing | 296 | based on the ARM architected timer. It is used for waking up CPUs |
217 | the wfe instruction at a frequency represented as a power-of-2 | 297 | executing the wfe instruction at a frequency represented as a |
218 | divisor of the clock rate. | 298 | power-of-2 divisor of the clock rate. The behaviour can also be |
299 | overridden on the command line using the | ||
300 | clocksource.arm_arch_timer.evtstream parameter. | ||
219 | The main use of the event stream is wfe-based timeouts of userspace | 301 | The main use of the event stream is wfe-based timeouts of userspace |
220 | locking implementations. It might also be useful for imposing timeout | 302 | locking implementations. It might also be useful for imposing timeout |
221 | on wfe to safeguard against any programming errors in case an expected | 303 | on wfe to safeguard against any programming errors in case an expected |
@@ -224,8 +306,9 @@ config ARM_ARCH_TIMER_EVTSTREAM | |||
224 | hardware anomalies of missing events. | 306 | hardware anomalies of missing events. |
225 | 307 | ||
226 | config ARM_GLOBAL_TIMER | 308 | config ARM_GLOBAL_TIMER |
227 | bool | 309 | bool "Support for the ARM global timer" if COMPILE_TEST |
228 | select CLKSRC_OF if OF | 310 | select CLKSRC_OF if OF |
311 | depends on ARM | ||
229 | help | 312 | help |
230 | This options enables support for the ARM global timer unit | 313 | This options enables support for the ARM global timer unit |
231 | 314 | ||
@@ -243,7 +326,7 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | |||
243 | Use ARM global timer clock source as sched_clock | 326 | Use ARM global timer clock source as sched_clock |
244 | 327 | ||
245 | config ARMV7M_SYSTICK | 328 | config ARMV7M_SYSTICK |
246 | bool | 329 | bool "Support for the ARMv7M system time" if COMPILE_TEST |
247 | select CLKSRC_OF if OF | 330 | select CLKSRC_OF if OF |
248 | select CLKSRC_MMIO | 331 | select CLKSRC_MMIO |
249 | help | 332 | help |
@@ -254,9 +337,12 @@ config ATMEL_PIT | |||
254 | def_bool SOC_AT91SAM9 || SOC_SAMA5 | 337 | def_bool SOC_AT91SAM9 || SOC_SAMA5 |
255 | 338 | ||
256 | config ATMEL_ST | 339 | config ATMEL_ST |
257 | bool | 340 | bool "Atmel ST timer support" if COMPILE_TEST |
341 | depends on GENERIC_CLOCKEVENTS | ||
258 | select CLKSRC_OF | 342 | select CLKSRC_OF |
259 | select MFD_SYSCON | 343 | select MFD_SYSCON |
344 | help | ||
345 | Support for the Atmel ST timer. | ||
260 | 346 | ||
261 | config CLKSRC_METAG_GENERIC | 347 | config CLKSRC_METAG_GENERIC |
262 | def_bool y if METAG | 348 | def_bool y if METAG |
@@ -270,7 +356,7 @@ config CLKSRC_EXYNOS_MCT | |||
270 | Support for Multi Core Timer controller on Exynos SoCs. | 356 | Support for Multi Core Timer controller on Exynos SoCs. |
271 | 357 | ||
272 | config CLKSRC_SAMSUNG_PWM | 358 | config CLKSRC_SAMSUNG_PWM |
273 | bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST | 359 | bool "PWM timer driver for Samsung S3C, S5P" if COMPILE_TEST |
274 | depends on GENERIC_CLOCKEVENTS | 360 | depends on GENERIC_CLOCKEVENTS |
275 | depends on HAS_IOMEM | 361 | depends on HAS_IOMEM |
276 | help | 362 | help |
@@ -293,6 +379,14 @@ config VF_PIT_TIMER | |||
293 | help | 379 | help |
294 | Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. | 380 | Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. |
295 | 381 | ||
382 | config OXNAS_RPS_TIMER | ||
383 | bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST | ||
384 | depends on GENERIC_CLOCKEVENTS | ||
385 | select CLKSRC_OF | ||
386 | select CLKSRC_MMIO | ||
387 | help | ||
388 | This enables support for the Oxford Semiconductor OXNAS RPS timers. | ||
389 | |||
296 | config SYS_SUPPORTS_SH_CMT | 390 | config SYS_SUPPORTS_SH_CMT |
297 | bool | 391 | bool |
298 | 392 | ||
@@ -361,8 +455,8 @@ config CLKSRC_QCOM | |||
361 | Qualcomm SoCs. | 455 | Qualcomm SoCs. |
362 | 456 | ||
363 | config CLKSRC_VERSATILE | 457 | config CLKSRC_VERSATILE |
364 | bool "ARM Versatile (Express) reference platforms clock source" | 458 | bool "ARM Versatile (Express) reference platforms clock source" if COMPILE_TEST |
365 | depends on PLAT_VERSATILE && GENERIC_SCHED_CLOCK && !ARCH_USES_GETTIMEOFFSET | 459 | depends on GENERIC_SCHED_CLOCK && !ARCH_USES_GETTIMEOFFSET |
366 | select CLKSRC_OF | 460 | select CLKSRC_OF |
367 | default y if MFD_VEXPRESS_SYSREG | 461 | default y if MFD_VEXPRESS_SYSREG |
368 | help | 462 | help |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 473974f9590a..fd9d6df0bbc0 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -19,21 +19,21 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o | |||
19 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o | 19 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o |
20 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | 20 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o |
21 | obj-$(CONFIG_ORION_TIMER) += time-orion.o | 21 | obj-$(CONFIG_ORION_TIMER) += time-orion.o |
22 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | 22 | obj-$(CONFIG_BCM2835_TIMER) += bcm2835_timer.o |
23 | obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o | 23 | obj-$(CONFIG_CLPS711X_TIMER) += clps711x-timer.o |
24 | obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o | 24 | obj-$(CONFIG_ATLAS7_TIMER) += timer-atlas7.o |
25 | obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o | 25 | obj-$(CONFIG_MOXART_TIMER) += moxart_timer.o |
26 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o | 26 | obj-$(CONFIG_MXS_TIMER) += mxs_timer.o |
27 | obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o | 27 | obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o |
28 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o | 28 | obj-$(CONFIG_PRIMA2_TIMER) += timer-prima2.o |
29 | obj-$(CONFIG_ARCH_U300) += timer-u300.o | 29 | obj-$(CONFIG_U300_TIMER) += timer-u300.o |
30 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o | 30 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o |
31 | obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o | 31 | obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o |
32 | obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o | 32 | obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o |
33 | obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o | 33 | obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o |
34 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o | 34 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o |
35 | obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o | 35 | obj-$(CONFIG_NSPIRE_TIMER) += zevio-timer.o |
36 | obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o | 36 | obj-$(CONFIG_BCM_KONA_TIMER) += bcm_kona_timer.o |
37 | obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o | 37 | obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o |
38 | obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o | 38 | obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o |
39 | obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o | 39 | obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o |
@@ -48,6 +48,7 @@ obj-$(CONFIG_MTK_TIMER) += mtk_timer.o | |||
48 | obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o | 48 | obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o |
49 | obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o | 49 | obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o |
50 | obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o | 50 | obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o |
51 | obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o | ||
51 | 52 | ||
52 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o | 53 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o |
53 | obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o | 54 | obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o |
@@ -55,8 +56,8 @@ obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o | |||
55 | obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp804.o | 56 | obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp804.o |
56 | obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o | 57 | obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o |
57 | obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o | 58 | obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o |
58 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o | 59 | obj-$(CONFIG_KEYSTONE_TIMER) += timer-keystone.o |
59 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o | 60 | obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o |
60 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o | 61 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o |
61 | obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o | 62 | obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o |
62 | obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o | 63 | obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o |
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 4814446a0024..5effd3027319 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -79,6 +79,14 @@ static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; | |||
79 | static bool arch_timer_c3stop; | 79 | static bool arch_timer_c3stop; |
80 | static bool arch_timer_mem_use_virtual; | 80 | static bool arch_timer_mem_use_virtual; |
81 | 81 | ||
82 | static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); | ||
83 | |||
84 | static int __init early_evtstrm_cfg(char *buf) | ||
85 | { | ||
86 | return strtobool(buf, &evtstrm_enable); | ||
87 | } | ||
88 | early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg); | ||
89 | |||
82 | /* | 90 | /* |
83 | * Architected system timer support. | 91 | * Architected system timer support. |
84 | */ | 92 | */ |
@@ -372,7 +380,7 @@ static int arch_timer_setup(struct clock_event_device *clk) | |||
372 | enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0); | 380 | enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0); |
373 | 381 | ||
374 | arch_counter_set_user_access(); | 382 | arch_counter_set_user_access(); |
375 | if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM)) | 383 | if (evtstrm_enable) |
376 | arch_timer_configure_evtstream(); | 384 | arch_timer_configure_evtstream(); |
377 | 385 | ||
378 | return 0; | 386 | return 0; |
@@ -693,25 +701,26 @@ arch_timer_needs_probing(int type, const struct of_device_id *matches) | |||
693 | return needs_probing; | 701 | return needs_probing; |
694 | } | 702 | } |
695 | 703 | ||
696 | static void __init arch_timer_common_init(void) | 704 | static int __init arch_timer_common_init(void) |
697 | { | 705 | { |
698 | unsigned mask = ARCH_CP15_TIMER | ARCH_MEM_TIMER; | 706 | unsigned mask = ARCH_CP15_TIMER | ARCH_MEM_TIMER; |
699 | 707 | ||
700 | /* Wait until both nodes are probed if we have two timers */ | 708 | /* Wait until both nodes are probed if we have two timers */ |
701 | if ((arch_timers_present & mask) != mask) { | 709 | if ((arch_timers_present & mask) != mask) { |
702 | if (arch_timer_needs_probing(ARCH_MEM_TIMER, arch_timer_mem_of_match)) | 710 | if (arch_timer_needs_probing(ARCH_MEM_TIMER, arch_timer_mem_of_match)) |
703 | return; | 711 | return 0; |
704 | if (arch_timer_needs_probing(ARCH_CP15_TIMER, arch_timer_of_match)) | 712 | if (arch_timer_needs_probing(ARCH_CP15_TIMER, arch_timer_of_match)) |
705 | return; | 713 | return 0; |
706 | } | 714 | } |
707 | 715 | ||
708 | arch_timer_banner(arch_timers_present); | 716 | arch_timer_banner(arch_timers_present); |
709 | arch_counter_register(arch_timers_present); | 717 | arch_counter_register(arch_timers_present); |
710 | arch_timer_arch_init(); | 718 | return arch_timer_arch_init(); |
711 | } | 719 | } |
712 | 720 | ||
713 | static void __init arch_timer_init(void) | 721 | static int __init arch_timer_init(void) |
714 | { | 722 | { |
723 | int ret; | ||
715 | /* | 724 | /* |
716 | * If HYP mode is available, we know that the physical timer | 725 | * If HYP mode is available, we know that the physical timer |
717 | * has been configured to be accessible from PL1. Use it, so | 726 | * has been configured to be accessible from PL1. Use it, so |
@@ -739,23 +748,30 @@ static void __init arch_timer_init(void) | |||
739 | 748 | ||
740 | if (!has_ppi) { | 749 | if (!has_ppi) { |
741 | pr_warn("arch_timer: No interrupt available, giving up\n"); | 750 | pr_warn("arch_timer: No interrupt available, giving up\n"); |
742 | return; | 751 | return -EINVAL; |
743 | } | 752 | } |
744 | } | 753 | } |
745 | 754 | ||
746 | arch_timer_register(); | 755 | ret = arch_timer_register(); |
747 | arch_timer_common_init(); | 756 | if (ret) |
757 | return ret; | ||
758 | |||
759 | ret = arch_timer_common_init(); | ||
760 | if (ret) | ||
761 | return ret; | ||
748 | 762 | ||
749 | arch_timer_kvm_info.virtual_irq = arch_timer_ppi[VIRT_PPI]; | 763 | arch_timer_kvm_info.virtual_irq = arch_timer_ppi[VIRT_PPI]; |
764 | |||
765 | return 0; | ||
750 | } | 766 | } |
751 | 767 | ||
752 | static void __init arch_timer_of_init(struct device_node *np) | 768 | static int __init arch_timer_of_init(struct device_node *np) |
753 | { | 769 | { |
754 | int i; | 770 | int i; |
755 | 771 | ||
756 | if (arch_timers_present & ARCH_CP15_TIMER) { | 772 | if (arch_timers_present & ARCH_CP15_TIMER) { |
757 | pr_warn("arch_timer: multiple nodes in dt, skipping\n"); | 773 | pr_warn("arch_timer: multiple nodes in dt, skipping\n"); |
758 | return; | 774 | return 0; |
759 | } | 775 | } |
760 | 776 | ||
761 | arch_timers_present |= ARCH_CP15_TIMER; | 777 | arch_timers_present |= ARCH_CP15_TIMER; |
@@ -774,23 +790,23 @@ static void __init arch_timer_of_init(struct device_node *np) | |||
774 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) | 790 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) |
775 | arch_timer_uses_ppi = PHYS_SECURE_PPI; | 791 | arch_timer_uses_ppi = PHYS_SECURE_PPI; |
776 | 792 | ||
777 | arch_timer_init(); | 793 | return arch_timer_init(); |
778 | } | 794 | } |
779 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); | 795 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); |
780 | CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); | 796 | CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); |
781 | 797 | ||
782 | static void __init arch_timer_mem_init(struct device_node *np) | 798 | static int __init arch_timer_mem_init(struct device_node *np) |
783 | { | 799 | { |
784 | struct device_node *frame, *best_frame = NULL; | 800 | struct device_node *frame, *best_frame = NULL; |
785 | void __iomem *cntctlbase, *base; | 801 | void __iomem *cntctlbase, *base; |
786 | unsigned int irq; | 802 | unsigned int irq, ret = -EINVAL; |
787 | u32 cnttidr; | 803 | u32 cnttidr; |
788 | 804 | ||
789 | arch_timers_present |= ARCH_MEM_TIMER; | 805 | arch_timers_present |= ARCH_MEM_TIMER; |
790 | cntctlbase = of_iomap(np, 0); | 806 | cntctlbase = of_iomap(np, 0); |
791 | if (!cntctlbase) { | 807 | if (!cntctlbase) { |
792 | pr_err("arch_timer: Can't find CNTCTLBase\n"); | 808 | pr_err("arch_timer: Can't find CNTCTLBase\n"); |
793 | return; | 809 | return -ENXIO; |
794 | } | 810 | } |
795 | 811 | ||
796 | cnttidr = readl_relaxed(cntctlbase + CNTTIDR); | 812 | cnttidr = readl_relaxed(cntctlbase + CNTTIDR); |
@@ -830,6 +846,7 @@ static void __init arch_timer_mem_init(struct device_node *np) | |||
830 | best_frame = of_node_get(frame); | 846 | best_frame = of_node_get(frame); |
831 | } | 847 | } |
832 | 848 | ||
849 | ret= -ENXIO; | ||
833 | base = arch_counter_base = of_iomap(best_frame, 0); | 850 | base = arch_counter_base = of_iomap(best_frame, 0); |
834 | if (!base) { | 851 | if (!base) { |
835 | pr_err("arch_timer: Can't map frame's registers\n"); | 852 | pr_err("arch_timer: Can't map frame's registers\n"); |
@@ -841,6 +858,7 @@ static void __init arch_timer_mem_init(struct device_node *np) | |||
841 | else | 858 | else |
842 | irq = irq_of_parse_and_map(best_frame, 0); | 859 | irq = irq_of_parse_and_map(best_frame, 0); |
843 | 860 | ||
861 | ret = -EINVAL; | ||
844 | if (!irq) { | 862 | if (!irq) { |
845 | pr_err("arch_timer: Frame missing %s irq", | 863 | pr_err("arch_timer: Frame missing %s irq", |
846 | arch_timer_mem_use_virtual ? "virt" : "phys"); | 864 | arch_timer_mem_use_virtual ? "virt" : "phys"); |
@@ -848,11 +866,15 @@ static void __init arch_timer_mem_init(struct device_node *np) | |||
848 | } | 866 | } |
849 | 867 | ||
850 | arch_timer_detect_rate(base, np); | 868 | arch_timer_detect_rate(base, np); |
851 | arch_timer_mem_register(base, irq); | 869 | ret = arch_timer_mem_register(base, irq); |
852 | arch_timer_common_init(); | 870 | if (ret) |
871 | goto out; | ||
872 | |||
873 | return arch_timer_common_init(); | ||
853 | out: | 874 | out: |
854 | iounmap(cntctlbase); | 875 | iounmap(cntctlbase); |
855 | of_node_put(best_frame); | 876 | of_node_put(best_frame); |
877 | return ret; | ||
856 | } | 878 | } |
857 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", | 879 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", |
858 | arch_timer_mem_init); | 880 | arch_timer_mem_init); |
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index 9df0d1699d22..2a9ceb6e93f9 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c | |||
@@ -238,7 +238,7 @@ static void __init gt_delay_timer_init(void) | |||
238 | register_current_timer_delay(>_delay_timer); | 238 | register_current_timer_delay(>_delay_timer); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void __init gt_clocksource_init(void) | 241 | static int __init gt_clocksource_init(void) |
242 | { | 242 | { |
243 | writel(0, gt_base + GT_CONTROL); | 243 | writel(0, gt_base + GT_CONTROL); |
244 | writel(0, gt_base + GT_COUNTER0); | 244 | writel(0, gt_base + GT_COUNTER0); |
@@ -249,7 +249,7 @@ static void __init gt_clocksource_init(void) | |||
249 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | 249 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
250 | sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate); | 250 | sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate); |
251 | #endif | 251 | #endif |
252 | clocksource_register_hz(>_clocksource, gt_clk_rate); | 252 | return clocksource_register_hz(>_clocksource, gt_clk_rate); |
253 | } | 253 | } |
254 | 254 | ||
255 | static int gt_cpu_notify(struct notifier_block *self, unsigned long action, | 255 | static int gt_cpu_notify(struct notifier_block *self, unsigned long action, |
@@ -270,7 +270,7 @@ static struct notifier_block gt_cpu_nb = { | |||
270 | .notifier_call = gt_cpu_notify, | 270 | .notifier_call = gt_cpu_notify, |
271 | }; | 271 | }; |
272 | 272 | ||
273 | static void __init global_timer_of_register(struct device_node *np) | 273 | static int __init global_timer_of_register(struct device_node *np) |
274 | { | 274 | { |
275 | struct clk *gt_clk; | 275 | struct clk *gt_clk; |
276 | int err = 0; | 276 | int err = 0; |
@@ -283,19 +283,19 @@ static void __init global_timer_of_register(struct device_node *np) | |||
283 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9 | 283 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9 |
284 | && (read_cpuid_id() & 0xf0000f) < 0x200000) { | 284 | && (read_cpuid_id() & 0xf0000f) < 0x200000) { |
285 | pr_warn("global-timer: non support for this cpu version.\n"); | 285 | pr_warn("global-timer: non support for this cpu version.\n"); |
286 | return; | 286 | return -ENOSYS; |
287 | } | 287 | } |
288 | 288 | ||
289 | gt_ppi = irq_of_parse_and_map(np, 0); | 289 | gt_ppi = irq_of_parse_and_map(np, 0); |
290 | if (!gt_ppi) { | 290 | if (!gt_ppi) { |
291 | pr_warn("global-timer: unable to parse irq\n"); | 291 | pr_warn("global-timer: unable to parse irq\n"); |
292 | return; | 292 | return -EINVAL; |
293 | } | 293 | } |
294 | 294 | ||
295 | gt_base = of_iomap(np, 0); | 295 | gt_base = of_iomap(np, 0); |
296 | if (!gt_base) { | 296 | if (!gt_base) { |
297 | pr_warn("global-timer: invalid base address\n"); | 297 | pr_warn("global-timer: invalid base address\n"); |
298 | return; | 298 | return -ENXIO; |
299 | } | 299 | } |
300 | 300 | ||
301 | gt_clk = of_clk_get(np, 0); | 301 | gt_clk = of_clk_get(np, 0); |
@@ -332,11 +332,17 @@ static void __init global_timer_of_register(struct device_node *np) | |||
332 | } | 332 | } |
333 | 333 | ||
334 | /* Immediately configure the timer on the boot CPU */ | 334 | /* Immediately configure the timer on the boot CPU */ |
335 | gt_clocksource_init(); | 335 | err = gt_clocksource_init(); |
336 | gt_clockevents_init(this_cpu_ptr(gt_evt)); | 336 | if (err) |
337 | goto out_irq; | ||
338 | |||
339 | err = gt_clockevents_init(this_cpu_ptr(gt_evt)); | ||
340 | if (err) | ||
341 | goto out_irq; | ||
342 | |||
337 | gt_delay_timer_init(); | 343 | gt_delay_timer_init(); |
338 | 344 | ||
339 | return; | 345 | return 0; |
340 | 346 | ||
341 | out_irq: | 347 | out_irq: |
342 | free_percpu_irq(gt_ppi, gt_evt); | 348 | free_percpu_irq(gt_ppi, gt_evt); |
@@ -347,6 +353,8 @@ out_clk: | |||
347 | out_unmap: | 353 | out_unmap: |
348 | iounmap(gt_base); | 354 | iounmap(gt_base); |
349 | WARN(err, "ARM Global timer register failed (%d)\n", err); | 355 | WARN(err, "ARM Global timer register failed (%d)\n", err); |
356 | |||
357 | return err; | ||
350 | } | 358 | } |
351 | 359 | ||
352 | /* Only tested on r2p2 and r3p0 */ | 360 | /* Only tested on r2p2 and r3p0 */ |
diff --git a/drivers/clocksource/armv7m_systick.c b/drivers/clocksource/armv7m_systick.c index addfd2c64f54..a315491b7047 100644 --- a/drivers/clocksource/armv7m_systick.c +++ b/drivers/clocksource/armv7m_systick.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/clocksource.h> | 8 | #include <linux/clocksource.h> |
9 | #include <linux/clockchips.h> | 9 | #include <linux/clockchips.h> |
10 | #include <linux/io.h> | ||
10 | #include <linux/of.h> | 11 | #include <linux/of.h> |
11 | #include <linux/of_address.h> | 12 | #include <linux/of_address.h> |
12 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
@@ -21,7 +22,7 @@ | |||
21 | 22 | ||
22 | #define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF | 23 | #define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF |
23 | 24 | ||
24 | static void __init system_timer_of_register(struct device_node *np) | 25 | static int __init system_timer_of_register(struct device_node *np) |
25 | { | 26 | { |
26 | struct clk *clk = NULL; | 27 | struct clk *clk = NULL; |
27 | void __iomem *base; | 28 | void __iomem *base; |
@@ -31,22 +32,26 @@ static void __init system_timer_of_register(struct device_node *np) | |||
31 | base = of_iomap(np, 0); | 32 | base = of_iomap(np, 0); |
32 | if (!base) { | 33 | if (!base) { |
33 | pr_warn("system-timer: invalid base address\n"); | 34 | pr_warn("system-timer: invalid base address\n"); |
34 | return; | 35 | return -ENXIO; |
35 | } | 36 | } |
36 | 37 | ||
37 | ret = of_property_read_u32(np, "clock-frequency", &rate); | 38 | ret = of_property_read_u32(np, "clock-frequency", &rate); |
38 | if (ret) { | 39 | if (ret) { |
39 | clk = of_clk_get(np, 0); | 40 | clk = of_clk_get(np, 0); |
40 | if (IS_ERR(clk)) | 41 | if (IS_ERR(clk)) { |
42 | ret = PTR_ERR(clk); | ||
41 | goto out_unmap; | 43 | goto out_unmap; |
44 | } | ||
42 | 45 | ||
43 | ret = clk_prepare_enable(clk); | 46 | ret = clk_prepare_enable(clk); |
44 | if (ret) | 47 | if (ret) |
45 | goto out_clk_put; | 48 | goto out_clk_put; |
46 | 49 | ||
47 | rate = clk_get_rate(clk); | 50 | rate = clk_get_rate(clk); |
48 | if (!rate) | 51 | if (!rate) { |
52 | ret = -EINVAL; | ||
49 | goto out_clk_disable; | 53 | goto out_clk_disable; |
54 | } | ||
50 | } | 55 | } |
51 | 56 | ||
52 | writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, base + SYST_RVR); | 57 | writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, base + SYST_RVR); |
@@ -64,7 +69,7 @@ static void __init system_timer_of_register(struct device_node *np) | |||
64 | 69 | ||
65 | pr_info("ARM System timer initialized as clocksource\n"); | 70 | pr_info("ARM System timer initialized as clocksource\n"); |
66 | 71 | ||
67 | return; | 72 | return 0; |
68 | 73 | ||
69 | out_clk_disable: | 74 | out_clk_disable: |
70 | clk_disable_unprepare(clk); | 75 | clk_disable_unprepare(clk); |
@@ -73,6 +78,8 @@ out_clk_put: | |||
73 | out_unmap: | 78 | out_unmap: |
74 | iounmap(base); | 79 | iounmap(base); |
75 | pr_warn("ARM System timer register failed (%d)\n", ret); | 80 | pr_warn("ARM System timer register failed (%d)\n", ret); |
81 | |||
82 | return ret; | ||
76 | } | 83 | } |
77 | 84 | ||
78 | CLOCKSOURCE_OF_DECLARE(arm_systick, "arm,armv7m-systick", | 85 | CLOCKSOURCE_OF_DECLARE(arm_systick, "arm,armv7m-systick", |
diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c index 217438d39eb3..1ba871b7fe11 100644 --- a/drivers/clocksource/asm9260_timer.c +++ b/drivers/clocksource/asm9260_timer.c | |||
@@ -184,7 +184,7 @@ static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id) | |||
184 | * Timer initialization | 184 | * Timer initialization |
185 | * --------------------------------------------------------------------------- | 185 | * --------------------------------------------------------------------------- |
186 | */ | 186 | */ |
187 | static void __init asm9260_timer_init(struct device_node *np) | 187 | static int __init asm9260_timer_init(struct device_node *np) |
188 | { | 188 | { |
189 | int irq; | 189 | int irq; |
190 | struct clk *clk; | 190 | struct clk *clk; |
@@ -192,20 +192,26 @@ static void __init asm9260_timer_init(struct device_node *np) | |||
192 | unsigned long rate; | 192 | unsigned long rate; |
193 | 193 | ||
194 | priv.base = of_io_request_and_map(np, 0, np->name); | 194 | priv.base = of_io_request_and_map(np, 0, np->name); |
195 | if (IS_ERR(priv.base)) | 195 | if (IS_ERR(priv.base)) { |
196 | panic("%s: unable to map resource", np->name); | 196 | pr_err("%s: unable to map resource", np->name); |
197 | return PTR_ERR(priv.base); | ||
198 | } | ||
197 | 199 | ||
198 | clk = of_clk_get(np, 0); | 200 | clk = of_clk_get(np, 0); |
199 | 201 | ||
200 | ret = clk_prepare_enable(clk); | 202 | ret = clk_prepare_enable(clk); |
201 | if (ret) | 203 | if (ret) { |
202 | panic("Failed to enable clk!\n"); | 204 | pr_err("Failed to enable clk!\n"); |
205 | return ret; | ||
206 | } | ||
203 | 207 | ||
204 | irq = irq_of_parse_and_map(np, 0); | 208 | irq = irq_of_parse_and_map(np, 0); |
205 | ret = request_irq(irq, asm9260_timer_interrupt, IRQF_TIMER, | 209 | ret = request_irq(irq, asm9260_timer_interrupt, IRQF_TIMER, |
206 | DRIVER_NAME, &event_dev); | 210 | DRIVER_NAME, &event_dev); |
207 | if (ret) | 211 | if (ret) { |
208 | panic("Failed to setup irq!\n"); | 212 | pr_err("Failed to setup irq!\n"); |
213 | return ret; | ||
214 | } | ||
209 | 215 | ||
210 | /* set all timers for count-up */ | 216 | /* set all timers for count-up */ |
211 | writel_relaxed(BM_DIR_DEFAULT, priv.base + HW_DIR); | 217 | writel_relaxed(BM_DIR_DEFAULT, priv.base + HW_DIR); |
@@ -229,6 +235,8 @@ static void __init asm9260_timer_init(struct device_node *np) | |||
229 | priv.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); | 235 | priv.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); |
230 | event_dev.cpumask = cpumask_of(0); | 236 | event_dev.cpumask = cpumask_of(0); |
231 | clockevents_config_and_register(&event_dev, rate, 0x2c00, 0xfffffffe); | 237 | clockevents_config_and_register(&event_dev, rate, 0x2c00, 0xfffffffe); |
238 | |||
239 | return 0; | ||
232 | } | 240 | } |
233 | CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer", | 241 | CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer", |
234 | asm9260_timer_init); | 242 | asm9260_timer_init); |
diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c index 6f2822928963..e71acf231c89 100644 --- a/drivers/clocksource/bcm2835_timer.c +++ b/drivers/clocksource/bcm2835_timer.c | |||
@@ -80,19 +80,24 @@ static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id) | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | static void __init bcm2835_timer_init(struct device_node *node) | 83 | static int __init bcm2835_timer_init(struct device_node *node) |
84 | { | 84 | { |
85 | void __iomem *base; | 85 | void __iomem *base; |
86 | u32 freq; | 86 | u32 freq; |
87 | int irq; | 87 | int irq, ret; |
88 | struct bcm2835_timer *timer; | 88 | struct bcm2835_timer *timer; |
89 | 89 | ||
90 | base = of_iomap(node, 0); | 90 | base = of_iomap(node, 0); |
91 | if (!base) | 91 | if (!base) { |
92 | panic("Can't remap registers"); | 92 | pr_err("Can't remap registers"); |
93 | return -ENXIO; | ||
94 | } | ||
93 | 95 | ||
94 | if (of_property_read_u32(node, "clock-frequency", &freq)) | 96 | ret = of_property_read_u32(node, "clock-frequency", &freq); |
95 | panic("Can't read clock-frequency"); | 97 | if (ret) { |
98 | pr_err("Can't read clock-frequency"); | ||
99 | return ret; | ||
100 | } | ||
96 | 101 | ||
97 | system_clock = base + REG_COUNTER_LO; | 102 | system_clock = base + REG_COUNTER_LO; |
98 | sched_clock_register(bcm2835_sched_read, 32, freq); | 103 | sched_clock_register(bcm2835_sched_read, 32, freq); |
@@ -101,12 +106,16 @@ static void __init bcm2835_timer_init(struct device_node *node) | |||
101 | freq, 300, 32, clocksource_mmio_readl_up); | 106 | freq, 300, 32, clocksource_mmio_readl_up); |
102 | 107 | ||
103 | irq = irq_of_parse_and_map(node, DEFAULT_TIMER); | 108 | irq = irq_of_parse_and_map(node, DEFAULT_TIMER); |
104 | if (irq <= 0) | 109 | if (irq <= 0) { |
105 | panic("Can't parse IRQ"); | 110 | pr_err("Can't parse IRQ"); |
111 | return -EINVAL; | ||
112 | } | ||
106 | 113 | ||
107 | timer = kzalloc(sizeof(*timer), GFP_KERNEL); | 114 | timer = kzalloc(sizeof(*timer), GFP_KERNEL); |
108 | if (!timer) | 115 | if (!timer) { |
109 | panic("Can't allocate timer struct\n"); | 116 | pr_err("Can't allocate timer struct\n"); |
117 | return -ENOMEM; | ||
118 | } | ||
110 | 119 | ||
111 | timer->control = base + REG_CONTROL; | 120 | timer->control = base + REG_CONTROL; |
112 | timer->compare = base + REG_COMPARE(DEFAULT_TIMER); | 121 | timer->compare = base + REG_COMPARE(DEFAULT_TIMER); |
@@ -121,12 +130,17 @@ static void __init bcm2835_timer_init(struct device_node *node) | |||
121 | timer->act.dev_id = timer; | 130 | timer->act.dev_id = timer; |
122 | timer->act.handler = bcm2835_time_interrupt; | 131 | timer->act.handler = bcm2835_time_interrupt; |
123 | 132 | ||
124 | if (setup_irq(irq, &timer->act)) | 133 | ret = setup_irq(irq, &timer->act); |
125 | panic("Can't set up timer IRQ\n"); | 134 | if (ret) { |
135 | pr_err("Can't set up timer IRQ\n"); | ||
136 | return ret; | ||
137 | } | ||
126 | 138 | ||
127 | clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); | 139 | clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); |
128 | 140 | ||
129 | pr_info("bcm2835: system timer (irq = %d)\n", irq); | 141 | pr_info("bcm2835: system timer (irq = %d)\n", irq); |
142 | |||
143 | return 0; | ||
130 | } | 144 | } |
131 | CLOCKSOURCE_OF_DECLARE(bcm2835, "brcm,bcm2835-system-timer", | 145 | CLOCKSOURCE_OF_DECLARE(bcm2835, "brcm,bcm2835-system-timer", |
132 | bcm2835_timer_init); | 146 | bcm2835_timer_init); |
diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index e717e87df9bc..7e3fd375a627 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | 21 | ||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <asm/mach/time.h> | ||
24 | 23 | ||
25 | #include <linux/of.h> | 24 | #include <linux/of.h> |
26 | #include <linux/of_address.h> | 25 | #include <linux/of_address.h> |
@@ -163,16 +162,11 @@ static struct irqaction kona_timer_irq = { | |||
163 | .handler = kona_timer_interrupt, | 162 | .handler = kona_timer_interrupt, |
164 | }; | 163 | }; |
165 | 164 | ||
166 | static void __init kona_timer_init(struct device_node *node) | 165 | static int __init kona_timer_init(struct device_node *node) |
167 | { | 166 | { |
168 | u32 freq; | 167 | u32 freq; |
169 | struct clk *external_clk; | 168 | struct clk *external_clk; |
170 | 169 | ||
171 | if (!of_device_is_available(node)) { | ||
172 | pr_info("Kona Timer v1 marked as disabled in device tree\n"); | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | external_clk = of_clk_get_by_name(node, NULL); | 170 | external_clk = of_clk_get_by_name(node, NULL); |
177 | 171 | ||
178 | if (!IS_ERR(external_clk)) { | 172 | if (!IS_ERR(external_clk)) { |
@@ -182,7 +176,7 @@ static void __init kona_timer_init(struct device_node *node) | |||
182 | arch_timer_rate = freq; | 176 | arch_timer_rate = freq; |
183 | } else { | 177 | } else { |
184 | pr_err("Kona Timer v1 unable to determine clock-frequency"); | 178 | pr_err("Kona Timer v1 unable to determine clock-frequency"); |
185 | return; | 179 | return -EINVAL; |
186 | } | 180 | } |
187 | 181 | ||
188 | /* Setup IRQ numbers */ | 182 | /* Setup IRQ numbers */ |
@@ -196,6 +190,8 @@ static void __init kona_timer_init(struct device_node *node) | |||
196 | kona_timer_clockevents_init(); | 190 | kona_timer_clockevents_init(); |
197 | setup_irq(timers.tmr_irq, &kona_timer_irq); | 191 | setup_irq(timers.tmr_irq, &kona_timer_irq); |
198 | kona_timer_set_next_event((arch_timer_rate / HZ), NULL); | 192 | kona_timer_set_next_event((arch_timer_rate / HZ), NULL); |
193 | |||
194 | return 0; | ||
199 | } | 195 | } |
200 | 196 | ||
201 | CLOCKSOURCE_OF_DECLARE(brcm_kona, "brcm,kona-timer", kona_timer_init); | 197 | CLOCKSOURCE_OF_DECLARE(brcm_kona, "brcm,kona-timer", kona_timer_init); |
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index 9be6018bd2b8..fbfbdec13b08 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c | |||
@@ -322,22 +322,22 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, | |||
322 | return NOTIFY_DONE; | 322 | return NOTIFY_DONE; |
323 | } | 323 | } |
324 | 324 | ||
325 | static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, | 325 | static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, |
326 | u32 timer_width) | 326 | u32 timer_width) |
327 | { | 327 | { |
328 | struct ttc_timer_clocksource *ttccs; | 328 | struct ttc_timer_clocksource *ttccs; |
329 | int err; | 329 | int err; |
330 | 330 | ||
331 | ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); | 331 | ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); |
332 | if (WARN_ON(!ttccs)) | 332 | if (!ttccs) |
333 | return; | 333 | return -ENOMEM; |
334 | 334 | ||
335 | ttccs->ttc.clk = clk; | 335 | ttccs->ttc.clk = clk; |
336 | 336 | ||
337 | err = clk_prepare_enable(ttccs->ttc.clk); | 337 | err = clk_prepare_enable(ttccs->ttc.clk); |
338 | if (WARN_ON(err)) { | 338 | if (err) { |
339 | kfree(ttccs); | 339 | kfree(ttccs); |
340 | return; | 340 | return err; |
341 | } | 341 | } |
342 | 342 | ||
343 | ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); | 343 | ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); |
@@ -345,8 +345,10 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, | |||
345 | ttccs->ttc.clk_rate_change_nb.notifier_call = | 345 | ttccs->ttc.clk_rate_change_nb.notifier_call = |
346 | ttc_rate_change_clocksource_cb; | 346 | ttc_rate_change_clocksource_cb; |
347 | ttccs->ttc.clk_rate_change_nb.next = NULL; | 347 | ttccs->ttc.clk_rate_change_nb.next = NULL; |
348 | if (clk_notifier_register(ttccs->ttc.clk, | 348 | |
349 | &ttccs->ttc.clk_rate_change_nb)) | 349 | err = clk_notifier_register(ttccs->ttc.clk, |
350 | &ttccs->ttc.clk_rate_change_nb); | ||
351 | if (err) | ||
350 | pr_warn("Unable to register clock notifier.\n"); | 352 | pr_warn("Unable to register clock notifier.\n"); |
351 | 353 | ||
352 | ttccs->ttc.base_addr = base; | 354 | ttccs->ttc.base_addr = base; |
@@ -368,14 +370,16 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, | |||
368 | ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); | 370 | ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); |
369 | 371 | ||
370 | err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); | 372 | err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); |
371 | if (WARN_ON(err)) { | 373 | if (err) { |
372 | kfree(ttccs); | 374 | kfree(ttccs); |
373 | return; | 375 | return err; |
374 | } | 376 | } |
375 | 377 | ||
376 | ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; | 378 | ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; |
377 | sched_clock_register(ttc_sched_clock_read, timer_width, | 379 | sched_clock_register(ttc_sched_clock_read, timer_width, |
378 | ttccs->ttc.freq / PRESCALE); | 380 | ttccs->ttc.freq / PRESCALE); |
381 | |||
382 | return 0; | ||
379 | } | 383 | } |
380 | 384 | ||
381 | static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, | 385 | static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, |
@@ -401,30 +405,35 @@ static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, | |||
401 | } | 405 | } |
402 | } | 406 | } |
403 | 407 | ||
404 | static void __init ttc_setup_clockevent(struct clk *clk, | 408 | static int __init ttc_setup_clockevent(struct clk *clk, |
405 | void __iomem *base, u32 irq) | 409 | void __iomem *base, u32 irq) |
406 | { | 410 | { |
407 | struct ttc_timer_clockevent *ttcce; | 411 | struct ttc_timer_clockevent *ttcce; |
408 | int err; | 412 | int err; |
409 | 413 | ||
410 | ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); | 414 | ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); |
411 | if (WARN_ON(!ttcce)) | 415 | if (!ttcce) |
412 | return; | 416 | return -ENOMEM; |
413 | 417 | ||
414 | ttcce->ttc.clk = clk; | 418 | ttcce->ttc.clk = clk; |
415 | 419 | ||
416 | err = clk_prepare_enable(ttcce->ttc.clk); | 420 | err = clk_prepare_enable(ttcce->ttc.clk); |
417 | if (WARN_ON(err)) { | 421 | if (err) { |
418 | kfree(ttcce); | 422 | kfree(ttcce); |
419 | return; | 423 | return err; |
420 | } | 424 | } |
421 | 425 | ||
422 | ttcce->ttc.clk_rate_change_nb.notifier_call = | 426 | ttcce->ttc.clk_rate_change_nb.notifier_call = |
423 | ttc_rate_change_clockevent_cb; | 427 | ttc_rate_change_clockevent_cb; |
424 | ttcce->ttc.clk_rate_change_nb.next = NULL; | 428 | ttcce->ttc.clk_rate_change_nb.next = NULL; |
425 | if (clk_notifier_register(ttcce->ttc.clk, | 429 | |
426 | &ttcce->ttc.clk_rate_change_nb)) | 430 | err = clk_notifier_register(ttcce->ttc.clk, |
431 | &ttcce->ttc.clk_rate_change_nb); | ||
432 | if (err) { | ||
427 | pr_warn("Unable to register clock notifier.\n"); | 433 | pr_warn("Unable to register clock notifier.\n"); |
434 | return err; | ||
435 | } | ||
436 | |||
428 | ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); | 437 | ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); |
429 | 438 | ||
430 | ttcce->ttc.base_addr = base; | 439 | ttcce->ttc.base_addr = base; |
@@ -451,13 +460,15 @@ static void __init ttc_setup_clockevent(struct clk *clk, | |||
451 | 460 | ||
452 | err = request_irq(irq, ttc_clock_event_interrupt, | 461 | err = request_irq(irq, ttc_clock_event_interrupt, |
453 | IRQF_TIMER, ttcce->ce.name, ttcce); | 462 | IRQF_TIMER, ttcce->ce.name, ttcce); |
454 | if (WARN_ON(err)) { | 463 | if (err) { |
455 | kfree(ttcce); | 464 | kfree(ttcce); |
456 | return; | 465 | return err; |
457 | } | 466 | } |
458 | 467 | ||
459 | clockevents_config_and_register(&ttcce->ce, | 468 | clockevents_config_and_register(&ttcce->ce, |
460 | ttcce->ttc.freq / PRESCALE, 1, 0xfffe); | 469 | ttcce->ttc.freq / PRESCALE, 1, 0xfffe); |
470 | |||
471 | return 0; | ||
461 | } | 472 | } |
462 | 473 | ||
463 | /** | 474 | /** |
@@ -466,17 +477,17 @@ static void __init ttc_setup_clockevent(struct clk *clk, | |||
466 | * Initializes the timer hardware and register the clock source and clock event | 477 | * Initializes the timer hardware and register the clock source and clock event |
467 | * timers with Linux kernal timer framework | 478 | * timers with Linux kernal timer framework |
468 | */ | 479 | */ |
469 | static void __init ttc_timer_init(struct device_node *timer) | 480 | static int __init ttc_timer_init(struct device_node *timer) |
470 | { | 481 | { |
471 | unsigned int irq; | 482 | unsigned int irq; |
472 | void __iomem *timer_baseaddr; | 483 | void __iomem *timer_baseaddr; |
473 | struct clk *clk_cs, *clk_ce; | 484 | struct clk *clk_cs, *clk_ce; |
474 | static int initialized; | 485 | static int initialized; |
475 | int clksel; | 486 | int clksel, ret; |
476 | u32 timer_width = 16; | 487 | u32 timer_width = 16; |
477 | 488 | ||
478 | if (initialized) | 489 | if (initialized) |
479 | return; | 490 | return 0; |
480 | 491 | ||
481 | initialized = 1; | 492 | initialized = 1; |
482 | 493 | ||
@@ -488,13 +499,13 @@ static void __init ttc_timer_init(struct device_node *timer) | |||
488 | timer_baseaddr = of_iomap(timer, 0); | 499 | timer_baseaddr = of_iomap(timer, 0); |
489 | if (!timer_baseaddr) { | 500 | if (!timer_baseaddr) { |
490 | pr_err("ERROR: invalid timer base address\n"); | 501 | pr_err("ERROR: invalid timer base address\n"); |
491 | BUG(); | 502 | return -ENXIO; |
492 | } | 503 | } |
493 | 504 | ||
494 | irq = irq_of_parse_and_map(timer, 1); | 505 | irq = irq_of_parse_and_map(timer, 1); |
495 | if (irq <= 0) { | 506 | if (irq <= 0) { |
496 | pr_err("ERROR: invalid interrupt number\n"); | 507 | pr_err("ERROR: invalid interrupt number\n"); |
497 | BUG(); | 508 | return -EINVAL; |
498 | } | 509 | } |
499 | 510 | ||
500 | of_property_read_u32(timer, "timer-width", &timer_width); | 511 | of_property_read_u32(timer, "timer-width", &timer_width); |
@@ -504,7 +515,7 @@ static void __init ttc_timer_init(struct device_node *timer) | |||
504 | clk_cs = of_clk_get(timer, clksel); | 515 | clk_cs = of_clk_get(timer, clksel); |
505 | if (IS_ERR(clk_cs)) { | 516 | if (IS_ERR(clk_cs)) { |
506 | pr_err("ERROR: timer input clock not found\n"); | 517 | pr_err("ERROR: timer input clock not found\n"); |
507 | BUG(); | 518 | return PTR_ERR(clk_cs); |
508 | } | 519 | } |
509 | 520 | ||
510 | clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); | 521 | clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); |
@@ -512,13 +523,20 @@ static void __init ttc_timer_init(struct device_node *timer) | |||
512 | clk_ce = of_clk_get(timer, clksel); | 523 | clk_ce = of_clk_get(timer, clksel); |
513 | if (IS_ERR(clk_ce)) { | 524 | if (IS_ERR(clk_ce)) { |
514 | pr_err("ERROR: timer input clock not found\n"); | 525 | pr_err("ERROR: timer input clock not found\n"); |
515 | BUG(); | 526 | return PTR_ERR(clk_ce); |
516 | } | 527 | } |
517 | 528 | ||
518 | ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); | 529 | ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); |
519 | ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); | 530 | if (ret) |
531 | return ret; | ||
532 | |||
533 | ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); | ||
534 | if (ret) | ||
535 | return ret; | ||
520 | 536 | ||
521 | pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); | 537 | pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); |
538 | |||
539 | return 0; | ||
522 | } | 540 | } |
523 | 541 | ||
524 | CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); | 542 | CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); |
diff --git a/drivers/clocksource/clksrc-dbx500-prcmu.c b/drivers/clocksource/clksrc-dbx500-prcmu.c index dfad6eb99662..77a365f573d7 100644 --- a/drivers/clocksource/clksrc-dbx500-prcmu.c +++ b/drivers/clocksource/clksrc-dbx500-prcmu.c | |||
@@ -64,7 +64,7 @@ static u64 notrace dbx500_prcmu_sched_clock_read(void) | |||
64 | 64 | ||
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | static void __init clksrc_dbx500_prcmu_init(struct device_node *node) | 67 | static int __init clksrc_dbx500_prcmu_init(struct device_node *node) |
68 | { | 68 | { |
69 | clksrc_dbx500_timer_base = of_iomap(node, 0); | 69 | clksrc_dbx500_timer_base = of_iomap(node, 0); |
70 | 70 | ||
@@ -84,7 +84,7 @@ static void __init clksrc_dbx500_prcmu_init(struct device_node *node) | |||
84 | #ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK | 84 | #ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK |
85 | sched_clock_register(dbx500_prcmu_sched_clock_read, 32, RATE_32K); | 85 | sched_clock_register(dbx500_prcmu_sched_clock_read, 32, RATE_32K); |
86 | #endif | 86 | #endif |
87 | clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K); | 87 | return clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K); |
88 | } | 88 | } |
89 | CLOCKSOURCE_OF_DECLARE(dbx500_prcmu, "stericsson,db8500-prcmu-timer-4", | 89 | CLOCKSOURCE_OF_DECLARE(dbx500_prcmu, "stericsson,db8500-prcmu-timer-4", |
90 | clksrc_dbx500_prcmu_init); | 90 | clksrc_dbx500_prcmu_init); |
diff --git a/drivers/clocksource/clksrc-probe.c b/drivers/clocksource/clksrc-probe.c index 7cb6c923a836..bc62be97f0a8 100644 --- a/drivers/clocksource/clksrc-probe.c +++ b/drivers/clocksource/clksrc-probe.c | |||
@@ -28,15 +28,23 @@ void __init clocksource_probe(void) | |||
28 | { | 28 | { |
29 | struct device_node *np; | 29 | struct device_node *np; |
30 | const struct of_device_id *match; | 30 | const struct of_device_id *match; |
31 | of_init_fn_1 init_func; | 31 | of_init_fn_1_ret init_func_ret; |
32 | unsigned clocksources = 0; | 32 | unsigned clocksources = 0; |
33 | int ret; | ||
33 | 34 | ||
34 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { | 35 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { |
35 | if (!of_device_is_available(np)) | 36 | if (!of_device_is_available(np)) |
36 | continue; | 37 | continue; |
37 | 38 | ||
38 | init_func = match->data; | 39 | init_func_ret = match->data; |
39 | init_func(np); | 40 | |
41 | ret = init_func_ret(np); | ||
42 | if (ret) { | ||
43 | pr_err("Failed to initialize '%s': %d", | ||
44 | of_node_full_name(np), ret); | ||
45 | continue; | ||
46 | } | ||
47 | |||
40 | clocksources++; | 48 | clocksources++; |
41 | } | 49 | } |
42 | 50 | ||
diff --git a/drivers/clocksource/clksrc_st_lpc.c b/drivers/clocksource/clksrc_st_lpc.c index 65ec4674416d..03cc49217bb4 100644 --- a/drivers/clocksource/clksrc_st_lpc.c +++ b/drivers/clocksource/clksrc_st_lpc.c | |||
@@ -92,7 +92,7 @@ static int __init st_clksrc_setup_clk(struct device_node *np) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static void __init st_clksrc_of_register(struct device_node *np) | 95 | static int __init st_clksrc_of_register(struct device_node *np) |
96 | { | 96 | { |
97 | int ret; | 97 | int ret; |
98 | uint32_t mode; | 98 | uint32_t mode; |
@@ -100,32 +100,36 @@ static void __init st_clksrc_of_register(struct device_node *np) | |||
100 | ret = of_property_read_u32(np, "st,lpc-mode", &mode); | 100 | ret = of_property_read_u32(np, "st,lpc-mode", &mode); |
101 | if (ret) { | 101 | if (ret) { |
102 | pr_err("clksrc-st-lpc: An LPC mode must be provided\n"); | 102 | pr_err("clksrc-st-lpc: An LPC mode must be provided\n"); |
103 | return; | 103 | return ret; |
104 | } | 104 | } |
105 | 105 | ||
106 | /* LPC can either run as a Clocksource or in RTC or WDT mode */ | 106 | /* LPC can either run as a Clocksource or in RTC or WDT mode */ |
107 | if (mode != ST_LPC_MODE_CLKSRC) | 107 | if (mode != ST_LPC_MODE_CLKSRC) |
108 | return; | 108 | return 0; |
109 | 109 | ||
110 | ddata.base = of_iomap(np, 0); | 110 | ddata.base = of_iomap(np, 0); |
111 | if (!ddata.base) { | 111 | if (!ddata.base) { |
112 | pr_err("clksrc-st-lpc: Unable to map iomem\n"); | 112 | pr_err("clksrc-st-lpc: Unable to map iomem\n"); |
113 | return; | 113 | return -ENXIO; |
114 | } | 114 | } |
115 | 115 | ||
116 | if (st_clksrc_setup_clk(np)) { | 116 | ret = st_clksrc_setup_clk(np); |
117 | if (ret) { | ||
117 | iounmap(ddata.base); | 118 | iounmap(ddata.base); |
118 | return; | 119 | return ret; |
119 | } | 120 | } |
120 | 121 | ||
121 | if (st_clksrc_init()) { | 122 | ret = st_clksrc_init(); |
123 | if (ret) { | ||
122 | clk_disable_unprepare(ddata.clk); | 124 | clk_disable_unprepare(ddata.clk); |
123 | clk_put(ddata.clk); | 125 | clk_put(ddata.clk); |
124 | iounmap(ddata.base); | 126 | iounmap(ddata.base); |
125 | return; | 127 | return ret; |
126 | } | 128 | } |
127 | 129 | ||
128 | pr_info("clksrc-st-lpc: clocksource initialised - running @ %luHz\n", | 130 | pr_info("clksrc-st-lpc: clocksource initialised - running @ %luHz\n", |
129 | clk_get_rate(ddata.clk)); | 131 | clk_get_rate(ddata.clk)); |
132 | |||
133 | return ret; | ||
130 | } | 134 | } |
131 | CLOCKSOURCE_OF_DECLARE(ddata, "st,stih407-lpc", st_clksrc_of_register); | 135 | CLOCKSOURCE_OF_DECLARE(ddata, "st,stih407-lpc", st_clksrc_of_register); |
diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c index cdd86e3525bb..84aed78261e4 100644 --- a/drivers/clocksource/clps711x-timer.c +++ b/drivers/clocksource/clps711x-timer.c | |||
@@ -104,7 +104,7 @@ void __init clps711x_clksrc_init(void __iomem *tc1_base, void __iomem *tc2_base, | |||
104 | } | 104 | } |
105 | 105 | ||
106 | #ifdef CONFIG_CLKSRC_OF | 106 | #ifdef CONFIG_CLKSRC_OF |
107 | static void __init clps711x_timer_init(struct device_node *np) | 107 | static int __init clps711x_timer_init(struct device_node *np) |
108 | { | 108 | { |
109 | unsigned int irq = irq_of_parse_and_map(np, 0); | 109 | unsigned int irq = irq_of_parse_and_map(np, 0); |
110 | struct clk *clock = of_clk_get(np, 0); | 110 | struct clk *clock = of_clk_get(np, 0); |
@@ -112,13 +112,11 @@ static void __init clps711x_timer_init(struct device_node *np) | |||
112 | 112 | ||
113 | switch (of_alias_get_id(np, "timer")) { | 113 | switch (of_alias_get_id(np, "timer")) { |
114 | case CLPS711X_CLKSRC_CLOCKSOURCE: | 114 | case CLPS711X_CLKSRC_CLOCKSOURCE: |
115 | BUG_ON(_clps711x_clksrc_init(clock, base)); | 115 | return _clps711x_clksrc_init(clock, base); |
116 | break; | ||
117 | case CLPS711X_CLKSRC_CLOCKEVENT: | 116 | case CLPS711X_CLKSRC_CLOCKEVENT: |
118 | BUG_ON(_clps711x_clkevt_init(clock, base, irq)); | 117 | return _clps711x_clkevt_init(clock, base, irq); |
119 | break; | ||
120 | default: | 118 | default: |
121 | break; | 119 | return -EINVAL; |
122 | } | 120 | } |
123 | } | 121 | } |
124 | CLOCKSOURCE_OF_DECLARE(clps711x, "cirrus,clps711x-timer", clps711x_timer_init); | 122 | CLOCKSOURCE_OF_DECLARE(clps711x, "cirrus,clps711x-timer", clps711x_timer_init); |
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c index 860843cef572..aee6c0d39a7c 100644 --- a/drivers/clocksource/dw_apb_timer_of.c +++ b/drivers/clocksource/dw_apb_timer_of.c | |||
@@ -143,7 +143,7 @@ static struct delay_timer dw_apb_delay_timer = { | |||
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | static int num_called; | 145 | static int num_called; |
146 | static void __init dw_apb_timer_init(struct device_node *timer) | 146 | static int __init dw_apb_timer_init(struct device_node *timer) |
147 | { | 147 | { |
148 | switch (num_called) { | 148 | switch (num_called) { |
149 | case 0: | 149 | case 0: |
@@ -164,6 +164,8 @@ static void __init dw_apb_timer_init(struct device_node *timer) | |||
164 | } | 164 | } |
165 | 165 | ||
166 | num_called++; | 166 | num_called++; |
167 | |||
168 | return 0; | ||
167 | } | 169 | } |
168 | CLOCKSOURCE_OF_DECLARE(pc3x2_timer, "picochip,pc3x2-timer", dw_apb_timer_init); | 170 | CLOCKSOURCE_OF_DECLARE(pc3x2_timer, "picochip,pc3x2-timer", dw_apb_timer_init); |
169 | CLOCKSOURCE_OF_DECLARE(apb_timer_osc, "snps,dw-apb-timer-osc", dw_apb_timer_init); | 171 | CLOCKSOURCE_OF_DECLARE(apb_timer_osc, "snps,dw-apb-timer-osc", dw_apb_timer_init); |
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index be09bc0b5e26..0d18dd4b3bd2 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c | |||
@@ -232,7 +232,7 @@ static cycles_t exynos4_read_current_timer(void) | |||
232 | return exynos4_read_count_32(); | 232 | return exynos4_read_count_32(); |
233 | } | 233 | } |
234 | 234 | ||
235 | static void __init exynos4_clocksource_init(void) | 235 | static int __init exynos4_clocksource_init(void) |
236 | { | 236 | { |
237 | exynos4_mct_frc_start(); | 237 | exynos4_mct_frc_start(); |
238 | 238 | ||
@@ -244,6 +244,8 @@ static void __init exynos4_clocksource_init(void) | |||
244 | panic("%s: can't register clocksource\n", mct_frc.name); | 244 | panic("%s: can't register clocksource\n", mct_frc.name); |
245 | 245 | ||
246 | sched_clock_register(exynos4_read_sched_clock, 32, clk_rate); | 246 | sched_clock_register(exynos4_read_sched_clock, 32, clk_rate); |
247 | |||
248 | return 0; | ||
247 | } | 249 | } |
248 | 250 | ||
249 | static void exynos4_mct_comp0_stop(void) | 251 | static void exynos4_mct_comp0_stop(void) |
@@ -335,12 +337,14 @@ static struct irqaction mct_comp_event_irq = { | |||
335 | .dev_id = &mct_comp_device, | 337 | .dev_id = &mct_comp_device, |
336 | }; | 338 | }; |
337 | 339 | ||
338 | static void exynos4_clockevent_init(void) | 340 | static int exynos4_clockevent_init(void) |
339 | { | 341 | { |
340 | mct_comp_device.cpumask = cpumask_of(0); | 342 | mct_comp_device.cpumask = cpumask_of(0); |
341 | clockevents_config_and_register(&mct_comp_device, clk_rate, | 343 | clockevents_config_and_register(&mct_comp_device, clk_rate, |
342 | 0xf, 0xffffffff); | 344 | 0xf, 0xffffffff); |
343 | setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq); | 345 | setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq); |
346 | |||
347 | return 0; | ||
344 | } | 348 | } |
345 | 349 | ||
346 | static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); | 350 | static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); |
@@ -516,7 +520,7 @@ static struct notifier_block exynos4_mct_cpu_nb = { | |||
516 | .notifier_call = exynos4_mct_cpu_notify, | 520 | .notifier_call = exynos4_mct_cpu_notify, |
517 | }; | 521 | }; |
518 | 522 | ||
519 | static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base) | 523 | static int __init exynos4_timer_resources(struct device_node *np, void __iomem *base) |
520 | { | 524 | { |
521 | int err, cpu; | 525 | int err, cpu; |
522 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); | 526 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); |
@@ -572,15 +576,17 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem | |||
572 | 576 | ||
573 | /* Immediately configure the timer on the boot CPU */ | 577 | /* Immediately configure the timer on the boot CPU */ |
574 | exynos4_local_timer_setup(mevt); | 578 | exynos4_local_timer_setup(mevt); |
575 | return; | 579 | return 0; |
576 | 580 | ||
577 | out_irq: | 581 | out_irq: |
578 | free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick); | 582 | free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick); |
583 | return err; | ||
579 | } | 584 | } |
580 | 585 | ||
581 | static void __init mct_init_dt(struct device_node *np, unsigned int int_type) | 586 | static int __init mct_init_dt(struct device_node *np, unsigned int int_type) |
582 | { | 587 | { |
583 | u32 nr_irqs, i; | 588 | u32 nr_irqs, i; |
589 | int ret; | ||
584 | 590 | ||
585 | mct_int_type = int_type; | 591 | mct_int_type = int_type; |
586 | 592 | ||
@@ -600,18 +606,24 @@ static void __init mct_init_dt(struct device_node *np, unsigned int int_type) | |||
600 | for (i = MCT_L0_IRQ; i < nr_irqs; i++) | 606 | for (i = MCT_L0_IRQ; i < nr_irqs; i++) |
601 | mct_irqs[i] = irq_of_parse_and_map(np, i); | 607 | mct_irqs[i] = irq_of_parse_and_map(np, i); |
602 | 608 | ||
603 | exynos4_timer_resources(np, of_iomap(np, 0)); | 609 | ret = exynos4_timer_resources(np, of_iomap(np, 0)); |
604 | exynos4_clocksource_init(); | 610 | if (ret) |
605 | exynos4_clockevent_init(); | 611 | return ret; |
612 | |||
613 | ret = exynos4_clocksource_init(); | ||
614 | if (ret) | ||
615 | return ret; | ||
616 | |||
617 | return exynos4_clockevent_init(); | ||
606 | } | 618 | } |
607 | 619 | ||
608 | 620 | ||
609 | static void __init mct_init_spi(struct device_node *np) | 621 | static int __init mct_init_spi(struct device_node *np) |
610 | { | 622 | { |
611 | return mct_init_dt(np, MCT_INT_SPI); | 623 | return mct_init_dt(np, MCT_INT_SPI); |
612 | } | 624 | } |
613 | 625 | ||
614 | static void __init mct_init_ppi(struct device_node *np) | 626 | static int __init mct_init_ppi(struct device_node *np) |
615 | { | 627 | { |
616 | return mct_init_dt(np, MCT_INT_PPI); | 628 | return mct_init_dt(np, MCT_INT_PPI); |
617 | } | 629 | } |
diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c index 517e1c7624d4..738515b89073 100644 --- a/drivers/clocksource/fsl_ftm_timer.c +++ b/drivers/clocksource/fsl_ftm_timer.c | |||
@@ -316,15 +316,16 @@ static int __init ftm_calc_closest_round_cyc(unsigned long freq) | |||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | 318 | ||
319 | static void __init ftm_timer_init(struct device_node *np) | 319 | static int __init ftm_timer_init(struct device_node *np) |
320 | { | 320 | { |
321 | unsigned long freq; | 321 | unsigned long freq; |
322 | int irq; | 322 | int ret, irq; |
323 | 323 | ||
324 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 324 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
325 | if (!priv) | 325 | if (!priv) |
326 | return; | 326 | return -ENOMEM; |
327 | 327 | ||
328 | ret = -ENXIO; | ||
328 | priv->clkevt_base = of_iomap(np, 0); | 329 | priv->clkevt_base = of_iomap(np, 0); |
329 | if (!priv->clkevt_base) { | 330 | if (!priv->clkevt_base) { |
330 | pr_err("ftm: unable to map event timer registers\n"); | 331 | pr_err("ftm: unable to map event timer registers\n"); |
@@ -337,6 +338,7 @@ static void __init ftm_timer_init(struct device_node *np) | |||
337 | goto err; | 338 | goto err; |
338 | } | 339 | } |
339 | 340 | ||
341 | ret = -EINVAL; | ||
340 | irq = irq_of_parse_and_map(np, 0); | 342 | irq = irq_of_parse_and_map(np, 0); |
341 | if (irq <= 0) { | 343 | if (irq <= 0) { |
342 | pr_err("ftm: unable to get IRQ from DT, %d\n", irq); | 344 | pr_err("ftm: unable to get IRQ from DT, %d\n", irq); |
@@ -349,18 +351,22 @@ static void __init ftm_timer_init(struct device_node *np) | |||
349 | if (!freq) | 351 | if (!freq) |
350 | goto err; | 352 | goto err; |
351 | 353 | ||
352 | if (ftm_calc_closest_round_cyc(freq)) | 354 | ret = ftm_calc_closest_round_cyc(freq); |
355 | if (ret) | ||
353 | goto err; | 356 | goto err; |
354 | 357 | ||
355 | if (ftm_clocksource_init(freq)) | 358 | ret = ftm_clocksource_init(freq); |
359 | if (ret) | ||
356 | goto err; | 360 | goto err; |
357 | 361 | ||
358 | if (ftm_clockevent_init(freq, irq)) | 362 | ret = ftm_clockevent_init(freq, irq); |
363 | if (ret) | ||
359 | goto err; | 364 | goto err; |
360 | 365 | ||
361 | return; | 366 | return 0; |
362 | 367 | ||
363 | err: | 368 | err: |
364 | kfree(priv); | 369 | kfree(priv); |
370 | return ret; | ||
365 | } | 371 | } |
366 | CLOCKSOURCE_OF_DECLARE(flextimer, "fsl,ftm-timer", ftm_timer_init); | 372 | CLOCKSOURCE_OF_DECLARE(flextimer, "fsl,ftm-timer", ftm_timer_init); |
diff --git a/drivers/clocksource/h8300_timer16.c b/drivers/clocksource/h8300_timer16.c index 75c44079b345..07d9d5be9054 100644 --- a/drivers/clocksource/h8300_timer16.c +++ b/drivers/clocksource/h8300_timer16.c | |||
@@ -126,7 +126,7 @@ static struct timer16_priv timer16_priv = { | |||
126 | #define REG_CH 0 | 126 | #define REG_CH 0 |
127 | #define REG_COMM 1 | 127 | #define REG_COMM 1 |
128 | 128 | ||
129 | static void __init h8300_16timer_init(struct device_node *node) | 129 | static int __init h8300_16timer_init(struct device_node *node) |
130 | { | 130 | { |
131 | void __iomem *base[2]; | 131 | void __iomem *base[2]; |
132 | int ret, irq; | 132 | int ret, irq; |
@@ -136,9 +136,10 @@ static void __init h8300_16timer_init(struct device_node *node) | |||
136 | clk = of_clk_get(node, 0); | 136 | clk = of_clk_get(node, 0); |
137 | if (IS_ERR(clk)) { | 137 | if (IS_ERR(clk)) { |
138 | pr_err("failed to get clock for clocksource\n"); | 138 | pr_err("failed to get clock for clocksource\n"); |
139 | return; | 139 | return PTR_ERR(clk); |
140 | } | 140 | } |
141 | 141 | ||
142 | ret = -ENXIO; | ||
142 | base[REG_CH] = of_iomap(node, 0); | 143 | base[REG_CH] = of_iomap(node, 0); |
143 | if (!base[REG_CH]) { | 144 | if (!base[REG_CH]) { |
144 | pr_err("failed to map registers for clocksource\n"); | 145 | pr_err("failed to map registers for clocksource\n"); |
@@ -151,6 +152,7 @@ static void __init h8300_16timer_init(struct device_node *node) | |||
151 | goto unmap_ch; | 152 | goto unmap_ch; |
152 | } | 153 | } |
153 | 154 | ||
155 | ret = -EINVAL; | ||
154 | irq = irq_of_parse_and_map(node, 0); | 156 | irq = irq_of_parse_and_map(node, 0); |
155 | if (!irq) { | 157 | if (!irq) { |
156 | pr_err("failed to get irq for clockevent\n"); | 158 | pr_err("failed to get irq for clockevent\n"); |
@@ -174,7 +176,7 @@ static void __init h8300_16timer_init(struct device_node *node) | |||
174 | 176 | ||
175 | clocksource_register_hz(&timer16_priv.cs, | 177 | clocksource_register_hz(&timer16_priv.cs, |
176 | clk_get_rate(clk) / 8); | 178 | clk_get_rate(clk) / 8); |
177 | return; | 179 | return 0; |
178 | 180 | ||
179 | unmap_comm: | 181 | unmap_comm: |
180 | iounmap(base[REG_COMM]); | 182 | iounmap(base[REG_COMM]); |
@@ -182,6 +184,8 @@ unmap_ch: | |||
182 | iounmap(base[REG_CH]); | 184 | iounmap(base[REG_CH]); |
183 | free_clk: | 185 | free_clk: |
184 | clk_put(clk); | 186 | clk_put(clk); |
187 | return ret; | ||
185 | } | 188 | } |
186 | 189 | ||
187 | CLOCKSOURCE_OF_DECLARE(h8300_16bit, "renesas,16bit-timer", h8300_16timer_init); | 190 | CLOCKSOURCE_OF_DECLARE(h8300_16bit, "renesas,16bit-timer", |
191 | h8300_16timer_init); | ||
diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c index c151941e1956..546bb180f5a4 100644 --- a/drivers/clocksource/h8300_timer8.c +++ b/drivers/clocksource/h8300_timer8.c | |||
@@ -164,24 +164,26 @@ static struct timer8_priv timer8_priv = { | |||
164 | }, | 164 | }, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static void __init h8300_8timer_init(struct device_node *node) | 167 | static int __init h8300_8timer_init(struct device_node *node) |
168 | { | 168 | { |
169 | void __iomem *base; | 169 | void __iomem *base; |
170 | int irq; | 170 | int irq, ret; |
171 | struct clk *clk; | 171 | struct clk *clk; |
172 | 172 | ||
173 | clk = of_clk_get(node, 0); | 173 | clk = of_clk_get(node, 0); |
174 | if (IS_ERR(clk)) { | 174 | if (IS_ERR(clk)) { |
175 | pr_err("failed to get clock for clockevent\n"); | 175 | pr_err("failed to get clock for clockevent\n"); |
176 | return; | 176 | return PTR_ERR(clk); |
177 | } | 177 | } |
178 | 178 | ||
179 | ret = ENXIO; | ||
179 | base = of_iomap(node, 0); | 180 | base = of_iomap(node, 0); |
180 | if (!base) { | 181 | if (!base) { |
181 | pr_err("failed to map registers for clockevent\n"); | 182 | pr_err("failed to map registers for clockevent\n"); |
182 | goto free_clk; | 183 | goto free_clk; |
183 | } | 184 | } |
184 | 185 | ||
186 | ret = -EINVAL; | ||
185 | irq = irq_of_parse_and_map(node, 0); | 187 | irq = irq_of_parse_and_map(node, 0); |
186 | if (!irq) { | 188 | if (!irq) { |
187 | pr_err("failed to get irq for clockevent\n"); | 189 | pr_err("failed to get irq for clockevent\n"); |
@@ -205,11 +207,12 @@ static void __init h8300_8timer_init(struct device_node *node) | |||
205 | clockevents_config_and_register(&timer8_priv.ced, | 207 | clockevents_config_and_register(&timer8_priv.ced, |
206 | timer8_priv.rate, 1, 0x0000ffff); | 208 | timer8_priv.rate, 1, 0x0000ffff); |
207 | 209 | ||
208 | return; | 210 | return 0; |
209 | unmap_reg: | 211 | unmap_reg: |
210 | iounmap(base); | 212 | iounmap(base); |
211 | free_clk: | 213 | free_clk: |
212 | clk_put(clk); | 214 | clk_put(clk); |
215 | return ret; | ||
213 | } | 216 | } |
214 | 217 | ||
215 | CLOCKSOURCE_OF_DECLARE(h8300_8bit, "renesas,8bit-timer", h8300_8timer_init); | 218 | CLOCKSOURCE_OF_DECLARE(h8300_8bit, "renesas,8bit-timer", h8300_8timer_init); |
diff --git a/drivers/clocksource/h8300_tpu.c b/drivers/clocksource/h8300_tpu.c index d4c1a287c262..7bdf1991c847 100644 --- a/drivers/clocksource/h8300_tpu.c +++ b/drivers/clocksource/h8300_tpu.c | |||
@@ -119,15 +119,16 @@ static struct tpu_priv tpu_priv = { | |||
119 | #define CH_L 0 | 119 | #define CH_L 0 |
120 | #define CH_H 1 | 120 | #define CH_H 1 |
121 | 121 | ||
122 | static void __init h8300_tpu_init(struct device_node *node) | 122 | static int __init h8300_tpu_init(struct device_node *node) |
123 | { | 123 | { |
124 | void __iomem *base[2]; | 124 | void __iomem *base[2]; |
125 | struct clk *clk; | 125 | struct clk *clk; |
126 | int ret = -ENXIO; | ||
126 | 127 | ||
127 | clk = of_clk_get(node, 0); | 128 | clk = of_clk_get(node, 0); |
128 | if (IS_ERR(clk)) { | 129 | if (IS_ERR(clk)) { |
129 | pr_err("failed to get clock for clocksource\n"); | 130 | pr_err("failed to get clock for clocksource\n"); |
130 | return; | 131 | return PTR_ERR(clk); |
131 | } | 132 | } |
132 | 133 | ||
133 | base[CH_L] = of_iomap(node, CH_L); | 134 | base[CH_L] = of_iomap(node, CH_L); |
@@ -144,14 +145,13 @@ static void __init h8300_tpu_init(struct device_node *node) | |||
144 | tpu_priv.mapbase1 = base[CH_L]; | 145 | tpu_priv.mapbase1 = base[CH_L]; |
145 | tpu_priv.mapbase2 = base[CH_H]; | 146 | tpu_priv.mapbase2 = base[CH_H]; |
146 | 147 | ||
147 | clocksource_register_hz(&tpu_priv.cs, clk_get_rate(clk) / 64); | 148 | return clocksource_register_hz(&tpu_priv.cs, clk_get_rate(clk) / 64); |
148 | |||
149 | return; | ||
150 | 149 | ||
151 | unmap_L: | 150 | unmap_L: |
152 | iounmap(base[CH_H]); | 151 | iounmap(base[CH_H]); |
153 | free_clk: | 152 | free_clk: |
154 | clk_put(clk); | 153 | clk_put(clk); |
154 | return ret; | ||
155 | } | 155 | } |
156 | 156 | ||
157 | CLOCKSOURCE_OF_DECLARE(h8300_tpu, "renesas,tpu", h8300_tpu_init); | 157 | CLOCKSOURCE_OF_DECLARE(h8300_tpu, "renesas,tpu", h8300_tpu_init); |
diff --git a/drivers/clocksource/meson6_timer.c b/drivers/clocksource/meson6_timer.c index 1fa22c4d2d49..52af591a9fc7 100644 --- a/drivers/clocksource/meson6_timer.c +++ b/drivers/clocksource/meson6_timer.c | |||
@@ -126,18 +126,22 @@ static struct irqaction meson6_timer_irq = { | |||
126 | .dev_id = &meson6_clockevent, | 126 | .dev_id = &meson6_clockevent, |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static void __init meson6_timer_init(struct device_node *node) | 129 | static int __init meson6_timer_init(struct device_node *node) |
130 | { | 130 | { |
131 | u32 val; | 131 | u32 val; |
132 | int ret, irq; | 132 | int ret, irq; |
133 | 133 | ||
134 | timer_base = of_io_request_and_map(node, 0, "meson6-timer"); | 134 | timer_base = of_io_request_and_map(node, 0, "meson6-timer"); |
135 | if (IS_ERR(timer_base)) | 135 | if (IS_ERR(timer_base)) { |
136 | panic("Can't map registers"); | 136 | pr_err("Can't map registers"); |
137 | return -ENXIO; | ||
138 | } | ||
137 | 139 | ||
138 | irq = irq_of_parse_and_map(node, 0); | 140 | irq = irq_of_parse_and_map(node, 0); |
139 | if (irq <= 0) | 141 | if (irq <= 0) { |
140 | panic("Can't parse IRQ"); | 142 | pr_err("Can't parse IRQ"); |
143 | return -EINVAL; | ||
144 | } | ||
141 | 145 | ||
142 | /* Set 1us for timer E */ | 146 | /* Set 1us for timer E */ |
143 | val = readl(timer_base + TIMER_ISA_MUX); | 147 | val = readl(timer_base + TIMER_ISA_MUX); |
@@ -158,14 +162,17 @@ static void __init meson6_timer_init(struct device_node *node) | |||
158 | meson6_clkevt_time_stop(CED_ID); | 162 | meson6_clkevt_time_stop(CED_ID); |
159 | 163 | ||
160 | ret = setup_irq(irq, &meson6_timer_irq); | 164 | ret = setup_irq(irq, &meson6_timer_irq); |
161 | if (ret) | 165 | if (ret) { |
162 | pr_warn("failed to setup irq %d\n", irq); | 166 | pr_warn("failed to setup irq %d\n", irq); |
167 | return ret; | ||
168 | } | ||
163 | 169 | ||
164 | meson6_clockevent.cpumask = cpu_possible_mask; | 170 | meson6_clockevent.cpumask = cpu_possible_mask; |
165 | meson6_clockevent.irq = irq; | 171 | meson6_clockevent.irq = irq; |
166 | 172 | ||
167 | clockevents_config_and_register(&meson6_clockevent, USEC_PER_SEC, | 173 | clockevents_config_and_register(&meson6_clockevent, USEC_PER_SEC, |
168 | 1, 0xfffe); | 174 | 1, 0xfffe); |
175 | return 0; | ||
169 | } | 176 | } |
170 | CLOCKSOURCE_OF_DECLARE(meson6, "amlogic,meson6-timer", | 177 | CLOCKSOURCE_OF_DECLARE(meson6, "amlogic,meson6-timer", |
171 | meson6_timer_init); | 178 | meson6_timer_init); |
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 89d3e4d7900c..1572c7a778ab 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c | |||
@@ -146,7 +146,7 @@ static struct clocksource gic_clocksource = { | |||
146 | .archdata = { .vdso_clock_mode = VDSO_CLOCK_GIC }, | 146 | .archdata = { .vdso_clock_mode = VDSO_CLOCK_GIC }, |
147 | }; | 147 | }; |
148 | 148 | ||
149 | static void __init __gic_clocksource_init(void) | 149 | static int __init __gic_clocksource_init(void) |
150 | { | 150 | { |
151 | int ret; | 151 | int ret; |
152 | 152 | ||
@@ -159,6 +159,8 @@ static void __init __gic_clocksource_init(void) | |||
159 | ret = clocksource_register_hz(&gic_clocksource, gic_frequency); | 159 | ret = clocksource_register_hz(&gic_clocksource, gic_frequency); |
160 | if (ret < 0) | 160 | if (ret < 0) |
161 | pr_warn("GIC: Unable to register clocksource\n"); | 161 | pr_warn("GIC: Unable to register clocksource\n"); |
162 | |||
163 | return ret; | ||
162 | } | 164 | } |
163 | 165 | ||
164 | void __init gic_clocksource_init(unsigned int frequency) | 166 | void __init gic_clocksource_init(unsigned int frequency) |
@@ -179,31 +181,35 @@ static void __init gic_clocksource_of_init(struct device_node *node) | |||
179 | struct clk *clk; | 181 | struct clk *clk; |
180 | int ret; | 182 | int ret; |
181 | 183 | ||
182 | if (WARN_ON(!gic_present || !node->parent || | 184 | if (!gic_present || !node->parent || |
183 | !of_device_is_compatible(node->parent, "mti,gic"))) | 185 | !of_device_is_compatible(node->parent, "mti,gic")) { |
184 | return; | 186 | pr_warn("No DT definition for the mips gic driver"); |
187 | return -ENXIO; | ||
188 | } | ||
185 | 189 | ||
186 | clk = of_clk_get(node, 0); | 190 | clk = of_clk_get(node, 0); |
187 | if (!IS_ERR(clk)) { | 191 | if (!IS_ERR(clk)) { |
188 | if (clk_prepare_enable(clk) < 0) { | 192 | if (clk_prepare_enable(clk) < 0) { |
189 | pr_err("GIC failed to enable clock\n"); | 193 | pr_err("GIC failed to enable clock\n"); |
190 | clk_put(clk); | 194 | clk_put(clk); |
191 | return; | 195 | return PTR_ERR(clk); |
192 | } | 196 | } |
193 | 197 | ||
194 | gic_frequency = clk_get_rate(clk); | 198 | gic_frequency = clk_get_rate(clk); |
195 | } else if (of_property_read_u32(node, "clock-frequency", | 199 | } else if (of_property_read_u32(node, "clock-frequency", |
196 | &gic_frequency)) { | 200 | &gic_frequency)) { |
197 | pr_err("GIC frequency not specified.\n"); | 201 | pr_err("GIC frequency not specified.\n"); |
198 | return; | 202 | return -EINVAL;; |
199 | } | 203 | } |
200 | gic_timer_irq = irq_of_parse_and_map(node, 0); | 204 | gic_timer_irq = irq_of_parse_and_map(node, 0); |
201 | if (!gic_timer_irq) { | 205 | if (!gic_timer_irq) { |
202 | pr_err("GIC timer IRQ not specified.\n"); | 206 | pr_err("GIC timer IRQ not specified.\n"); |
203 | return; | 207 | return -EINVAL;; |
204 | } | 208 | } |
205 | 209 | ||
206 | __gic_clocksource_init(); | 210 | ret = __gic_clocksource_init(); |
211 | if (ret) | ||
212 | return ret; | ||
207 | 213 | ||
208 | ret = gic_clockevent_init(); | 214 | ret = gic_clockevent_init(); |
209 | if (!ret && !IS_ERR(clk)) { | 215 | if (!ret && !IS_ERR(clk)) { |
@@ -213,6 +219,8 @@ static void __init gic_clocksource_of_init(struct device_node *node) | |||
213 | 219 | ||
214 | /* And finally start the counter */ | 220 | /* And finally start the counter */ |
215 | gic_start_count(); | 221 | gic_start_count(); |
222 | |||
223 | return 0; | ||
216 | } | 224 | } |
217 | CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", | 225 | CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", |
218 | gic_clocksource_of_init); | 226 | gic_clocksource_of_init); |
diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c index 19857af651c1..841454417acd 100644 --- a/drivers/clocksource/moxart_timer.c +++ b/drivers/clocksource/moxart_timer.c | |||
@@ -119,34 +119,45 @@ static struct irqaction moxart_timer_irq = { | |||
119 | .dev_id = &moxart_clockevent, | 119 | .dev_id = &moxart_clockevent, |
120 | }; | 120 | }; |
121 | 121 | ||
122 | static void __init moxart_timer_init(struct device_node *node) | 122 | static int __init moxart_timer_init(struct device_node *node) |
123 | { | 123 | { |
124 | int ret, irq; | 124 | int ret, irq; |
125 | unsigned long pclk; | 125 | unsigned long pclk; |
126 | struct clk *clk; | 126 | struct clk *clk; |
127 | 127 | ||
128 | base = of_iomap(node, 0); | 128 | base = of_iomap(node, 0); |
129 | if (!base) | 129 | if (!base) { |
130 | panic("%s: of_iomap failed\n", node->full_name); | 130 | pr_err("%s: of_iomap failed\n", node->full_name); |
131 | return -ENXIO; | ||
132 | } | ||
131 | 133 | ||
132 | irq = irq_of_parse_and_map(node, 0); | 134 | irq = irq_of_parse_and_map(node, 0); |
133 | if (irq <= 0) | 135 | if (irq <= 0) { |
134 | panic("%s: irq_of_parse_and_map failed\n", node->full_name); | 136 | pr_err("%s: irq_of_parse_and_map failed\n", node->full_name); |
137 | return -EINVAL; | ||
138 | } | ||
135 | 139 | ||
136 | ret = setup_irq(irq, &moxart_timer_irq); | 140 | ret = setup_irq(irq, &moxart_timer_irq); |
137 | if (ret) | 141 | if (ret) { |
138 | panic("%s: setup_irq failed\n", node->full_name); | 142 | pr_err("%s: setup_irq failed\n", node->full_name); |
143 | return ret; | ||
144 | } | ||
139 | 145 | ||
140 | clk = of_clk_get(node, 0); | 146 | clk = of_clk_get(node, 0); |
141 | if (IS_ERR(clk)) | 147 | if (IS_ERR(clk)) { |
142 | panic("%s: of_clk_get failed\n", node->full_name); | 148 | pr_err("%s: of_clk_get failed\n", node->full_name); |
149 | return PTR_ERR(clk); | ||
150 | } | ||
143 | 151 | ||
144 | pclk = clk_get_rate(clk); | 152 | pclk = clk_get_rate(clk); |
145 | 153 | ||
146 | if (clocksource_mmio_init(base + TIMER2_BASE + REG_COUNT, | 154 | ret = clocksource_mmio_init(base + TIMER2_BASE + REG_COUNT, |
147 | "moxart_timer", pclk, 200, 32, | 155 | "moxart_timer", pclk, 200, 32, |
148 | clocksource_mmio_readl_down)) | 156 | clocksource_mmio_readl_down); |
149 | panic("%s: clocksource_mmio_init failed\n", node->full_name); | 157 | if (ret) { |
158 | pr_err("%s: clocksource_mmio_init failed\n", node->full_name); | ||
159 | return ret; | ||
160 | } | ||
150 | 161 | ||
151 | clock_count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); | 162 | clock_count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); |
152 | 163 | ||
@@ -164,5 +175,7 @@ static void __init moxart_timer_init(struct device_node *node) | |||
164 | */ | 175 | */ |
165 | clockevents_config_and_register(&moxart_clockevent, pclk, | 176 | clockevents_config_and_register(&moxart_clockevent, pclk, |
166 | 0x4, 0xfffffffe); | 177 | 0x4, 0xfffffffe); |
178 | |||
179 | return 0; | ||
167 | } | 180 | } |
168 | CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); | 181 | CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); |
diff --git a/drivers/clocksource/mps2-timer.c b/drivers/clocksource/mps2-timer.c index 3d33a5e23dee..3e4431ed9aa9 100644 --- a/drivers/clocksource/mps2-timer.c +++ b/drivers/clocksource/mps2-timer.c | |||
@@ -250,7 +250,7 @@ out: | |||
250 | return ret; | 250 | return ret; |
251 | } | 251 | } |
252 | 252 | ||
253 | static void __init mps2_timer_init(struct device_node *np) | 253 | static int __init mps2_timer_init(struct device_node *np) |
254 | { | 254 | { |
255 | static int has_clocksource, has_clockevent; | 255 | static int has_clocksource, has_clockevent; |
256 | int ret; | 256 | int ret; |
@@ -259,7 +259,7 @@ static void __init mps2_timer_init(struct device_node *np) | |||
259 | ret = mps2_clocksource_init(np); | 259 | ret = mps2_clocksource_init(np); |
260 | if (!ret) { | 260 | if (!ret) { |
261 | has_clocksource = 1; | 261 | has_clocksource = 1; |
262 | return; | 262 | return 0; |
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
@@ -267,9 +267,11 @@ static void __init mps2_timer_init(struct device_node *np) | |||
267 | ret = mps2_clockevent_init(np); | 267 | ret = mps2_clockevent_init(np); |
268 | if (!ret) { | 268 | if (!ret) { |
269 | has_clockevent = 1; | 269 | has_clockevent = 1; |
270 | return; | 270 | return 0; |
271 | } | 271 | } |
272 | } | 272 | } |
273 | |||
274 | return 0; | ||
273 | } | 275 | } |
274 | 276 | ||
275 | CLOCKSOURCE_OF_DECLARE(mps2_timer, "arm,mps2-timer", mps2_timer_init); | 277 | CLOCKSOURCE_OF_DECLARE(mps2_timer, "arm,mps2-timer", mps2_timer_init); |
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c index 7e583f8ea5f4..90659493c59c 100644 --- a/drivers/clocksource/mtk_timer.c +++ b/drivers/clocksource/mtk_timer.c | |||
@@ -181,7 +181,7 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer) | |||
181 | evt->gpt_base + GPT_IRQ_EN_REG); | 181 | evt->gpt_base + GPT_IRQ_EN_REG); |
182 | } | 182 | } |
183 | 183 | ||
184 | static void __init mtk_timer_init(struct device_node *node) | 184 | static int __init mtk_timer_init(struct device_node *node) |
185 | { | 185 | { |
186 | struct mtk_clock_event_device *evt; | 186 | struct mtk_clock_event_device *evt; |
187 | struct resource res; | 187 | struct resource res; |
@@ -190,7 +190,7 @@ static void __init mtk_timer_init(struct device_node *node) | |||
190 | 190 | ||
191 | evt = kzalloc(sizeof(*evt), GFP_KERNEL); | 191 | evt = kzalloc(sizeof(*evt), GFP_KERNEL); |
192 | if (!evt) | 192 | if (!evt) |
193 | return; | 193 | return -ENOMEM; |
194 | 194 | ||
195 | evt->dev.name = "mtk_tick"; | 195 | evt->dev.name = "mtk_tick"; |
196 | evt->dev.rating = 300; | 196 | evt->dev.rating = 300; |
@@ -248,7 +248,7 @@ static void __init mtk_timer_init(struct device_node *node) | |||
248 | 248 | ||
249 | mtk_timer_enable_irq(evt, GPT_CLK_EVT); | 249 | mtk_timer_enable_irq(evt, GPT_CLK_EVT); |
250 | 250 | ||
251 | return; | 251 | return 0; |
252 | 252 | ||
253 | err_clk_disable: | 253 | err_clk_disable: |
254 | clk_disable_unprepare(clk); | 254 | clk_disable_unprepare(clk); |
@@ -262,5 +262,7 @@ err_mem: | |||
262 | release_mem_region(res.start, resource_size(&res)); | 262 | release_mem_region(res.start, resource_size(&res)); |
263 | err_kzalloc: | 263 | err_kzalloc: |
264 | kfree(evt); | 264 | kfree(evt); |
265 | |||
266 | return -EINVAL; | ||
265 | } | 267 | } |
266 | CLOCKSOURCE_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init); | 268 | CLOCKSOURCE_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init); |
diff --git a/drivers/clocksource/mxs_timer.c b/drivers/clocksource/mxs_timer.c index f5ce2961c0d6..0ba0a913b41d 100644 --- a/drivers/clocksource/mxs_timer.c +++ b/drivers/clocksource/mxs_timer.c | |||
@@ -31,8 +31,6 @@ | |||
31 | #include <linux/stmp_device.h> | 31 | #include <linux/stmp_device.h> |
32 | #include <linux/sched_clock.h> | 32 | #include <linux/sched_clock.h> |
33 | 33 | ||
34 | #include <asm/mach/time.h> | ||
35 | |||
36 | /* | 34 | /* |
37 | * There are 2 versions of the timrot on Freescale MXS-based SoCs. | 35 | * There are 2 versions of the timrot on Freescale MXS-based SoCs. |
38 | * The v1 on MX23 only gets 16 bits counter, while v2 on MX28 | 36 | * The v1 on MX23 only gets 16 bits counter, while v2 on MX28 |
@@ -226,10 +224,10 @@ static int __init mxs_clocksource_init(struct clk *timer_clk) | |||
226 | return 0; | 224 | return 0; |
227 | } | 225 | } |
228 | 226 | ||
229 | static void __init mxs_timer_init(struct device_node *np) | 227 | static int __init mxs_timer_init(struct device_node *np) |
230 | { | 228 | { |
231 | struct clk *timer_clk; | 229 | struct clk *timer_clk; |
232 | int irq; | 230 | int irq, ret; |
233 | 231 | ||
234 | mxs_timrot_base = of_iomap(np, 0); | 232 | mxs_timrot_base = of_iomap(np, 0); |
235 | WARN_ON(!mxs_timrot_base); | 233 | WARN_ON(!mxs_timrot_base); |
@@ -237,10 +235,12 @@ static void __init mxs_timer_init(struct device_node *np) | |||
237 | timer_clk = of_clk_get(np, 0); | 235 | timer_clk = of_clk_get(np, 0); |
238 | if (IS_ERR(timer_clk)) { | 236 | if (IS_ERR(timer_clk)) { |
239 | pr_err("%s: failed to get clk\n", __func__); | 237 | pr_err("%s: failed to get clk\n", __func__); |
240 | return; | 238 | return PTR_ERR(timer_clk); |
241 | } | 239 | } |
242 | 240 | ||
243 | clk_prepare_enable(timer_clk); | 241 | ret = clk_prepare_enable(timer_clk); |
242 | if (ret) | ||
243 | return ret; | ||
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Initialize timers to a known state | 246 | * Initialize timers to a known state |
@@ -278,11 +278,19 @@ static void __init mxs_timer_init(struct device_node *np) | |||
278 | mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1)); | 278 | mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1)); |
279 | 279 | ||
280 | /* init and register the timer to the framework */ | 280 | /* init and register the timer to the framework */ |
281 | mxs_clocksource_init(timer_clk); | 281 | ret = mxs_clocksource_init(timer_clk); |
282 | mxs_clockevent_init(timer_clk); | 282 | if (ret) |
283 | return ret; | ||
284 | |||
285 | ret = mxs_clockevent_init(timer_clk); | ||
286 | if (ret) | ||
287 | return ret; | ||
283 | 288 | ||
284 | /* Make irqs happen */ | 289 | /* Make irqs happen */ |
285 | irq = irq_of_parse_and_map(np, 0); | 290 | irq = irq_of_parse_and_map(np, 0); |
286 | setup_irq(irq, &mxs_timer_irq); | 291 | if (irq <= 0) |
292 | return -EINVAL; | ||
293 | |||
294 | return setup_irq(irq, &mxs_timer_irq); | ||
287 | } | 295 | } |
288 | CLOCKSOURCE_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init); | 296 | CLOCKSOURCE_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init); |
diff --git a/drivers/clocksource/nomadik-mtu.c b/drivers/clocksource/nomadik-mtu.c index bc8dd443c727..3c124d1ca600 100644 --- a/drivers/clocksource/nomadik-mtu.c +++ b/drivers/clocksource/nomadik-mtu.c | |||
@@ -193,10 +193,11 @@ static struct irqaction nmdk_timer_irq = { | |||
193 | .dev_id = &nmdk_clkevt, | 193 | .dev_id = &nmdk_clkevt, |
194 | }; | 194 | }; |
195 | 195 | ||
196 | static void __init nmdk_timer_init(void __iomem *base, int irq, | 196 | static int __init nmdk_timer_init(void __iomem *base, int irq, |
197 | struct clk *pclk, struct clk *clk) | 197 | struct clk *pclk, struct clk *clk) |
198 | { | 198 | { |
199 | unsigned long rate; | 199 | unsigned long rate; |
200 | int ret; | ||
200 | 201 | ||
201 | mtu_base = base; | 202 | mtu_base = base; |
202 | 203 | ||
@@ -226,10 +227,12 @@ static void __init nmdk_timer_init(void __iomem *base, int irq, | |||
226 | /* Timer 0 is the free running clocksource */ | 227 | /* Timer 0 is the free running clocksource */ |
227 | nmdk_clksrc_reset(); | 228 | nmdk_clksrc_reset(); |
228 | 229 | ||
229 | if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", | 230 | ret = clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", |
230 | rate, 200, 32, clocksource_mmio_readl_down)) | 231 | rate, 200, 32, clocksource_mmio_readl_down); |
231 | pr_err("timer: failed to initialize clock source %s\n", | 232 | if (ret) { |
232 | "mtu_0"); | 233 | pr_err("timer: failed to initialize clock source %s\n", "mtu_0"); |
234 | return ret; | ||
235 | } | ||
233 | 236 | ||
234 | #ifdef CONFIG_CLKSRC_NOMADIK_MTU_SCHED_CLOCK | 237 | #ifdef CONFIG_CLKSRC_NOMADIK_MTU_SCHED_CLOCK |
235 | sched_clock_register(nomadik_read_sched_clock, 32, rate); | 238 | sched_clock_register(nomadik_read_sched_clock, 32, rate); |
@@ -244,9 +247,11 @@ static void __init nmdk_timer_init(void __iomem *base, int irq, | |||
244 | mtu_delay_timer.read_current_timer = &nmdk_timer_read_current_timer; | 247 | mtu_delay_timer.read_current_timer = &nmdk_timer_read_current_timer; |
245 | mtu_delay_timer.freq = rate; | 248 | mtu_delay_timer.freq = rate; |
246 | register_current_timer_delay(&mtu_delay_timer); | 249 | register_current_timer_delay(&mtu_delay_timer); |
250 | |||
251 | return 0; | ||
247 | } | 252 | } |
248 | 253 | ||
249 | static void __init nmdk_timer_of_init(struct device_node *node) | 254 | static int __init nmdk_timer_of_init(struct device_node *node) |
250 | { | 255 | { |
251 | struct clk *pclk; | 256 | struct clk *pclk; |
252 | struct clk *clk; | 257 | struct clk *clk; |
@@ -254,22 +259,30 @@ static void __init nmdk_timer_of_init(struct device_node *node) | |||
254 | int irq; | 259 | int irq; |
255 | 260 | ||
256 | base = of_iomap(node, 0); | 261 | base = of_iomap(node, 0); |
257 | if (!base) | 262 | if (!base) { |
258 | panic("Can't remap registers"); | 263 | pr_err("Can't remap registers"); |
264 | return -ENXIO; | ||
265 | } | ||
259 | 266 | ||
260 | pclk = of_clk_get_by_name(node, "apb_pclk"); | 267 | pclk = of_clk_get_by_name(node, "apb_pclk"); |
261 | if (IS_ERR(pclk)) | 268 | if (IS_ERR(pclk)) { |
262 | panic("could not get apb_pclk"); | 269 | pr_err("could not get apb_pclk"); |
270 | return PTR_ERR(pclk); | ||
271 | } | ||
263 | 272 | ||
264 | clk = of_clk_get_by_name(node, "timclk"); | 273 | clk = of_clk_get_by_name(node, "timclk"); |
265 | if (IS_ERR(clk)) | 274 | if (IS_ERR(clk)) { |
266 | panic("could not get timclk"); | 275 | pr_err("could not get timclk"); |
276 | return PTR_ERR(clk); | ||
277 | } | ||
267 | 278 | ||
268 | irq = irq_of_parse_and_map(node, 0); | 279 | irq = irq_of_parse_and_map(node, 0); |
269 | if (irq <= 0) | 280 | if (irq <= 0) { |
270 | panic("Can't parse IRQ"); | 281 | pr_err("Can't parse IRQ"); |
282 | return -EINVAL; | ||
283 | } | ||
271 | 284 | ||
272 | nmdk_timer_init(base, irq, pclk, clk); | 285 | return nmdk_timer_init(base, irq, pclk, clk); |
273 | } | 286 | } |
274 | CLOCKSOURCE_OF_DECLARE(nomadik_mtu, "st,nomadik-mtu", | 287 | CLOCKSOURCE_OF_DECLARE(nomadik_mtu, "st,nomadik-mtu", |
275 | nmdk_timer_of_init); | 288 | nmdk_timer_of_init); |
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/pxa_timer.c index 45b6a4999713..937e10b84d58 100644 --- a/drivers/clocksource/pxa_timer.c +++ b/drivers/clocksource/pxa_timer.c | |||
@@ -150,8 +150,10 @@ static struct irqaction pxa_ost0_irq = { | |||
150 | .dev_id = &ckevt_pxa_osmr0, | 150 | .dev_id = &ckevt_pxa_osmr0, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static void __init pxa_timer_common_init(int irq, unsigned long clock_tick_rate) | 153 | static int __init pxa_timer_common_init(int irq, unsigned long clock_tick_rate) |
154 | { | 154 | { |
155 | int ret; | ||
156 | |||
155 | timer_writel(0, OIER); | 157 | timer_writel(0, OIER); |
156 | timer_writel(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); | 158 | timer_writel(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); |
157 | 159 | ||
@@ -159,39 +161,57 @@ static void __init pxa_timer_common_init(int irq, unsigned long clock_tick_rate) | |||
159 | 161 | ||
160 | ckevt_pxa_osmr0.cpumask = cpumask_of(0); | 162 | ckevt_pxa_osmr0.cpumask = cpumask_of(0); |
161 | 163 | ||
162 | setup_irq(irq, &pxa_ost0_irq); | 164 | ret = setup_irq(irq, &pxa_ost0_irq); |
165 | if (ret) { | ||
166 | pr_err("Failed to setup irq"); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | ret = clocksource_mmio_init(timer_base + OSCR, "oscr0", clock_tick_rate, 200, | ||
171 | 32, clocksource_mmio_readl_up); | ||
172 | if (ret) { | ||
173 | pr_err("Failed to init clocksource"); | ||
174 | return ret; | ||
175 | } | ||
163 | 176 | ||
164 | clocksource_mmio_init(timer_base + OSCR, "oscr0", clock_tick_rate, 200, | ||
165 | 32, clocksource_mmio_readl_up); | ||
166 | clockevents_config_and_register(&ckevt_pxa_osmr0, clock_tick_rate, | 177 | clockevents_config_and_register(&ckevt_pxa_osmr0, clock_tick_rate, |
167 | MIN_OSCR_DELTA * 2, 0x7fffffff); | 178 | MIN_OSCR_DELTA * 2, 0x7fffffff); |
179 | |||
180 | return 0; | ||
168 | } | 181 | } |
169 | 182 | ||
170 | static void __init pxa_timer_dt_init(struct device_node *np) | 183 | static int __init pxa_timer_dt_init(struct device_node *np) |
171 | { | 184 | { |
172 | struct clk *clk; | 185 | struct clk *clk; |
173 | int irq; | 186 | int irq, ret; |
174 | 187 | ||
175 | /* timer registers are shared with watchdog timer */ | 188 | /* timer registers are shared with watchdog timer */ |
176 | timer_base = of_iomap(np, 0); | 189 | timer_base = of_iomap(np, 0); |
177 | if (!timer_base) | 190 | if (!timer_base) { |
178 | panic("%s: unable to map resource\n", np->name); | 191 | pr_err("%s: unable to map resource\n", np->name); |
192 | return -ENXIO; | ||
193 | } | ||
179 | 194 | ||
180 | clk = of_clk_get(np, 0); | 195 | clk = of_clk_get(np, 0); |
181 | if (IS_ERR(clk)) { | 196 | if (IS_ERR(clk)) { |
182 | pr_crit("%s: unable to get clk\n", np->name); | 197 | pr_crit("%s: unable to get clk\n", np->name); |
183 | return; | 198 | return PTR_ERR(clk); |
199 | } | ||
200 | |||
201 | ret = clk_prepare_enable(clk); | ||
202 | if (ret) { | ||
203 | pr_crit("Failed to prepare clock"); | ||
204 | return ret; | ||
184 | } | 205 | } |
185 | clk_prepare_enable(clk); | ||
186 | 206 | ||
187 | /* we are only interested in OS-timer0 irq */ | 207 | /* we are only interested in OS-timer0 irq */ |
188 | irq = irq_of_parse_and_map(np, 0); | 208 | irq = irq_of_parse_and_map(np, 0); |
189 | if (irq <= 0) { | 209 | if (irq <= 0) { |
190 | pr_crit("%s: unable to parse OS-timer0 irq\n", np->name); | 210 | pr_crit("%s: unable to parse OS-timer0 irq\n", np->name); |
191 | return; | 211 | return -EINVAL; |
192 | } | 212 | } |
193 | 213 | ||
194 | pxa_timer_common_init(irq, clk_get_rate(clk)); | 214 | return pxa_timer_common_init(irq, clk_get_rate(clk)); |
195 | } | 215 | } |
196 | CLOCKSOURCE_OF_DECLARE(pxa_timer, "marvell,pxa-timer", pxa_timer_dt_init); | 216 | CLOCKSOURCE_OF_DECLARE(pxa_timer, "marvell,pxa-timer", pxa_timer_dt_init); |
197 | 217 | ||
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c index f8e09f923651..662576339049 100644 --- a/drivers/clocksource/qcom-timer.c +++ b/drivers/clocksource/qcom-timer.c | |||
@@ -178,7 +178,7 @@ static struct delay_timer msm_delay_timer = { | |||
178 | .read_current_timer = msm_read_current_timer, | 178 | .read_current_timer = msm_read_current_timer, |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, | 181 | static int __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, |
182 | bool percpu) | 182 | bool percpu) |
183 | { | 183 | { |
184 | struct clocksource *cs = &msm_clocksource; | 184 | struct clocksource *cs = &msm_clocksource; |
@@ -218,12 +218,14 @@ err: | |||
218 | sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); | 218 | sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); |
219 | msm_delay_timer.freq = dgt_hz; | 219 | msm_delay_timer.freq = dgt_hz; |
220 | register_current_timer_delay(&msm_delay_timer); | 220 | register_current_timer_delay(&msm_delay_timer); |
221 | |||
222 | return res; | ||
221 | } | 223 | } |
222 | 224 | ||
223 | static void __init msm_dt_timer_init(struct device_node *np) | 225 | static int __init msm_dt_timer_init(struct device_node *np) |
224 | { | 226 | { |
225 | u32 freq; | 227 | u32 freq; |
226 | int irq; | 228 | int irq, ret; |
227 | struct resource res; | 229 | struct resource res; |
228 | u32 percpu_offset; | 230 | u32 percpu_offset; |
229 | void __iomem *base; | 231 | void __iomem *base; |
@@ -232,34 +234,35 @@ static void __init msm_dt_timer_init(struct device_node *np) | |||
232 | base = of_iomap(np, 0); | 234 | base = of_iomap(np, 0); |
233 | if (!base) { | 235 | if (!base) { |
234 | pr_err("Failed to map event base\n"); | 236 | pr_err("Failed to map event base\n"); |
235 | return; | 237 | return -ENXIO; |
236 | } | 238 | } |
237 | 239 | ||
238 | /* We use GPT0 for the clockevent */ | 240 | /* We use GPT0 for the clockevent */ |
239 | irq = irq_of_parse_and_map(np, 1); | 241 | irq = irq_of_parse_and_map(np, 1); |
240 | if (irq <= 0) { | 242 | if (irq <= 0) { |
241 | pr_err("Can't get irq\n"); | 243 | pr_err("Can't get irq\n"); |
242 | return; | 244 | return -EINVAL; |
243 | } | 245 | } |
244 | 246 | ||
245 | /* We use CPU0's DGT for the clocksource */ | 247 | /* We use CPU0's DGT for the clocksource */ |
246 | if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) | 248 | if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) |
247 | percpu_offset = 0; | 249 | percpu_offset = 0; |
248 | 250 | ||
249 | if (of_address_to_resource(np, 0, &res)) { | 251 | ret = of_address_to_resource(np, 0, &res); |
252 | if (ret) { | ||
250 | pr_err("Failed to parse DGT resource\n"); | 253 | pr_err("Failed to parse DGT resource\n"); |
251 | return; | 254 | return ret; |
252 | } | 255 | } |
253 | 256 | ||
254 | cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); | 257 | cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); |
255 | if (!cpu0_base) { | 258 | if (!cpu0_base) { |
256 | pr_err("Failed to map source base\n"); | 259 | pr_err("Failed to map source base\n"); |
257 | return; | 260 | return -EINVAL; |
258 | } | 261 | } |
259 | 262 | ||
260 | if (of_property_read_u32(np, "clock-frequency", &freq)) { | 263 | if (of_property_read_u32(np, "clock-frequency", &freq)) { |
261 | pr_err("Unknown frequency\n"); | 264 | pr_err("Unknown frequency\n"); |
262 | return; | 265 | return -EINVAL; |
263 | } | 266 | } |
264 | 267 | ||
265 | event_base = base + 0x4; | 268 | event_base = base + 0x4; |
@@ -268,7 +271,7 @@ static void __init msm_dt_timer_init(struct device_node *np) | |||
268 | freq /= 4; | 271 | freq /= 4; |
269 | writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); | 272 | writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); |
270 | 273 | ||
271 | msm_timer_init(freq, 32, irq, !!percpu_offset); | 274 | return msm_timer_init(freq, 32, irq, !!percpu_offset); |
272 | } | 275 | } |
273 | CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); | 276 | CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); |
274 | CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); | 277 | CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); |
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c index b991b288c803..23e267acba25 100644 --- a/drivers/clocksource/rockchip_timer.c +++ b/drivers/clocksource/rockchip_timer.c | |||
@@ -19,7 +19,8 @@ | |||
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_REG3288 0x10 |
23 | #define TIMER_CONTROL_REG3399 0x1c | ||
23 | #define TIMER_INT_STATUS 0x18 | 24 | #define TIMER_INT_STATUS 0x18 |
24 | 25 | ||
25 | #define TIMER_DISABLE 0x0 | 26 | #define TIMER_DISABLE 0x0 |
@@ -31,6 +32,7 @@ | |||
31 | struct bc_timer { | 32 | struct bc_timer { |
32 | struct clock_event_device ce; | 33 | struct clock_event_device ce; |
33 | void __iomem *base; | 34 | void __iomem *base; |
35 | void __iomem *ctrl; | ||
34 | u32 freq; | 36 | u32 freq; |
35 | }; | 37 | }; |
36 | 38 | ||
@@ -46,15 +48,20 @@ static inline void __iomem *rk_base(struct clock_event_device *ce) | |||
46 | return rk_timer(ce)->base; | 48 | return rk_timer(ce)->base; |
47 | } | 49 | } |
48 | 50 | ||
51 | static inline void __iomem *rk_ctrl(struct clock_event_device *ce) | ||
52 | { | ||
53 | return rk_timer(ce)->ctrl; | ||
54 | } | ||
55 | |||
49 | static inline void rk_timer_disable(struct clock_event_device *ce) | 56 | static inline void rk_timer_disable(struct clock_event_device *ce) |
50 | { | 57 | { |
51 | writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG); | 58 | writel_relaxed(TIMER_DISABLE, rk_ctrl(ce)); |
52 | } | 59 | } |
53 | 60 | ||
54 | static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) | 61 | static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) |
55 | { | 62 | { |
56 | writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, | 63 | writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, |
57 | rk_base(ce) + TIMER_CONTROL_REG); | 64 | rk_ctrl(ce)); |
58 | } | 65 | } |
59 | 66 | ||
60 | static void rk_timer_update_counter(unsigned long cycles, | 67 | static void rk_timer_update_counter(unsigned long cycles, |
@@ -106,37 +113,42 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) | |||
106 | return IRQ_HANDLED; | 113 | return IRQ_HANDLED; |
107 | } | 114 | } |
108 | 115 | ||
109 | static void __init rk_timer_init(struct device_node *np) | 116 | static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg) |
110 | { | 117 | { |
111 | struct clock_event_device *ce = &bc_timer.ce; | 118 | struct clock_event_device *ce = &bc_timer.ce; |
112 | struct clk *timer_clk; | 119 | struct clk *timer_clk; |
113 | struct clk *pclk; | 120 | struct clk *pclk; |
114 | int ret, irq; | 121 | int ret = -EINVAL, irq; |
115 | 122 | ||
116 | bc_timer.base = of_iomap(np, 0); | 123 | bc_timer.base = of_iomap(np, 0); |
117 | if (!bc_timer.base) { | 124 | if (!bc_timer.base) { |
118 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); | 125 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); |
119 | return; | 126 | return -ENXIO; |
120 | } | 127 | } |
128 | bc_timer.ctrl = bc_timer.base + ctrl_reg; | ||
121 | 129 | ||
122 | pclk = of_clk_get_by_name(np, "pclk"); | 130 | pclk = of_clk_get_by_name(np, "pclk"); |
123 | if (IS_ERR(pclk)) { | 131 | if (IS_ERR(pclk)) { |
132 | ret = PTR_ERR(pclk); | ||
124 | pr_err("Failed to get pclk for '%s'\n", TIMER_NAME); | 133 | pr_err("Failed to get pclk for '%s'\n", TIMER_NAME); |
125 | goto out_unmap; | 134 | goto out_unmap; |
126 | } | 135 | } |
127 | 136 | ||
128 | if (clk_prepare_enable(pclk)) { | 137 | ret = clk_prepare_enable(pclk); |
138 | if (ret) { | ||
129 | pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); | 139 | pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); |
130 | goto out_unmap; | 140 | goto out_unmap; |
131 | } | 141 | } |
132 | 142 | ||
133 | timer_clk = of_clk_get_by_name(np, "timer"); | 143 | timer_clk = of_clk_get_by_name(np, "timer"); |
134 | if (IS_ERR(timer_clk)) { | 144 | if (IS_ERR(timer_clk)) { |
145 | ret = PTR_ERR(timer_clk); | ||
135 | pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME); | 146 | pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME); |
136 | goto out_timer_clk; | 147 | goto out_timer_clk; |
137 | } | 148 | } |
138 | 149 | ||
139 | if (clk_prepare_enable(timer_clk)) { | 150 | ret = clk_prepare_enable(timer_clk); |
151 | if (ret) { | ||
140 | pr_err("Failed to enable timer clock\n"); | 152 | pr_err("Failed to enable timer clock\n"); |
141 | goto out_timer_clk; | 153 | goto out_timer_clk; |
142 | } | 154 | } |
@@ -145,17 +157,19 @@ static void __init rk_timer_init(struct device_node *np) | |||
145 | 157 | ||
146 | irq = irq_of_parse_and_map(np, 0); | 158 | irq = irq_of_parse_and_map(np, 0); |
147 | if (!irq) { | 159 | if (!irq) { |
160 | ret = -EINVAL; | ||
148 | pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); | 161 | pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); |
149 | goto out_irq; | 162 | goto out_irq; |
150 | } | 163 | } |
151 | 164 | ||
152 | ce->name = TIMER_NAME; | 165 | ce->name = TIMER_NAME; |
153 | ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | 166 | ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | |
167 | CLOCK_EVT_FEAT_DYNIRQ; | ||
154 | ce->set_next_event = rk_timer_set_next_event; | 168 | ce->set_next_event = rk_timer_set_next_event; |
155 | ce->set_state_shutdown = rk_timer_shutdown; | 169 | ce->set_state_shutdown = rk_timer_shutdown; |
156 | ce->set_state_periodic = rk_timer_set_periodic; | 170 | ce->set_state_periodic = rk_timer_set_periodic; |
157 | ce->irq = irq; | 171 | ce->irq = irq; |
158 | ce->cpumask = cpumask_of(0); | 172 | ce->cpumask = cpu_possible_mask; |
159 | ce->rating = 250; | 173 | ce->rating = 250; |
160 | 174 | ||
161 | rk_timer_interrupt_clear(ce); | 175 | rk_timer_interrupt_clear(ce); |
@@ -169,7 +183,7 @@ static void __init rk_timer_init(struct device_node *np) | |||
169 | 183 | ||
170 | clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); | 184 | clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); |
171 | 185 | ||
172 | return; | 186 | return 0; |
173 | 187 | ||
174 | out_irq: | 188 | out_irq: |
175 | clk_disable_unprepare(timer_clk); | 189 | clk_disable_unprepare(timer_clk); |
@@ -177,6 +191,21 @@ out_timer_clk: | |||
177 | clk_disable_unprepare(pclk); | 191 | clk_disable_unprepare(pclk); |
178 | out_unmap: | 192 | out_unmap: |
179 | iounmap(bc_timer.base); | 193 | iounmap(bc_timer.base); |
194 | |||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | static int __init rk3288_timer_init(struct device_node *np) | ||
199 | { | ||
200 | return rk_timer_init(np, TIMER_CONTROL_REG3288); | ||
201 | } | ||
202 | |||
203 | static int __init rk3399_timer_init(struct device_node *np) | ||
204 | { | ||
205 | return rk_timer_init(np, TIMER_CONTROL_REG3399); | ||
180 | } | 206 | } |
181 | 207 | ||
182 | CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); | 208 | CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", |
209 | rk3288_timer_init); | ||
210 | CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", | ||
211 | rk3399_timer_init); | ||
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c index 9502bc4c3f6d..54565bd0093b 100644 --- a/drivers/clocksource/samsung_pwm_timer.c +++ b/drivers/clocksource/samsung_pwm_timer.c | |||
@@ -130,9 +130,9 @@ static void samsung_time_stop(unsigned int channel) | |||
130 | 130 | ||
131 | spin_lock_irqsave(&samsung_pwm_lock, flags); | 131 | spin_lock_irqsave(&samsung_pwm_lock, flags); |
132 | 132 | ||
133 | tcon = __raw_readl(pwm.base + REG_TCON); | 133 | tcon = readl_relaxed(pwm.base + REG_TCON); |
134 | tcon &= ~TCON_START(channel); | 134 | tcon &= ~TCON_START(channel); |
135 | __raw_writel(tcon, pwm.base + REG_TCON); | 135 | writel_relaxed(tcon, pwm.base + REG_TCON); |
136 | 136 | ||
137 | spin_unlock_irqrestore(&samsung_pwm_lock, flags); | 137 | spin_unlock_irqrestore(&samsung_pwm_lock, flags); |
138 | } | 138 | } |
@@ -148,14 +148,14 @@ static void samsung_time_setup(unsigned int channel, unsigned long tcnt) | |||
148 | 148 | ||
149 | spin_lock_irqsave(&samsung_pwm_lock, flags); | 149 | spin_lock_irqsave(&samsung_pwm_lock, flags); |
150 | 150 | ||
151 | tcon = __raw_readl(pwm.base + REG_TCON); | 151 | tcon = readl_relaxed(pwm.base + REG_TCON); |
152 | 152 | ||
153 | tcon &= ~(TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan)); | 153 | tcon &= ~(TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan)); |
154 | tcon |= TCON_MANUALUPDATE(tcon_chan); | 154 | tcon |= TCON_MANUALUPDATE(tcon_chan); |
155 | 155 | ||
156 | __raw_writel(tcnt, pwm.base + REG_TCNTB(channel)); | 156 | writel_relaxed(tcnt, pwm.base + REG_TCNTB(channel)); |
157 | __raw_writel(tcnt, pwm.base + REG_TCMPB(channel)); | 157 | writel_relaxed(tcnt, pwm.base + REG_TCMPB(channel)); |
158 | __raw_writel(tcon, pwm.base + REG_TCON); | 158 | writel_relaxed(tcon, pwm.base + REG_TCON); |
159 | 159 | ||
160 | spin_unlock_irqrestore(&samsung_pwm_lock, flags); | 160 | spin_unlock_irqrestore(&samsung_pwm_lock, flags); |
161 | } | 161 | } |
@@ -170,7 +170,7 @@ static void samsung_time_start(unsigned int channel, bool periodic) | |||
170 | 170 | ||
171 | spin_lock_irqsave(&samsung_pwm_lock, flags); | 171 | spin_lock_irqsave(&samsung_pwm_lock, flags); |
172 | 172 | ||
173 | tcon = __raw_readl(pwm.base + REG_TCON); | 173 | tcon = readl_relaxed(pwm.base + REG_TCON); |
174 | 174 | ||
175 | tcon &= ~TCON_MANUALUPDATE(channel); | 175 | tcon &= ~TCON_MANUALUPDATE(channel); |
176 | tcon |= TCON_START(channel); | 176 | tcon |= TCON_START(channel); |
@@ -180,7 +180,7 @@ static void samsung_time_start(unsigned int channel, bool periodic) | |||
180 | else | 180 | else |
181 | tcon &= ~TCON_AUTORELOAD(channel); | 181 | tcon &= ~TCON_AUTORELOAD(channel); |
182 | 182 | ||
183 | __raw_writel(tcon, pwm.base + REG_TCON); | 183 | writel_relaxed(tcon, pwm.base + REG_TCON); |
184 | 184 | ||
185 | spin_unlock_irqrestore(&samsung_pwm_lock, flags); | 185 | spin_unlock_irqrestore(&samsung_pwm_lock, flags); |
186 | } | 186 | } |
@@ -333,11 +333,10 @@ static u64 notrace samsung_read_sched_clock(void) | |||
333 | return samsung_clocksource_read(NULL); | 333 | return samsung_clocksource_read(NULL); |
334 | } | 334 | } |
335 | 335 | ||
336 | static void __init samsung_clocksource_init(void) | 336 | static int __init samsung_clocksource_init(void) |
337 | { | 337 | { |
338 | unsigned long pclk; | 338 | unsigned long pclk; |
339 | unsigned long clock_rate; | 339 | unsigned long clock_rate; |
340 | int ret; | ||
341 | 340 | ||
342 | pclk = clk_get_rate(pwm.timerclk); | 341 | pclk = clk_get_rate(pwm.timerclk); |
343 | 342 | ||
@@ -358,9 +357,7 @@ static void __init samsung_clocksource_init(void) | |||
358 | pwm.variant.bits, clock_rate); | 357 | pwm.variant.bits, clock_rate); |
359 | 358 | ||
360 | samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits); | 359 | samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits); |
361 | ret = clocksource_register_hz(&samsung_clocksource, clock_rate); | 360 | return clocksource_register_hz(&samsung_clocksource, clock_rate); |
362 | if (ret) | ||
363 | panic("samsung_clocksource_timer: can't register clocksource\n"); | ||
364 | } | 361 | } |
365 | 362 | ||
366 | static void __init samsung_timer_resources(void) | 363 | static void __init samsung_timer_resources(void) |
@@ -380,26 +377,31 @@ static void __init samsung_timer_resources(void) | |||
380 | /* | 377 | /* |
381 | * PWM master driver | 378 | * PWM master driver |
382 | */ | 379 | */ |
383 | static void __init _samsung_pwm_clocksource_init(void) | 380 | static int __init _samsung_pwm_clocksource_init(void) |
384 | { | 381 | { |
385 | u8 mask; | 382 | u8 mask; |
386 | int channel; | 383 | int channel; |
387 | 384 | ||
388 | mask = ~pwm.variant.output_mask & ((1 << SAMSUNG_PWM_NUM) - 1); | 385 | mask = ~pwm.variant.output_mask & ((1 << SAMSUNG_PWM_NUM) - 1); |
389 | channel = fls(mask) - 1; | 386 | channel = fls(mask) - 1; |
390 | if (channel < 0) | 387 | if (channel < 0) { |
391 | panic("failed to find PWM channel for clocksource"); | 388 | pr_crit("failed to find PWM channel for clocksource"); |
389 | return -EINVAL; | ||
390 | } | ||
392 | pwm.source_id = channel; | 391 | pwm.source_id = channel; |
393 | 392 | ||
394 | mask &= ~(1 << channel); | 393 | mask &= ~(1 << channel); |
395 | channel = fls(mask) - 1; | 394 | channel = fls(mask) - 1; |
396 | if (channel < 0) | 395 | if (channel < 0) { |
397 | panic("failed to find PWM channel for clock event"); | 396 | pr_crit("failed to find PWM channel for clock event"); |
397 | return -EINVAL; | ||
398 | } | ||
398 | pwm.event_id = channel; | 399 | pwm.event_id = channel; |
399 | 400 | ||
400 | samsung_timer_resources(); | 401 | samsung_timer_resources(); |
401 | samsung_clockevent_init(); | 402 | samsung_clockevent_init(); |
402 | samsung_clocksource_init(); | 403 | |
404 | return samsung_clocksource_init(); | ||
403 | } | 405 | } |
404 | 406 | ||
405 | void __init samsung_pwm_clocksource_init(void __iomem *base, | 407 | void __init samsung_pwm_clocksource_init(void __iomem *base, |
@@ -417,8 +419,8 @@ void __init samsung_pwm_clocksource_init(void __iomem *base, | |||
417 | } | 419 | } |
418 | 420 | ||
419 | #ifdef CONFIG_CLKSRC_OF | 421 | #ifdef CONFIG_CLKSRC_OF |
420 | static void __init samsung_pwm_alloc(struct device_node *np, | 422 | static int __init samsung_pwm_alloc(struct device_node *np, |
421 | const struct samsung_pwm_variant *variant) | 423 | const struct samsung_pwm_variant *variant) |
422 | { | 424 | { |
423 | struct property *prop; | 425 | struct property *prop; |
424 | const __be32 *cur; | 426 | const __be32 *cur; |
@@ -441,14 +443,16 @@ static void __init samsung_pwm_alloc(struct device_node *np, | |||
441 | pwm.base = of_iomap(np, 0); | 443 | pwm.base = of_iomap(np, 0); |
442 | if (!pwm.base) { | 444 | if (!pwm.base) { |
443 | pr_err("%s: failed to map PWM registers\n", __func__); | 445 | pr_err("%s: failed to map PWM registers\n", __func__); |
444 | return; | 446 | return -ENXIO; |
445 | } | 447 | } |
446 | 448 | ||
447 | pwm.timerclk = of_clk_get_by_name(np, "timers"); | 449 | pwm.timerclk = of_clk_get_by_name(np, "timers"); |
448 | if (IS_ERR(pwm.timerclk)) | 450 | if (IS_ERR(pwm.timerclk)) { |
449 | panic("failed to get timers clock for timer"); | 451 | pr_crit("failed to get timers clock for timer"); |
452 | return PTR_ERR(pwm.timerclk); | ||
453 | } | ||
450 | 454 | ||
451 | _samsung_pwm_clocksource_init(); | 455 | return _samsung_pwm_clocksource_init(); |
452 | } | 456 | } |
453 | 457 | ||
454 | static const struct samsung_pwm_variant s3c24xx_variant = { | 458 | static const struct samsung_pwm_variant s3c24xx_variant = { |
@@ -458,9 +462,9 @@ static const struct samsung_pwm_variant s3c24xx_variant = { | |||
458 | .tclk_mask = (1 << 4), | 462 | .tclk_mask = (1 << 4), |
459 | }; | 463 | }; |
460 | 464 | ||
461 | static void __init s3c2410_pwm_clocksource_init(struct device_node *np) | 465 | static int __init s3c2410_pwm_clocksource_init(struct device_node *np) |
462 | { | 466 | { |
463 | samsung_pwm_alloc(np, &s3c24xx_variant); | 467 | return samsung_pwm_alloc(np, &s3c24xx_variant); |
464 | } | 468 | } |
465 | CLOCKSOURCE_OF_DECLARE(s3c2410_pwm, "samsung,s3c2410-pwm", s3c2410_pwm_clocksource_init); | 469 | CLOCKSOURCE_OF_DECLARE(s3c2410_pwm, "samsung,s3c2410-pwm", s3c2410_pwm_clocksource_init); |
466 | 470 | ||
@@ -471,9 +475,9 @@ static const struct samsung_pwm_variant s3c64xx_variant = { | |||
471 | .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5), | 475 | .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5), |
472 | }; | 476 | }; |
473 | 477 | ||
474 | static void __init s3c64xx_pwm_clocksource_init(struct device_node *np) | 478 | static int __init s3c64xx_pwm_clocksource_init(struct device_node *np) |
475 | { | 479 | { |
476 | samsung_pwm_alloc(np, &s3c64xx_variant); | 480 | return samsung_pwm_alloc(np, &s3c64xx_variant); |
477 | } | 481 | } |
478 | CLOCKSOURCE_OF_DECLARE(s3c6400_pwm, "samsung,s3c6400-pwm", s3c64xx_pwm_clocksource_init); | 482 | CLOCKSOURCE_OF_DECLARE(s3c6400_pwm, "samsung,s3c6400-pwm", s3c64xx_pwm_clocksource_init); |
479 | 483 | ||
@@ -484,9 +488,9 @@ static const struct samsung_pwm_variant s5p64x0_variant = { | |||
484 | .tclk_mask = 0, | 488 | .tclk_mask = 0, |
485 | }; | 489 | }; |
486 | 490 | ||
487 | static void __init s5p64x0_pwm_clocksource_init(struct device_node *np) | 491 | static int __init s5p64x0_pwm_clocksource_init(struct device_node *np) |
488 | { | 492 | { |
489 | samsung_pwm_alloc(np, &s5p64x0_variant); | 493 | return samsung_pwm_alloc(np, &s5p64x0_variant); |
490 | } | 494 | } |
491 | CLOCKSOURCE_OF_DECLARE(s5p6440_pwm, "samsung,s5p6440-pwm", s5p64x0_pwm_clocksource_init); | 495 | CLOCKSOURCE_OF_DECLARE(s5p6440_pwm, "samsung,s5p6440-pwm", s5p64x0_pwm_clocksource_init); |
492 | 496 | ||
@@ -497,9 +501,9 @@ static const struct samsung_pwm_variant s5p_variant = { | |||
497 | .tclk_mask = (1 << 5), | 501 | .tclk_mask = (1 << 5), |
498 | }; | 502 | }; |
499 | 503 | ||
500 | static void __init s5p_pwm_clocksource_init(struct device_node *np) | 504 | static int __init s5p_pwm_clocksource_init(struct device_node *np) |
501 | { | 505 | { |
502 | samsung_pwm_alloc(np, &s5p_variant); | 506 | return samsung_pwm_alloc(np, &s5p_variant); |
503 | } | 507 | } |
504 | CLOCKSOURCE_OF_DECLARE(s5pc100_pwm, "samsung,s5pc100-pwm", s5p_pwm_clocksource_init); | 508 | CLOCKSOURCE_OF_DECLARE(s5pc100_pwm, "samsung,s5pc100-pwm", s5p_pwm_clocksource_init); |
505 | #endif | 509 | #endif |
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c index 6f3719d73390..97669ee4df2a 100644 --- a/drivers/clocksource/sun4i_timer.c +++ b/drivers/clocksource/sun4i_timer.c | |||
@@ -146,7 +146,7 @@ static u64 notrace sun4i_timer_sched_read(void) | |||
146 | return ~readl(timer_base + TIMER_CNTVAL_REG(1)); | 146 | return ~readl(timer_base + TIMER_CNTVAL_REG(1)); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void __init sun4i_timer_init(struct device_node *node) | 149 | static int __init sun4i_timer_init(struct device_node *node) |
150 | { | 150 | { |
151 | unsigned long rate = 0; | 151 | unsigned long rate = 0; |
152 | struct clk *clk; | 152 | struct clk *clk; |
@@ -154,17 +154,28 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
154 | u32 val; | 154 | u32 val; |
155 | 155 | ||
156 | timer_base = of_iomap(node, 0); | 156 | timer_base = of_iomap(node, 0); |
157 | if (!timer_base) | 157 | if (!timer_base) { |
158 | panic("Can't map registers"); | 158 | pr_crit("Can't map registers"); |
159 | return -ENXIO; | ||
160 | } | ||
159 | 161 | ||
160 | irq = irq_of_parse_and_map(node, 0); | 162 | irq = irq_of_parse_and_map(node, 0); |
161 | if (irq <= 0) | 163 | if (irq <= 0) { |
162 | panic("Can't parse IRQ"); | 164 | pr_crit("Can't parse IRQ"); |
165 | return -EINVAL; | ||
166 | } | ||
163 | 167 | ||
164 | clk = of_clk_get(node, 0); | 168 | clk = of_clk_get(node, 0); |
165 | if (IS_ERR(clk)) | 169 | if (IS_ERR(clk)) { |
166 | panic("Can't get timer clock"); | 170 | pr_crit("Can't get timer clock"); |
167 | clk_prepare_enable(clk); | 171 | return PTR_ERR(clk); |
172 | } | ||
173 | |||
174 | ret = clk_prepare_enable(clk); | ||
175 | if (ret) { | ||
176 | pr_err("Failed to prepare clock"); | ||
177 | return ret; | ||
178 | } | ||
168 | 179 | ||
169 | rate = clk_get_rate(clk); | 180 | rate = clk_get_rate(clk); |
170 | 181 | ||
@@ -182,8 +193,12 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
182 | of_machine_is_compatible("allwinner,sun5i-a10s")) | 193 | of_machine_is_compatible("allwinner,sun5i-a10s")) |
183 | sched_clock_register(sun4i_timer_sched_read, 32, rate); | 194 | sched_clock_register(sun4i_timer_sched_read, 32, rate); |
184 | 195 | ||
185 | clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name, | 196 | ret = clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name, |
186 | rate, 350, 32, clocksource_mmio_readl_down); | 197 | rate, 350, 32, clocksource_mmio_readl_down); |
198 | if (ret) { | ||
199 | pr_err("Failed to register clocksource"); | ||
200 | return ret; | ||
201 | } | ||
187 | 202 | ||
188 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); | 203 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); |
189 | 204 | ||
@@ -200,12 +215,16 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
200 | TIMER_SYNC_TICKS, 0xffffffff); | 215 | TIMER_SYNC_TICKS, 0xffffffff); |
201 | 216 | ||
202 | ret = setup_irq(irq, &sun4i_timer_irq); | 217 | ret = setup_irq(irq, &sun4i_timer_irq); |
203 | if (ret) | 218 | if (ret) { |
204 | pr_warn("failed to setup irq %d\n", irq); | 219 | pr_err("failed to setup irq %d\n", irq); |
220 | return ret; | ||
221 | } | ||
205 | 222 | ||
206 | /* Enable timer0 interrupt */ | 223 | /* Enable timer0 interrupt */ |
207 | val = readl(timer_base + TIMER_IRQ_EN_REG); | 224 | val = readl(timer_base + TIMER_IRQ_EN_REG); |
208 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); | 225 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); |
226 | |||
227 | return ret; | ||
209 | } | 228 | } |
210 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer", | 229 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-a10-timer", |
211 | sun4i_timer_init); | 230 | sun4i_timer_init); |
diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c index c407c47a3232..12fcef8cf2d3 100644 --- a/drivers/clocksource/tango_xtal.c +++ b/drivers/clocksource/tango_xtal.c | |||
@@ -19,7 +19,7 @@ static u64 notrace read_sched_clock(void) | |||
19 | return read_xtal_counter(); | 19 | return read_xtal_counter(); |
20 | } | 20 | } |
21 | 21 | ||
22 | static void __init tango_clocksource_init(struct device_node *np) | 22 | static int __init tango_clocksource_init(struct device_node *np) |
23 | { | 23 | { |
24 | struct clk *clk; | 24 | struct clk *clk; |
25 | int xtal_freq, ret; | 25 | int xtal_freq, ret; |
@@ -27,13 +27,13 @@ static void __init tango_clocksource_init(struct device_node *np) | |||
27 | xtal_in_cnt = of_iomap(np, 0); | 27 | xtal_in_cnt = of_iomap(np, 0); |
28 | if (xtal_in_cnt == NULL) { | 28 | if (xtal_in_cnt == NULL) { |
29 | pr_err("%s: invalid address\n", np->full_name); | 29 | pr_err("%s: invalid address\n", np->full_name); |
30 | return; | 30 | return -ENXIO; |
31 | } | 31 | } |
32 | 32 | ||
33 | clk = of_clk_get(np, 0); | 33 | clk = of_clk_get(np, 0); |
34 | if (IS_ERR(clk)) { | 34 | if (IS_ERR(clk)) { |
35 | pr_err("%s: invalid clock\n", np->full_name); | 35 | pr_err("%s: invalid clock\n", np->full_name); |
36 | return; | 36 | return PTR_ERR(clk); |
37 | } | 37 | } |
38 | 38 | ||
39 | xtal_freq = clk_get_rate(clk); | 39 | xtal_freq = clk_get_rate(clk); |
@@ -44,11 +44,13 @@ static void __init tango_clocksource_init(struct device_node *np) | |||
44 | 32, clocksource_mmio_readl_up); | 44 | 32, clocksource_mmio_readl_up); |
45 | if (ret) { | 45 | if (ret) { |
46 | pr_err("%s: registration failed\n", np->full_name); | 46 | pr_err("%s: registration failed\n", np->full_name); |
47 | return; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | sched_clock_register(read_sched_clock, 32, xtal_freq); | 50 | sched_clock_register(read_sched_clock, 32, xtal_freq); |
51 | register_current_timer_delay(&delay_timer); | 51 | register_current_timer_delay(&delay_timer); |
52 | |||
53 | return 0; | ||
52 | } | 54 | } |
53 | 55 | ||
54 | CLOCKSOURCE_OF_DECLARE(tango, "sigma,tick-counter", tango_clocksource_init); | 56 | CLOCKSOURCE_OF_DECLARE(tango, "sigma,tick-counter", tango_clocksource_init); |
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c index 7b94ad2ab278..f960891aa04e 100644 --- a/drivers/clocksource/tegra20_timer.c +++ b/drivers/clocksource/tegra20_timer.c | |||
@@ -165,7 +165,7 @@ static struct irqaction tegra_timer_irq = { | |||
165 | .dev_id = &tegra_clockevent, | 165 | .dev_id = &tegra_clockevent, |
166 | }; | 166 | }; |
167 | 167 | ||
168 | static void __init tegra20_init_timer(struct device_node *np) | 168 | static int __init tegra20_init_timer(struct device_node *np) |
169 | { | 169 | { |
170 | struct clk *clk; | 170 | struct clk *clk; |
171 | unsigned long rate; | 171 | unsigned long rate; |
@@ -174,13 +174,13 @@ static void __init tegra20_init_timer(struct device_node *np) | |||
174 | timer_reg_base = of_iomap(np, 0); | 174 | timer_reg_base = of_iomap(np, 0); |
175 | if (!timer_reg_base) { | 175 | if (!timer_reg_base) { |
176 | pr_err("Can't map timer registers\n"); | 176 | pr_err("Can't map timer registers\n"); |
177 | BUG(); | 177 | return -ENXIO; |
178 | } | 178 | } |
179 | 179 | ||
180 | tegra_timer_irq.irq = irq_of_parse_and_map(np, 2); | 180 | tegra_timer_irq.irq = irq_of_parse_and_map(np, 2); |
181 | if (tegra_timer_irq.irq <= 0) { | 181 | if (tegra_timer_irq.irq <= 0) { |
182 | pr_err("Failed to map timer IRQ\n"); | 182 | pr_err("Failed to map timer IRQ\n"); |
183 | BUG(); | 183 | return -EINVAL; |
184 | } | 184 | } |
185 | 185 | ||
186 | clk = of_clk_get(np, 0); | 186 | clk = of_clk_get(np, 0); |
@@ -211,10 +211,12 @@ static void __init tegra20_init_timer(struct device_node *np) | |||
211 | 211 | ||
212 | sched_clock_register(tegra_read_sched_clock, 32, 1000000); | 212 | sched_clock_register(tegra_read_sched_clock, 32, 1000000); |
213 | 213 | ||
214 | if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, | 214 | ret = clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, |
215 | "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) { | 215 | "timer_us", 1000000, 300, 32, |
216 | clocksource_mmio_readl_up); | ||
217 | if (ret) { | ||
216 | pr_err("Failed to register clocksource\n"); | 218 | pr_err("Failed to register clocksource\n"); |
217 | BUG(); | 219 | return ret; |
218 | } | 220 | } |
219 | 221 | ||
220 | tegra_delay_timer.read_current_timer = | 222 | tegra_delay_timer.read_current_timer = |
@@ -225,24 +227,26 @@ static void __init tegra20_init_timer(struct device_node *np) | |||
225 | ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq); | 227 | ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq); |
226 | if (ret) { | 228 | if (ret) { |
227 | pr_err("Failed to register timer IRQ: %d\n", ret); | 229 | pr_err("Failed to register timer IRQ: %d\n", ret); |
228 | BUG(); | 230 | return ret; |
229 | } | 231 | } |
230 | 232 | ||
231 | tegra_clockevent.cpumask = cpu_all_mask; | 233 | tegra_clockevent.cpumask = cpu_all_mask; |
232 | tegra_clockevent.irq = tegra_timer_irq.irq; | 234 | tegra_clockevent.irq = tegra_timer_irq.irq; |
233 | clockevents_config_and_register(&tegra_clockevent, 1000000, | 235 | clockevents_config_and_register(&tegra_clockevent, 1000000, |
234 | 0x1, 0x1fffffff); | 236 | 0x1, 0x1fffffff); |
237 | |||
238 | return 0; | ||
235 | } | 239 | } |
236 | CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer); | 240 | CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer); |
237 | 241 | ||
238 | static void __init tegra20_init_rtc(struct device_node *np) | 242 | static int __init tegra20_init_rtc(struct device_node *np) |
239 | { | 243 | { |
240 | struct clk *clk; | 244 | struct clk *clk; |
241 | 245 | ||
242 | rtc_base = of_iomap(np, 0); | 246 | rtc_base = of_iomap(np, 0); |
243 | if (!rtc_base) { | 247 | if (!rtc_base) { |
244 | pr_err("Can't map RTC registers"); | 248 | pr_err("Can't map RTC registers"); |
245 | BUG(); | 249 | return -ENXIO; |
246 | } | 250 | } |
247 | 251 | ||
248 | /* | 252 | /* |
@@ -255,6 +259,6 @@ static void __init tegra20_init_rtc(struct device_node *np) | |||
255 | else | 259 | else |
256 | clk_prepare_enable(clk); | 260 | clk_prepare_enable(clk); |
257 | 261 | ||
258 | register_persistent_clock(NULL, tegra_read_persistent_clock64); | 262 | return register_persistent_clock(NULL, tegra_read_persistent_clock64); |
259 | } | 263 | } |
260 | CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); | 264 | CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); |
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index d93ec3c4f139..a4e59239f28e 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c | |||
@@ -246,7 +246,7 @@ static void armada_370_xp_timer_resume(void) | |||
246 | writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); | 246 | writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); |
247 | } | 247 | } |
248 | 248 | ||
249 | struct syscore_ops armada_370_xp_timer_syscore_ops = { | 249 | static struct syscore_ops armada_370_xp_timer_syscore_ops = { |
250 | .suspend = armada_370_xp_timer_suspend, | 250 | .suspend = armada_370_xp_timer_suspend, |
251 | .resume = armada_370_xp_timer_resume, | 251 | .resume = armada_370_xp_timer_resume, |
252 | }; | 252 | }; |
@@ -260,14 +260,22 @@ static struct delay_timer armada_370_delay_timer = { | |||
260 | .read_current_timer = armada_370_delay_timer_read, | 260 | .read_current_timer = armada_370_delay_timer_read, |
261 | }; | 261 | }; |
262 | 262 | ||
263 | static void __init armada_370_xp_timer_common_init(struct device_node *np) | 263 | static int __init armada_370_xp_timer_common_init(struct device_node *np) |
264 | { | 264 | { |
265 | u32 clr = 0, set = 0; | 265 | u32 clr = 0, set = 0; |
266 | int res; | 266 | int res; |
267 | 267 | ||
268 | timer_base = of_iomap(np, 0); | 268 | timer_base = of_iomap(np, 0); |
269 | WARN_ON(!timer_base); | 269 | if (!timer_base) { |
270 | pr_err("Failed to iomap"); | ||
271 | return -ENXIO; | ||
272 | } | ||
273 | |||
270 | local_base = of_iomap(np, 1); | 274 | local_base = of_iomap(np, 1); |
275 | if (!local_base) { | ||
276 | pr_err("Failed to iomap"); | ||
277 | return -ENXIO; | ||
278 | } | ||
271 | 279 | ||
272 | if (timer25Mhz) { | 280 | if (timer25Mhz) { |
273 | set = TIMER0_25MHZ; | 281 | set = TIMER0_25MHZ; |
@@ -306,14 +314,19 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np) | |||
306 | */ | 314 | */ |
307 | sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk); | 315 | sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk); |
308 | 316 | ||
309 | clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, | 317 | res = clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, |
310 | "armada_370_xp_clocksource", | 318 | "armada_370_xp_clocksource", |
311 | timer_clk, 300, 32, clocksource_mmio_readl_down); | 319 | timer_clk, 300, 32, clocksource_mmio_readl_down); |
320 | if (res) { | ||
321 | pr_err("Failed to initialize clocksource mmio"); | ||
322 | return res; | ||
323 | } | ||
312 | 324 | ||
313 | register_cpu_notifier(&armada_370_xp_timer_cpu_nb); | 325 | register_cpu_notifier(&armada_370_xp_timer_cpu_nb); |
314 | 326 | ||
315 | armada_370_xp_evt = alloc_percpu(struct clock_event_device); | 327 | armada_370_xp_evt = alloc_percpu(struct clock_event_device); |
316 | 328 | if (!armada_370_xp_evt) | |
329 | return -ENOMEM; | ||
317 | 330 | ||
318 | /* | 331 | /* |
319 | * Setup clockevent timer (interrupt-driven). | 332 | * Setup clockevent timer (interrupt-driven). |
@@ -323,33 +336,54 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np) | |||
323 | "armada_370_xp_per_cpu_tick", | 336 | "armada_370_xp_per_cpu_tick", |
324 | armada_370_xp_evt); | 337 | armada_370_xp_evt); |
325 | /* Immediately configure the timer on the boot CPU */ | 338 | /* Immediately configure the timer on the boot CPU */ |
326 | if (!res) | 339 | if (res) { |
327 | armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); | 340 | pr_err("Failed to request percpu irq"); |
341 | return res; | ||
342 | } | ||
343 | |||
344 | res = armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); | ||
345 | if (!res) { | ||
346 | pr_err("Failed to setup timer"); | ||
347 | return res; | ||
348 | } | ||
328 | 349 | ||
329 | register_syscore_ops(&armada_370_xp_timer_syscore_ops); | 350 | register_syscore_ops(&armada_370_xp_timer_syscore_ops); |
351 | |||
352 | return 0; | ||
330 | } | 353 | } |
331 | 354 | ||
332 | static void __init armada_xp_timer_init(struct device_node *np) | 355 | static int __init armada_xp_timer_init(struct device_node *np) |
333 | { | 356 | { |
334 | struct clk *clk = of_clk_get_by_name(np, "fixed"); | 357 | struct clk *clk = of_clk_get_by_name(np, "fixed"); |
358 | int ret; | ||
359 | |||
360 | clk = of_clk_get(np, 0); | ||
361 | if (IS_ERR(clk)) { | ||
362 | pr_err("Failed to get clock"); | ||
363 | return PTR_ERR(clk); | ||
364 | } | ||
365 | |||
366 | ret = clk_prepare_enable(clk); | ||
367 | if (ret) | ||
368 | return ret; | ||
335 | 369 | ||
336 | /* The 25Mhz fixed clock is mandatory, and must always be available */ | ||
337 | BUG_ON(IS_ERR(clk)); | ||
338 | clk_prepare_enable(clk); | ||
339 | timer_clk = clk_get_rate(clk); | 370 | timer_clk = clk_get_rate(clk); |
340 | 371 | ||
341 | armada_370_xp_timer_common_init(np); | 372 | return armada_370_xp_timer_common_init(np); |
342 | } | 373 | } |
343 | CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", | 374 | CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", |
344 | armada_xp_timer_init); | 375 | armada_xp_timer_init); |
345 | 376 | ||
346 | static void __init armada_375_timer_init(struct device_node *np) | 377 | static int __init armada_375_timer_init(struct device_node *np) |
347 | { | 378 | { |
348 | struct clk *clk; | 379 | struct clk *clk; |
380 | int ret; | ||
349 | 381 | ||
350 | clk = of_clk_get_by_name(np, "fixed"); | 382 | clk = of_clk_get_by_name(np, "fixed"); |
351 | if (!IS_ERR(clk)) { | 383 | if (!IS_ERR(clk)) { |
352 | clk_prepare_enable(clk); | 384 | ret = clk_prepare_enable(clk); |
385 | if (ret) | ||
386 | return ret; | ||
353 | timer_clk = clk_get_rate(clk); | 387 | timer_clk = clk_get_rate(clk); |
354 | } else { | 388 | } else { |
355 | 389 | ||
@@ -360,27 +394,43 @@ static void __init armada_375_timer_init(struct device_node *np) | |||
360 | clk = of_clk_get(np, 0); | 394 | clk = of_clk_get(np, 0); |
361 | 395 | ||
362 | /* Must have at least a clock */ | 396 | /* Must have at least a clock */ |
363 | BUG_ON(IS_ERR(clk)); | 397 | if (IS_ERR(clk)) { |
364 | clk_prepare_enable(clk); | 398 | pr_err("Failed to get clock"); |
399 | return PTR_ERR(clk); | ||
400 | } | ||
401 | |||
402 | ret = clk_prepare_enable(clk); | ||
403 | if (ret) | ||
404 | return ret; | ||
405 | |||
365 | timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; | 406 | timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; |
366 | timer25Mhz = false; | 407 | timer25Mhz = false; |
367 | } | 408 | } |
368 | 409 | ||
369 | armada_370_xp_timer_common_init(np); | 410 | return armada_370_xp_timer_common_init(np); |
370 | } | 411 | } |
371 | CLOCKSOURCE_OF_DECLARE(armada_375, "marvell,armada-375-timer", | 412 | CLOCKSOURCE_OF_DECLARE(armada_375, "marvell,armada-375-timer", |
372 | armada_375_timer_init); | 413 | armada_375_timer_init); |
373 | 414 | ||
374 | static void __init armada_370_timer_init(struct device_node *np) | 415 | static int __init armada_370_timer_init(struct device_node *np) |
375 | { | 416 | { |
376 | struct clk *clk = of_clk_get(np, 0); | 417 | struct clk *clk; |
418 | int ret; | ||
419 | |||
420 | clk = of_clk_get(np, 0); | ||
421 | if (IS_ERR(clk)) { | ||
422 | pr_err("Failed to get clock"); | ||
423 | return PTR_ERR(clk); | ||
424 | } | ||
425 | |||
426 | ret = clk_prepare_enable(clk); | ||
427 | if (ret) | ||
428 | return ret; | ||
377 | 429 | ||
378 | BUG_ON(IS_ERR(clk)); | ||
379 | clk_prepare_enable(clk); | ||
380 | timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; | 430 | timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; |
381 | timer25Mhz = false; | 431 | timer25Mhz = false; |
382 | 432 | ||
383 | armada_370_xp_timer_common_init(np); | 433 | return armada_370_xp_timer_common_init(np); |
384 | } | 434 | } |
385 | CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer", | 435 | CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer", |
386 | armada_370_timer_init); | 436 | armada_370_timer_init); |
diff --git a/drivers/clocksource/time-efm32.c b/drivers/clocksource/time-efm32.c index b06e4c2be406..5ac344b383e1 100644 --- a/drivers/clocksource/time-efm32.c +++ b/drivers/clocksource/time-efm32.c | |||
@@ -233,10 +233,15 @@ static int __init efm32_clockevent_init(struct device_node *np) | |||
233 | DIV_ROUND_CLOSEST(rate, 1024), | 233 | DIV_ROUND_CLOSEST(rate, 1024), |
234 | 0xf, 0xffff); | 234 | 0xf, 0xffff); |
235 | 235 | ||
236 | setup_irq(irq, &efm32_clock_event_irq); | 236 | ret = setup_irq(irq, &efm32_clock_event_irq); |
237 | if (ret) { | ||
238 | pr_err("Failed setup irq"); | ||
239 | goto err_setup_irq; | ||
240 | } | ||
237 | 241 | ||
238 | return 0; | 242 | return 0; |
239 | 243 | ||
244 | err_setup_irq: | ||
240 | err_get_irq: | 245 | err_get_irq: |
241 | 246 | ||
242 | iounmap(base); | 247 | iounmap(base); |
@@ -255,16 +260,16 @@ err_clk_get: | |||
255 | * This function asserts that we have exactly one clocksource and one | 260 | * This function asserts that we have exactly one clocksource and one |
256 | * clock_event_device in the end. | 261 | * clock_event_device in the end. |
257 | */ | 262 | */ |
258 | static void __init efm32_timer_init(struct device_node *np) | 263 | static int __init efm32_timer_init(struct device_node *np) |
259 | { | 264 | { |
260 | static int has_clocksource, has_clockevent; | 265 | static int has_clocksource, has_clockevent; |
261 | int ret; | 266 | int ret = 0; |
262 | 267 | ||
263 | if (!has_clocksource) { | 268 | if (!has_clocksource) { |
264 | ret = efm32_clocksource_init(np); | 269 | ret = efm32_clocksource_init(np); |
265 | if (!ret) { | 270 | if (!ret) { |
266 | has_clocksource = 1; | 271 | has_clocksource = 1; |
267 | return; | 272 | return 0; |
268 | } | 273 | } |
269 | } | 274 | } |
270 | 275 | ||
@@ -272,9 +277,11 @@ static void __init efm32_timer_init(struct device_node *np) | |||
272 | ret = efm32_clockevent_init(np); | 277 | ret = efm32_clockevent_init(np); |
273 | if (!ret) { | 278 | if (!ret) { |
274 | has_clockevent = 1; | 279 | has_clockevent = 1; |
275 | return; | 280 | return 0; |
276 | } | 281 | } |
277 | } | 282 | } |
283 | |||
284 | return ret; | ||
278 | } | 285 | } |
279 | CLOCKSOURCE_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init); | 286 | CLOCKSOURCE_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init); |
280 | CLOCKSOURCE_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init); | 287 | CLOCKSOURCE_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init); |
diff --git a/drivers/clocksource/time-lpc32xx.c b/drivers/clocksource/time-lpc32xx.c index daae61e8c820..9649cfdb9213 100644 --- a/drivers/clocksource/time-lpc32xx.c +++ b/drivers/clocksource/time-lpc32xx.c | |||
@@ -288,16 +288,16 @@ err_clk_enable: | |||
288 | * This function asserts that we have exactly one clocksource and one | 288 | * This function asserts that we have exactly one clocksource and one |
289 | * clock_event_device in the end. | 289 | * clock_event_device in the end. |
290 | */ | 290 | */ |
291 | static void __init lpc32xx_timer_init(struct device_node *np) | 291 | static int __init lpc32xx_timer_init(struct device_node *np) |
292 | { | 292 | { |
293 | static int has_clocksource, has_clockevent; | 293 | static int has_clocksource, has_clockevent; |
294 | int ret; | 294 | int ret = 0; |
295 | 295 | ||
296 | if (!has_clocksource) { | 296 | if (!has_clocksource) { |
297 | ret = lpc32xx_clocksource_init(np); | 297 | ret = lpc32xx_clocksource_init(np); |
298 | if (!ret) { | 298 | if (!ret) { |
299 | has_clocksource = 1; | 299 | has_clocksource = 1; |
300 | return; | 300 | return 0; |
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
@@ -305,8 +305,10 @@ static void __init lpc32xx_timer_init(struct device_node *np) | |||
305 | ret = lpc32xx_clockevent_init(np); | 305 | ret = lpc32xx_clockevent_init(np); |
306 | if (!ret) { | 306 | if (!ret) { |
307 | has_clockevent = 1; | 307 | has_clockevent = 1; |
308 | return; | 308 | return 0; |
309 | } | 309 | } |
310 | } | 310 | } |
311 | |||
312 | return ret; | ||
311 | } | 313 | } |
312 | CLOCKSOURCE_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init); | 314 | CLOCKSOURCE_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init); |
diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c index 0ece7427b497..a28f496e97cf 100644 --- a/drivers/clocksource/time-orion.c +++ b/drivers/clocksource/time-orion.c | |||
@@ -104,25 +104,36 @@ static struct irqaction orion_clkevt_irq = { | |||
104 | .handler = orion_clkevt_irq_handler, | 104 | .handler = orion_clkevt_irq_handler, |
105 | }; | 105 | }; |
106 | 106 | ||
107 | static void __init orion_timer_init(struct device_node *np) | 107 | static int __init orion_timer_init(struct device_node *np) |
108 | { | 108 | { |
109 | struct clk *clk; | 109 | struct clk *clk; |
110 | int irq; | 110 | int irq, ret; |
111 | 111 | ||
112 | /* timer registers are shared with watchdog timer */ | 112 | /* timer registers are shared with watchdog timer */ |
113 | timer_base = of_iomap(np, 0); | 113 | timer_base = of_iomap(np, 0); |
114 | if (!timer_base) | 114 | if (!timer_base) { |
115 | panic("%s: unable to map resource\n", np->name); | 115 | pr_err("%s: unable to map resource\n", np->name); |
116 | return -ENXIO; | ||
117 | } | ||
116 | 118 | ||
117 | clk = of_clk_get(np, 0); | 119 | clk = of_clk_get(np, 0); |
118 | if (IS_ERR(clk)) | 120 | if (IS_ERR(clk)) { |
119 | panic("%s: unable to get clk\n", np->name); | 121 | pr_err("%s: unable to get clk\n", np->name); |
120 | clk_prepare_enable(clk); | 122 | return PTR_ERR(clk); |
123 | } | ||
124 | |||
125 | ret = clk_prepare_enable(clk); | ||
126 | if (ret) { | ||
127 | pr_err("Failed to prepare clock"); | ||
128 | return ret; | ||
129 | } | ||
121 | 130 | ||
122 | /* we are only interested in timer1 irq */ | 131 | /* we are only interested in timer1 irq */ |
123 | irq = irq_of_parse_and_map(np, 1); | 132 | irq = irq_of_parse_and_map(np, 1); |
124 | if (irq <= 0) | 133 | if (irq <= 0) { |
125 | panic("%s: unable to parse timer1 irq\n", np->name); | 134 | pr_err("%s: unable to parse timer1 irq\n", np->name); |
135 | return -EINVAL; | ||
136 | } | ||
126 | 137 | ||
127 | /* setup timer0 as free-running clocksource */ | 138 | /* setup timer0 as free-running clocksource */ |
128 | writel(~0, timer_base + TIMER0_VAL); | 139 | writel(~0, timer_base + TIMER0_VAL); |
@@ -130,19 +141,30 @@ static void __init orion_timer_init(struct device_node *np) | |||
130 | atomic_io_modify(timer_base + TIMER_CTRL, | 141 | atomic_io_modify(timer_base + TIMER_CTRL, |
131 | TIMER0_RELOAD_EN | TIMER0_EN, | 142 | TIMER0_RELOAD_EN | TIMER0_EN, |
132 | TIMER0_RELOAD_EN | TIMER0_EN); | 143 | TIMER0_RELOAD_EN | TIMER0_EN); |
133 | clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", | 144 | |
134 | clk_get_rate(clk), 300, 32, | 145 | ret = clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", |
135 | clocksource_mmio_readl_down); | 146 | clk_get_rate(clk), 300, 32, |
147 | clocksource_mmio_readl_down); | ||
148 | if (ret) { | ||
149 | pr_err("Failed to initialize mmio timer"); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
136 | sched_clock_register(orion_read_sched_clock, 32, clk_get_rate(clk)); | 153 | sched_clock_register(orion_read_sched_clock, 32, clk_get_rate(clk)); |
137 | 154 | ||
138 | /* setup timer1 as clockevent timer */ | 155 | /* setup timer1 as clockevent timer */ |
139 | if (setup_irq(irq, &orion_clkevt_irq)) | 156 | ret = setup_irq(irq, &orion_clkevt_irq); |
140 | panic("%s: unable to setup irq\n", np->name); | 157 | if (ret) { |
158 | pr_err("%s: unable to setup irq\n", np->name); | ||
159 | return ret; | ||
160 | } | ||
141 | 161 | ||
142 | ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; | 162 | ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; |
143 | orion_clkevt.cpumask = cpumask_of(0); | 163 | orion_clkevt.cpumask = cpumask_of(0); |
144 | orion_clkevt.irq = irq; | 164 | orion_clkevt.irq = irq; |
145 | clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk), | 165 | clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk), |
146 | ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); | 166 | ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); |
167 | |||
168 | return 0; | ||
147 | } | 169 | } |
148 | CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); | 170 | CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); |
diff --git a/drivers/clocksource/time-pistachio.c b/drivers/clocksource/time-pistachio.c index 376e59bc5fa0..a7d9a08e4b0e 100644 --- a/drivers/clocksource/time-pistachio.c +++ b/drivers/clocksource/time-pistachio.c | |||
@@ -148,7 +148,7 @@ static struct pistachio_clocksource pcs_gpt = { | |||
148 | }, | 148 | }, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static void __init pistachio_clksrc_of_init(struct device_node *node) | 151 | static int __init pistachio_clksrc_of_init(struct device_node *node) |
152 | { | 152 | { |
153 | struct clk *sys_clk, *fast_clk; | 153 | struct clk *sys_clk, *fast_clk; |
154 | struct regmap *periph_regs; | 154 | struct regmap *periph_regs; |
@@ -158,45 +158,45 @@ static void __init pistachio_clksrc_of_init(struct device_node *node) | |||
158 | pcs_gpt.base = of_iomap(node, 0); | 158 | pcs_gpt.base = of_iomap(node, 0); |
159 | if (!pcs_gpt.base) { | 159 | if (!pcs_gpt.base) { |
160 | pr_err("cannot iomap\n"); | 160 | pr_err("cannot iomap\n"); |
161 | return; | 161 | return -ENXIO; |
162 | } | 162 | } |
163 | 163 | ||
164 | periph_regs = syscon_regmap_lookup_by_phandle(node, "img,cr-periph"); | 164 | periph_regs = syscon_regmap_lookup_by_phandle(node, "img,cr-periph"); |
165 | if (IS_ERR(periph_regs)) { | 165 | if (IS_ERR(periph_regs)) { |
166 | pr_err("cannot get peripheral regmap (%ld)\n", | 166 | pr_err("cannot get peripheral regmap (%ld)\n", |
167 | PTR_ERR(periph_regs)); | 167 | PTR_ERR(periph_regs)); |
168 | return; | 168 | return PTR_ERR(periph_regs); |
169 | } | 169 | } |
170 | 170 | ||
171 | /* Switch to using the fast counter clock */ | 171 | /* Switch to using the fast counter clock */ |
172 | ret = regmap_update_bits(periph_regs, PERIP_TIMER_CONTROL, | 172 | ret = regmap_update_bits(periph_regs, PERIP_TIMER_CONTROL, |
173 | 0xf, 0x0); | 173 | 0xf, 0x0); |
174 | if (ret) | 174 | if (ret) |
175 | return; | 175 | return ret; |
176 | 176 | ||
177 | sys_clk = of_clk_get_by_name(node, "sys"); | 177 | sys_clk = of_clk_get_by_name(node, "sys"); |
178 | if (IS_ERR(sys_clk)) { | 178 | if (IS_ERR(sys_clk)) { |
179 | pr_err("clock get failed (%ld)\n", PTR_ERR(sys_clk)); | 179 | pr_err("clock get failed (%ld)\n", PTR_ERR(sys_clk)); |
180 | return; | 180 | return PTR_ERR(sys_clk); |
181 | } | 181 | } |
182 | 182 | ||
183 | fast_clk = of_clk_get_by_name(node, "fast"); | 183 | fast_clk = of_clk_get_by_name(node, "fast"); |
184 | if (IS_ERR(fast_clk)) { | 184 | if (IS_ERR(fast_clk)) { |
185 | pr_err("clock get failed (%lu)\n", PTR_ERR(fast_clk)); | 185 | pr_err("clock get failed (%lu)\n", PTR_ERR(fast_clk)); |
186 | return; | 186 | return PTR_ERR(fast_clk); |
187 | } | 187 | } |
188 | 188 | ||
189 | ret = clk_prepare_enable(sys_clk); | 189 | ret = clk_prepare_enable(sys_clk); |
190 | if (ret < 0) { | 190 | if (ret < 0) { |
191 | pr_err("failed to enable clock (%d)\n", ret); | 191 | pr_err("failed to enable clock (%d)\n", ret); |
192 | return; | 192 | return ret; |
193 | } | 193 | } |
194 | 194 | ||
195 | ret = clk_prepare_enable(fast_clk); | 195 | ret = clk_prepare_enable(fast_clk); |
196 | if (ret < 0) { | 196 | if (ret < 0) { |
197 | pr_err("failed to enable clock (%d)\n", ret); | 197 | pr_err("failed to enable clock (%d)\n", ret); |
198 | clk_disable_unprepare(sys_clk); | 198 | clk_disable_unprepare(sys_clk); |
199 | return; | 199 | return ret; |
200 | } | 200 | } |
201 | 201 | ||
202 | rate = clk_get_rate(fast_clk); | 202 | rate = clk_get_rate(fast_clk); |
@@ -212,7 +212,7 @@ static void __init pistachio_clksrc_of_init(struct device_node *node) | |||
212 | 212 | ||
213 | raw_spin_lock_init(&pcs_gpt.lock); | 213 | raw_spin_lock_init(&pcs_gpt.lock); |
214 | sched_clock_register(pistachio_read_sched_clock, 32, rate); | 214 | sched_clock_register(pistachio_read_sched_clock, 32, rate); |
215 | clocksource_register_hz(&pcs_gpt.cs, rate); | 215 | return clocksource_register_hz(&pcs_gpt.cs, rate); |
216 | } | 216 | } |
217 | CLOCKSOURCE_OF_DECLARE(pistachio_gptimer, "img,pistachio-gptimer", | 217 | CLOCKSOURCE_OF_DECLARE(pistachio_gptimer, "img,pistachio-gptimer", |
218 | pistachio_clksrc_of_init); | 218 | pistachio_clksrc_of_init); |
diff --git a/drivers/clocksource/timer-atlas7.c b/drivers/clocksource/timer-atlas7.c index 27fa13680be1..90f8fbc154a4 100644 --- a/drivers/clocksource/timer-atlas7.c +++ b/drivers/clocksource/timer-atlas7.c | |||
@@ -238,7 +238,7 @@ static struct notifier_block sirfsoc_cpu_nb = { | |||
238 | .notifier_call = sirfsoc_cpu_notify, | 238 | .notifier_call = sirfsoc_cpu_notify, |
239 | }; | 239 | }; |
240 | 240 | ||
241 | static void __init sirfsoc_clockevent_init(void) | 241 | static int __init sirfsoc_clockevent_init(void) |
242 | { | 242 | { |
243 | sirfsoc_clockevent = alloc_percpu(struct clock_event_device); | 243 | sirfsoc_clockevent = alloc_percpu(struct clock_event_device); |
244 | BUG_ON(!sirfsoc_clockevent); | 244 | BUG_ON(!sirfsoc_clockevent); |
@@ -246,11 +246,11 @@ static void __init sirfsoc_clockevent_init(void) | |||
246 | BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb)); | 246 | BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb)); |
247 | 247 | ||
248 | /* Immediately configure the timer on the boot CPU */ | 248 | /* Immediately configure the timer on the boot CPU */ |
249 | sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent)); | 249 | return sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent)); |
250 | } | 250 | } |
251 | 251 | ||
252 | /* initialize the kernel jiffy timer source */ | 252 | /* initialize the kernel jiffy timer source */ |
253 | static void __init sirfsoc_atlas7_timer_init(struct device_node *np) | 253 | static int __init sirfsoc_atlas7_timer_init(struct device_node *np) |
254 | { | 254 | { |
255 | struct clk *clk; | 255 | struct clk *clk; |
256 | 256 | ||
@@ -279,23 +279,29 @@ static void __init sirfsoc_atlas7_timer_init(struct device_node *np) | |||
279 | 279 | ||
280 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, atlas7_timer_rate)); | 280 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, atlas7_timer_rate)); |
281 | 281 | ||
282 | sirfsoc_clockevent_init(); | 282 | return sirfsoc_clockevent_init(); |
283 | } | 283 | } |
284 | 284 | ||
285 | static void __init sirfsoc_of_timer_init(struct device_node *np) | 285 | static int __init sirfsoc_of_timer_init(struct device_node *np) |
286 | { | 286 | { |
287 | sirfsoc_timer_base = of_iomap(np, 0); | 287 | sirfsoc_timer_base = of_iomap(np, 0); |
288 | if (!sirfsoc_timer_base) | 288 | if (!sirfsoc_timer_base) { |
289 | panic("unable to map timer cpu registers\n"); | 289 | pr_err("unable to map timer cpu registers\n"); |
290 | return -ENXIO; | ||
291 | } | ||
290 | 292 | ||
291 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); | 293 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); |
292 | if (!sirfsoc_timer_irq.irq) | 294 | if (!sirfsoc_timer_irq.irq) { |
293 | panic("No irq passed for timer0 via DT\n"); | 295 | pr_err("No irq passed for timer0 via DT\n"); |
296 | return -EINVAL; | ||
297 | } | ||
294 | 298 | ||
295 | sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); | 299 | sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); |
296 | if (!sirfsoc_timer1_irq.irq) | 300 | if (!sirfsoc_timer1_irq.irq) { |
297 | panic("No irq passed for timer1 via DT\n"); | 301 | pr_err("No irq passed for timer1 via DT\n"); |
302 | return -EINVAL; | ||
303 | } | ||
298 | 304 | ||
299 | sirfsoc_atlas7_timer_init(np); | 305 | return sirfsoc_atlas7_timer_init(np); |
300 | } | 306 | } |
301 | CLOCKSOURCE_OF_DECLARE(sirfsoc_atlas7_timer, "sirf,atlas7-tick", sirfsoc_of_timer_init); | 307 | CLOCKSOURCE_OF_DECLARE(sirfsoc_atlas7_timer, "sirf,atlas7-tick", sirfsoc_of_timer_init); |
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index d911c5dca8f1..1ffac0cb0cb7 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c | |||
@@ -177,7 +177,7 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) | |||
177 | /* | 177 | /* |
178 | * Set up both clocksource and clockevent support. | 178 | * Set up both clocksource and clockevent support. |
179 | */ | 179 | */ |
180 | static void __init at91sam926x_pit_common_init(struct pit_data *data) | 180 | static int __init at91sam926x_pit_common_init(struct pit_data *data) |
181 | { | 181 | { |
182 | unsigned long pit_rate; | 182 | unsigned long pit_rate; |
183 | unsigned bits; | 183 | unsigned bits; |
@@ -204,14 +204,21 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data) | |||
204 | data->clksrc.rating = 175; | 204 | data->clksrc.rating = 175; |
205 | data->clksrc.read = read_pit_clk; | 205 | data->clksrc.read = read_pit_clk; |
206 | data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; | 206 | data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; |
207 | clocksource_register_hz(&data->clksrc, pit_rate); | 207 | |
208 | ret = clocksource_register_hz(&data->clksrc, pit_rate); | ||
209 | if (ret) { | ||
210 | pr_err("Failed to register clocksource"); | ||
211 | return ret; | ||
212 | } | ||
208 | 213 | ||
209 | /* Set up irq handler */ | 214 | /* Set up irq handler */ |
210 | ret = request_irq(data->irq, at91sam926x_pit_interrupt, | 215 | ret = request_irq(data->irq, at91sam926x_pit_interrupt, |
211 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, | 216 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, |
212 | "at91_tick", data); | 217 | "at91_tick", data); |
213 | if (ret) | 218 | if (ret) { |
214 | panic(pr_fmt("Unable to setup IRQ\n")); | 219 | pr_err("Unable to setup IRQ\n"); |
220 | return ret; | ||
221 | } | ||
215 | 222 | ||
216 | /* Set up and register clockevents */ | 223 | /* Set up and register clockevents */ |
217 | data->clkevt.name = "pit"; | 224 | data->clkevt.name = "pit"; |
@@ -226,34 +233,42 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data) | |||
226 | data->clkevt.resume = at91sam926x_pit_resume; | 233 | data->clkevt.resume = at91sam926x_pit_resume; |
227 | data->clkevt.suspend = at91sam926x_pit_suspend; | 234 | data->clkevt.suspend = at91sam926x_pit_suspend; |
228 | clockevents_register_device(&data->clkevt); | 235 | clockevents_register_device(&data->clkevt); |
236 | |||
237 | return 0; | ||
229 | } | 238 | } |
230 | 239 | ||
231 | static void __init at91sam926x_pit_dt_init(struct device_node *node) | 240 | static int __init at91sam926x_pit_dt_init(struct device_node *node) |
232 | { | 241 | { |
233 | struct pit_data *data; | 242 | struct pit_data *data; |
234 | 243 | ||
235 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 244 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
236 | if (!data) | 245 | if (!data) |
237 | panic(pr_fmt("Unable to allocate memory\n")); | 246 | return -ENOMEM; |
238 | 247 | ||
239 | data->base = of_iomap(node, 0); | 248 | data->base = of_iomap(node, 0); |
240 | if (!data->base) | 249 | if (!data->base) { |
241 | panic(pr_fmt("Could not map PIT address\n")); | 250 | pr_err("Could not map PIT address\n"); |
251 | return -ENXIO; | ||
252 | } | ||
242 | 253 | ||
243 | data->mck = of_clk_get(node, 0); | 254 | data->mck = of_clk_get(node, 0); |
244 | if (IS_ERR(data->mck)) | 255 | if (IS_ERR(data->mck)) |
245 | /* Fallback on clkdev for !CCF-based boards */ | 256 | /* Fallback on clkdev for !CCF-based boards */ |
246 | data->mck = clk_get(NULL, "mck"); | 257 | data->mck = clk_get(NULL, "mck"); |
247 | 258 | ||
248 | if (IS_ERR(data->mck)) | 259 | if (IS_ERR(data->mck)) { |
249 | panic(pr_fmt("Unable to get mck clk\n")); | 260 | pr_err("Unable to get mck clk\n"); |
261 | return PTR_ERR(data->mck); | ||
262 | } | ||
250 | 263 | ||
251 | /* Get the interrupts property */ | 264 | /* Get the interrupts property */ |
252 | data->irq = irq_of_parse_and_map(node, 0); | 265 | data->irq = irq_of_parse_and_map(node, 0); |
253 | if (!data->irq) | 266 | if (!data->irq) { |
254 | panic(pr_fmt("Unable to get IRQ from DT\n")); | 267 | pr_err("Unable to get IRQ from DT\n"); |
268 | return -EINVAL; | ||
269 | } | ||
255 | 270 | ||
256 | at91sam926x_pit_common_init(data); | 271 | return at91sam926x_pit_common_init(data); |
257 | } | 272 | } |
258 | CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", | 273 | CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", |
259 | at91sam926x_pit_dt_init); | 274 | at91sam926x_pit_dt_init); |
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c index 29d21d68df5a..e90ab5b63a90 100644 --- a/drivers/clocksource/timer-atmel-st.c +++ b/drivers/clocksource/timer-atmel-st.c | |||
@@ -194,15 +194,17 @@ static struct clock_event_device clkevt = { | |||
194 | /* | 194 | /* |
195 | * ST (system timer) module supports both clockevents and clocksource. | 195 | * ST (system timer) module supports both clockevents and clocksource. |
196 | */ | 196 | */ |
197 | static void __init atmel_st_timer_init(struct device_node *node) | 197 | static int __init atmel_st_timer_init(struct device_node *node) |
198 | { | 198 | { |
199 | struct clk *sclk; | 199 | struct clk *sclk; |
200 | unsigned int sclk_rate, val; | 200 | unsigned int sclk_rate, val; |
201 | int irq, ret; | 201 | int irq, ret; |
202 | 202 | ||
203 | regmap_st = syscon_node_to_regmap(node); | 203 | regmap_st = syscon_node_to_regmap(node); |
204 | if (IS_ERR(regmap_st)) | 204 | if (IS_ERR(regmap_st)) { |
205 | panic(pr_fmt("Unable to get regmap\n")); | 205 | pr_err("Unable to get regmap\n"); |
206 | return PTR_ERR(regmap_st); | ||
207 | } | ||
206 | 208 | ||
207 | /* Disable all timer interrupts, and clear any pending ones */ | 209 | /* Disable all timer interrupts, and clear any pending ones */ |
208 | regmap_write(regmap_st, AT91_ST_IDR, | 210 | regmap_write(regmap_st, AT91_ST_IDR, |
@@ -211,27 +213,37 @@ static void __init atmel_st_timer_init(struct device_node *node) | |||
211 | 213 | ||
212 | /* Get the interrupts property */ | 214 | /* Get the interrupts property */ |
213 | irq = irq_of_parse_and_map(node, 0); | 215 | irq = irq_of_parse_and_map(node, 0); |
214 | if (!irq) | 216 | if (!irq) { |
215 | panic(pr_fmt("Unable to get IRQ from DT\n")); | 217 | pr_err("Unable to get IRQ from DT\n"); |
218 | return -EINVAL; | ||
219 | } | ||
216 | 220 | ||
217 | /* Make IRQs happen for the system timer */ | 221 | /* Make IRQs happen for the system timer */ |
218 | ret = request_irq(irq, at91rm9200_timer_interrupt, | 222 | ret = request_irq(irq, at91rm9200_timer_interrupt, |
219 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, | 223 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, |
220 | "at91_tick", regmap_st); | 224 | "at91_tick", regmap_st); |
221 | if (ret) | 225 | if (ret) { |
222 | panic(pr_fmt("Unable to setup IRQ\n")); | 226 | pr_err("Unable to setup IRQ\n"); |
227 | return ret; | ||
228 | } | ||
223 | 229 | ||
224 | sclk = of_clk_get(node, 0); | 230 | sclk = of_clk_get(node, 0); |
225 | if (IS_ERR(sclk)) | 231 | if (IS_ERR(sclk)) { |
226 | panic(pr_fmt("Unable to get slow clock\n")); | 232 | pr_err("Unable to get slow clock\n"); |
233 | return PTR_ERR(sclk); | ||
234 | } | ||
227 | 235 | ||
228 | clk_prepare_enable(sclk); | 236 | ret = clk_prepare_enable(sclk); |
229 | if (ret) | 237 | if (ret) { |
230 | panic(pr_fmt("Could not enable slow clock\n")); | 238 | pr_err("Could not enable slow clock\n"); |
239 | return ret; | ||
240 | } | ||
231 | 241 | ||
232 | sclk_rate = clk_get_rate(sclk); | 242 | sclk_rate = clk_get_rate(sclk); |
233 | if (!sclk_rate) | 243 | if (!sclk_rate) { |
234 | panic(pr_fmt("Invalid slow clock rate\n")); | 244 | pr_err("Invalid slow clock rate\n"); |
245 | return -EINVAL; | ||
246 | } | ||
235 | timer_latch = (sclk_rate + HZ / 2) / HZ; | 247 | timer_latch = (sclk_rate + HZ / 2) / HZ; |
236 | 248 | ||
237 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used | 249 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used |
@@ -246,7 +258,7 @@ static void __init atmel_st_timer_init(struct device_node *node) | |||
246 | 2, AT91_ST_ALMV); | 258 | 2, AT91_ST_ALMV); |
247 | 259 | ||
248 | /* register clocksource */ | 260 | /* register clocksource */ |
249 | clocksource_register_hz(&clk32k, sclk_rate); | 261 | return clocksource_register_hz(&clk32k, sclk_rate); |
250 | } | 262 | } |
251 | CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st", | 263 | CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st", |
252 | atmel_st_timer_init); | 264 | atmel_st_timer_init); |
diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c index a536eeb634d8..10318cc99c0e 100644 --- a/drivers/clocksource/timer-digicolor.c +++ b/drivers/clocksource/timer-digicolor.c | |||
@@ -63,7 +63,7 @@ struct digicolor_timer { | |||
63 | int timer_id; /* one of TIMER_* */ | 63 | int timer_id; /* one of TIMER_* */ |
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct digicolor_timer *dc_timer(struct clock_event_device *ce) | 66 | static struct digicolor_timer *dc_timer(struct clock_event_device *ce) |
67 | { | 67 | { |
68 | return container_of(ce, struct digicolor_timer, ce); | 68 | return container_of(ce, struct digicolor_timer, ce); |
69 | } | 69 | } |
@@ -148,7 +148,7 @@ static u64 notrace digicolor_timer_sched_read(void) | |||
148 | return ~readl(dc_timer_dev.base + COUNT(TIMER_B)); | 148 | return ~readl(dc_timer_dev.base + COUNT(TIMER_B)); |
149 | } | 149 | } |
150 | 150 | ||
151 | static void __init digicolor_timer_init(struct device_node *node) | 151 | static int __init digicolor_timer_init(struct device_node *node) |
152 | { | 152 | { |
153 | unsigned long rate; | 153 | unsigned long rate; |
154 | struct clk *clk; | 154 | struct clk *clk; |
@@ -161,19 +161,19 @@ static void __init digicolor_timer_init(struct device_node *node) | |||
161 | dc_timer_dev.base = of_iomap(node, 0); | 161 | dc_timer_dev.base = of_iomap(node, 0); |
162 | if (!dc_timer_dev.base) { | 162 | if (!dc_timer_dev.base) { |
163 | pr_err("Can't map registers"); | 163 | pr_err("Can't map registers"); |
164 | return; | 164 | return -ENXIO; |
165 | } | 165 | } |
166 | 166 | ||
167 | irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id); | 167 | irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id); |
168 | if (irq <= 0) { | 168 | if (irq <= 0) { |
169 | pr_err("Can't parse IRQ"); | 169 | pr_err("Can't parse IRQ"); |
170 | return; | 170 | return -EINVAL; |
171 | } | 171 | } |
172 | 172 | ||
173 | clk = of_clk_get(node, 0); | 173 | clk = of_clk_get(node, 0); |
174 | if (IS_ERR(clk)) { | 174 | if (IS_ERR(clk)) { |
175 | pr_err("Can't get timer clock"); | 175 | pr_err("Can't get timer clock"); |
176 | return; | 176 | return PTR_ERR(clk); |
177 | } | 177 | } |
178 | clk_prepare_enable(clk); | 178 | clk_prepare_enable(clk); |
179 | rate = clk_get_rate(clk); | 179 | rate = clk_get_rate(clk); |
@@ -190,13 +190,17 @@ static void __init digicolor_timer_init(struct device_node *node) | |||
190 | ret = request_irq(irq, digicolor_timer_interrupt, | 190 | ret = request_irq(irq, digicolor_timer_interrupt, |
191 | IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC", | 191 | IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC", |
192 | &dc_timer_dev.ce); | 192 | &dc_timer_dev.ce); |
193 | if (ret) | 193 | if (ret) { |
194 | pr_warn("request of timer irq %d failed (%d)\n", irq, ret); | 194 | pr_warn("request of timer irq %d failed (%d)\n", irq, ret); |
195 | return ret; | ||
196 | } | ||
195 | 197 | ||
196 | dc_timer_dev.ce.cpumask = cpu_possible_mask; | 198 | dc_timer_dev.ce.cpumask = cpu_possible_mask; |
197 | dc_timer_dev.ce.irq = irq; | 199 | dc_timer_dev.ce.irq = irq; |
198 | 200 | ||
199 | clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff); | 201 | clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff); |
202 | |||
203 | return 0; | ||
200 | } | 204 | } |
201 | CLOCKSOURCE_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer", | 205 | CLOCKSOURCE_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer", |
202 | digicolor_timer_init); | 206 | digicolor_timer_init); |
diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c index 99ec96769dda..f595460bfc58 100644 --- a/drivers/clocksource/timer-imx-gpt.c +++ b/drivers/clocksource/timer-imx-gpt.c | |||
@@ -407,8 +407,10 @@ static const struct imx_gpt_data imx6dl_gpt_data = { | |||
407 | .set_next_event = v2_set_next_event, | 407 | .set_next_event = v2_set_next_event, |
408 | }; | 408 | }; |
409 | 409 | ||
410 | static void __init _mxc_timer_init(struct imx_timer *imxtm) | 410 | static int __init _mxc_timer_init(struct imx_timer *imxtm) |
411 | { | 411 | { |
412 | int ret; | ||
413 | |||
412 | switch (imxtm->type) { | 414 | switch (imxtm->type) { |
413 | case GPT_TYPE_IMX1: | 415 | case GPT_TYPE_IMX1: |
414 | imxtm->gpt = &imx1_gpt_data; | 416 | imxtm->gpt = &imx1_gpt_data; |
@@ -423,12 +425,12 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm) | |||
423 | imxtm->gpt = &imx6dl_gpt_data; | 425 | imxtm->gpt = &imx6dl_gpt_data; |
424 | break; | 426 | break; |
425 | default: | 427 | default: |
426 | BUG(); | 428 | return -EINVAL; |
427 | } | 429 | } |
428 | 430 | ||
429 | if (IS_ERR(imxtm->clk_per)) { | 431 | if (IS_ERR(imxtm->clk_per)) { |
430 | pr_err("i.MX timer: unable to get clk\n"); | 432 | pr_err("i.MX timer: unable to get clk\n"); |
431 | return; | 433 | return PTR_ERR(imxtm->clk_per); |
432 | } | 434 | } |
433 | 435 | ||
434 | if (!IS_ERR(imxtm->clk_ipg)) | 436 | if (!IS_ERR(imxtm->clk_ipg)) |
@@ -446,8 +448,11 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm) | |||
446 | imxtm->gpt->gpt_setup_tctl(imxtm); | 448 | imxtm->gpt->gpt_setup_tctl(imxtm); |
447 | 449 | ||
448 | /* init and register the timer to the framework */ | 450 | /* init and register the timer to the framework */ |
449 | mxc_clocksource_init(imxtm); | 451 | ret = mxc_clocksource_init(imxtm); |
450 | mxc_clockevent_init(imxtm); | 452 | if (ret) |
453 | return ret; | ||
454 | |||
455 | return mxc_clockevent_init(imxtm); | ||
451 | } | 456 | } |
452 | 457 | ||
453 | void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) | 458 | void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) |
@@ -469,21 +474,27 @@ void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type) | |||
469 | _mxc_timer_init(imxtm); | 474 | _mxc_timer_init(imxtm); |
470 | } | 475 | } |
471 | 476 | ||
472 | static void __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type type) | 477 | static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type type) |
473 | { | 478 | { |
474 | struct imx_timer *imxtm; | 479 | struct imx_timer *imxtm; |
475 | static int initialized; | 480 | static int initialized; |
481 | int ret; | ||
476 | 482 | ||
477 | /* Support one instance only */ | 483 | /* Support one instance only */ |
478 | if (initialized) | 484 | if (initialized) |
479 | return; | 485 | return 0; |
480 | 486 | ||
481 | imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); | 487 | imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); |
482 | BUG_ON(!imxtm); | 488 | if (!imxtm) |
489 | return -ENOMEM; | ||
483 | 490 | ||
484 | imxtm->base = of_iomap(np, 0); | 491 | imxtm->base = of_iomap(np, 0); |
485 | WARN_ON(!imxtm->base); | 492 | if (!imxtm->base) |
493 | return -ENXIO; | ||
494 | |||
486 | imxtm->irq = irq_of_parse_and_map(np, 0); | 495 | imxtm->irq = irq_of_parse_and_map(np, 0); |
496 | if (imxtm->irq <= 0) | ||
497 | return -EINVAL; | ||
487 | 498 | ||
488 | imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); | 499 | imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); |
489 | 500 | ||
@@ -494,22 +505,26 @@ static void __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type | |||
494 | 505 | ||
495 | imxtm->type = type; | 506 | imxtm->type = type; |
496 | 507 | ||
497 | _mxc_timer_init(imxtm); | 508 | ret = _mxc_timer_init(imxtm); |
509 | if (ret) | ||
510 | return ret; | ||
498 | 511 | ||
499 | initialized = 1; | 512 | initialized = 1; |
513 | |||
514 | return 0; | ||
500 | } | 515 | } |
501 | 516 | ||
502 | static void __init imx1_timer_init_dt(struct device_node *np) | 517 | static int __init imx1_timer_init_dt(struct device_node *np) |
503 | { | 518 | { |
504 | mxc_timer_init_dt(np, GPT_TYPE_IMX1); | 519 | return mxc_timer_init_dt(np, GPT_TYPE_IMX1); |
505 | } | 520 | } |
506 | 521 | ||
507 | static void __init imx21_timer_init_dt(struct device_node *np) | 522 | static int __init imx21_timer_init_dt(struct device_node *np) |
508 | { | 523 | { |
509 | mxc_timer_init_dt(np, GPT_TYPE_IMX21); | 524 | return mxc_timer_init_dt(np, GPT_TYPE_IMX21); |
510 | } | 525 | } |
511 | 526 | ||
512 | static void __init imx31_timer_init_dt(struct device_node *np) | 527 | static int __init imx31_timer_init_dt(struct device_node *np) |
513 | { | 528 | { |
514 | enum imx_gpt_type type = GPT_TYPE_IMX31; | 529 | enum imx_gpt_type type = GPT_TYPE_IMX31; |
515 | 530 | ||
@@ -522,12 +537,12 @@ static void __init imx31_timer_init_dt(struct device_node *np) | |||
522 | if (of_machine_is_compatible("fsl,imx6dl")) | 537 | if (of_machine_is_compatible("fsl,imx6dl")) |
523 | type = GPT_TYPE_IMX6DL; | 538 | type = GPT_TYPE_IMX6DL; |
524 | 539 | ||
525 | mxc_timer_init_dt(np, type); | 540 | return mxc_timer_init_dt(np, type); |
526 | } | 541 | } |
527 | 542 | ||
528 | static void __init imx6dl_timer_init_dt(struct device_node *np) | 543 | static int __init imx6dl_timer_init_dt(struct device_node *np) |
529 | { | 544 | { |
530 | mxc_timer_init_dt(np, GPT_TYPE_IMX6DL); | 545 | return mxc_timer_init_dt(np, GPT_TYPE_IMX6DL); |
531 | } | 546 | } |
532 | 547 | ||
533 | CLOCKSOURCE_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt); | 548 | CLOCKSOURCE_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt); |
diff --git a/drivers/clocksource/timer-integrator-ap.c b/drivers/clocksource/timer-integrator-ap.c index 3f59ac2180dc..df6e672afc04 100644 --- a/drivers/clocksource/timer-integrator-ap.c +++ b/drivers/clocksource/timer-integrator-ap.c | |||
@@ -36,11 +36,12 @@ static u64 notrace integrator_read_sched_clock(void) | |||
36 | return -readl(sched_clk_base + TIMER_VALUE); | 36 | return -readl(sched_clk_base + TIMER_VALUE); |
37 | } | 37 | } |
38 | 38 | ||
39 | static void integrator_clocksource_init(unsigned long inrate, | 39 | static int integrator_clocksource_init(unsigned long inrate, |
40 | void __iomem *base) | 40 | void __iomem *base) |
41 | { | 41 | { |
42 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; | 42 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; |
43 | unsigned long rate = inrate; | 43 | unsigned long rate = inrate; |
44 | int ret; | ||
44 | 45 | ||
45 | if (rate >= 1500000) { | 46 | if (rate >= 1500000) { |
46 | rate /= 16; | 47 | rate /= 16; |
@@ -50,11 +51,15 @@ static void integrator_clocksource_init(unsigned long inrate, | |||
50 | writel(0xffff, base + TIMER_LOAD); | 51 | writel(0xffff, base + TIMER_LOAD); |
51 | writel(ctrl, base + TIMER_CTRL); | 52 | writel(ctrl, base + TIMER_CTRL); |
52 | 53 | ||
53 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", | 54 | ret = clocksource_mmio_init(base + TIMER_VALUE, "timer2", |
54 | rate, 200, 16, clocksource_mmio_readl_down); | 55 | rate, 200, 16, clocksource_mmio_readl_down); |
56 | if (ret) | ||
57 | return ret; | ||
55 | 58 | ||
56 | sched_clk_base = base; | 59 | sched_clk_base = base; |
57 | sched_clock_register(integrator_read_sched_clock, 16, rate); | 60 | sched_clock_register(integrator_read_sched_clock, 16, rate); |
61 | |||
62 | return 0; | ||
58 | } | 63 | } |
59 | 64 | ||
60 | static unsigned long timer_reload; | 65 | static unsigned long timer_reload; |
@@ -138,11 +143,12 @@ static struct irqaction integrator_timer_irq = { | |||
138 | .dev_id = &integrator_clockevent, | 143 | .dev_id = &integrator_clockevent, |
139 | }; | 144 | }; |
140 | 145 | ||
141 | static void integrator_clockevent_init(unsigned long inrate, | 146 | static int integrator_clockevent_init(unsigned long inrate, |
142 | void __iomem *base, int irq) | 147 | void __iomem *base, int irq) |
143 | { | 148 | { |
144 | unsigned long rate = inrate; | 149 | unsigned long rate = inrate; |
145 | unsigned int ctrl = 0; | 150 | unsigned int ctrl = 0; |
151 | int ret; | ||
146 | 152 | ||
147 | clkevt_base = base; | 153 | clkevt_base = base; |
148 | /* Calculate and program a divisor */ | 154 | /* Calculate and program a divisor */ |
@@ -156,14 +162,18 @@ static void integrator_clockevent_init(unsigned long inrate, | |||
156 | timer_reload = rate / HZ; | 162 | timer_reload = rate / HZ; |
157 | writel(ctrl, clkevt_base + TIMER_CTRL); | 163 | writel(ctrl, clkevt_base + TIMER_CTRL); |
158 | 164 | ||
159 | setup_irq(irq, &integrator_timer_irq); | 165 | ret = setup_irq(irq, &integrator_timer_irq); |
166 | if (ret) | ||
167 | return ret; | ||
168 | |||
160 | clockevents_config_and_register(&integrator_clockevent, | 169 | clockevents_config_and_register(&integrator_clockevent, |
161 | rate, | 170 | rate, |
162 | 1, | 171 | 1, |
163 | 0xffffU); | 172 | 0xffffU); |
173 | return 0; | ||
164 | } | 174 | } |
165 | 175 | ||
166 | static void __init integrator_ap_timer_init_of(struct device_node *node) | 176 | static int __init integrator_ap_timer_init_of(struct device_node *node) |
167 | { | 177 | { |
168 | const char *path; | 178 | const char *path; |
169 | void __iomem *base; | 179 | void __iomem *base; |
@@ -176,12 +186,12 @@ static void __init integrator_ap_timer_init_of(struct device_node *node) | |||
176 | 186 | ||
177 | base = of_io_request_and_map(node, 0, "integrator-timer"); | 187 | base = of_io_request_and_map(node, 0, "integrator-timer"); |
178 | if (IS_ERR(base)) | 188 | if (IS_ERR(base)) |
179 | return; | 189 | return PTR_ERR(base); |
180 | 190 | ||
181 | clk = of_clk_get(node, 0); | 191 | clk = of_clk_get(node, 0); |
182 | if (IS_ERR(clk)) { | 192 | if (IS_ERR(clk)) { |
183 | pr_err("No clock for %s\n", node->name); | 193 | pr_err("No clock for %s\n", node->name); |
184 | return; | 194 | return PTR_ERR(clk); |
185 | } | 195 | } |
186 | clk_prepare_enable(clk); | 196 | clk_prepare_enable(clk); |
187 | rate = clk_get_rate(clk); | 197 | rate = clk_get_rate(clk); |
@@ -189,30 +199,37 @@ static void __init integrator_ap_timer_init_of(struct device_node *node) | |||
189 | 199 | ||
190 | err = of_property_read_string(of_aliases, | 200 | err = of_property_read_string(of_aliases, |
191 | "arm,timer-primary", &path); | 201 | "arm,timer-primary", &path); |
192 | if (WARN_ON(err)) | 202 | if (err) { |
193 | return; | 203 | pr_warn("Failed to read property"); |
204 | return err; | ||
205 | } | ||
206 | |||
194 | pri_node = of_find_node_by_path(path); | 207 | pri_node = of_find_node_by_path(path); |
208 | |||
195 | err = of_property_read_string(of_aliases, | 209 | err = of_property_read_string(of_aliases, |
196 | "arm,timer-secondary", &path); | 210 | "arm,timer-secondary", &path); |
197 | if (WARN_ON(err)) | 211 | if (err) { |
198 | return; | 212 | pr_warn("Failed to read property"); |
213 | return err; | ||
214 | } | ||
215 | |||
216 | |||
199 | sec_node = of_find_node_by_path(path); | 217 | sec_node = of_find_node_by_path(path); |
200 | 218 | ||
201 | if (node == pri_node) { | 219 | if (node == pri_node) |
202 | /* The primary timer lacks IRQ, use as clocksource */ | 220 | /* The primary timer lacks IRQ, use as clocksource */ |
203 | integrator_clocksource_init(rate, base); | 221 | return integrator_clocksource_init(rate, base); |
204 | return; | ||
205 | } | ||
206 | 222 | ||
207 | if (node == sec_node) { | 223 | if (node == sec_node) { |
208 | /* The secondary timer will drive the clock event */ | 224 | /* The secondary timer will drive the clock event */ |
209 | irq = irq_of_parse_and_map(node, 0); | 225 | irq = irq_of_parse_and_map(node, 0); |
210 | integrator_clockevent_init(rate, base, irq); | 226 | return integrator_clockevent_init(rate, base, irq); |
211 | return; | ||
212 | } | 227 | } |
213 | 228 | ||
214 | pr_info("Timer @%p unused\n", base); | 229 | pr_info("Timer @%p unused\n", base); |
215 | clk_disable_unprepare(clk); | 230 | clk_disable_unprepare(clk); |
231 | |||
232 | return 0; | ||
216 | } | 233 | } |
217 | 234 | ||
218 | CLOCKSOURCE_OF_DECLARE(integrator_ap_timer, "arm,integrator-timer", | 235 | CLOCKSOURCE_OF_DECLARE(integrator_ap_timer, "arm,integrator-timer", |
diff --git a/drivers/clocksource/timer-keystone.c b/drivers/clocksource/timer-keystone.c index 1cea08cf603e..ab68a47ab3b4 100644 --- a/drivers/clocksource/timer-keystone.c +++ b/drivers/clocksource/timer-keystone.c | |||
@@ -144,7 +144,7 @@ static int keystone_set_periodic(struct clock_event_device *evt) | |||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
146 | 146 | ||
147 | static void __init keystone_timer_init(struct device_node *np) | 147 | static int __init keystone_timer_init(struct device_node *np) |
148 | { | 148 | { |
149 | struct clock_event_device *event_dev = &timer.event_dev; | 149 | struct clock_event_device *event_dev = &timer.event_dev; |
150 | unsigned long rate; | 150 | unsigned long rate; |
@@ -154,20 +154,20 @@ static void __init keystone_timer_init(struct device_node *np) | |||
154 | irq = irq_of_parse_and_map(np, 0); | 154 | irq = irq_of_parse_and_map(np, 0); |
155 | if (!irq) { | 155 | if (!irq) { |
156 | pr_err("%s: failed to map interrupts\n", __func__); | 156 | pr_err("%s: failed to map interrupts\n", __func__); |
157 | return; | 157 | return -EINVAL; |
158 | } | 158 | } |
159 | 159 | ||
160 | timer.base = of_iomap(np, 0); | 160 | timer.base = of_iomap(np, 0); |
161 | if (!timer.base) { | 161 | if (!timer.base) { |
162 | pr_err("%s: failed to map registers\n", __func__); | 162 | pr_err("%s: failed to map registers\n", __func__); |
163 | return; | 163 | return -ENXIO; |
164 | } | 164 | } |
165 | 165 | ||
166 | clk = of_clk_get(np, 0); | 166 | clk = of_clk_get(np, 0); |
167 | if (IS_ERR(clk)) { | 167 | if (IS_ERR(clk)) { |
168 | pr_err("%s: failed to get clock\n", __func__); | 168 | pr_err("%s: failed to get clock\n", __func__); |
169 | iounmap(timer.base); | 169 | iounmap(timer.base); |
170 | return; | 170 | return PTR_ERR(clk); |
171 | } | 171 | } |
172 | 172 | ||
173 | error = clk_prepare_enable(clk); | 173 | error = clk_prepare_enable(clk); |
@@ -219,11 +219,12 @@ static void __init keystone_timer_init(struct device_node *np) | |||
219 | clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX); | 219 | clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX); |
220 | 220 | ||
221 | pr_info("keystone timer clock @%lu Hz\n", rate); | 221 | pr_info("keystone timer clock @%lu Hz\n", rate); |
222 | return; | 222 | return 0; |
223 | err: | 223 | err: |
224 | clk_put(clk); | 224 | clk_put(clk); |
225 | iounmap(timer.base); | 225 | iounmap(timer.base); |
226 | return error; | ||
226 | } | 227 | } |
227 | 228 | ||
228 | CLOCKSOURCE_OF_DECLARE(keystone_timer, "ti,keystone-timer", | 229 | CLOCKSOURCE_OF_DECLARE(keystone_timer, "ti,keystone-timer", |
229 | keystone_timer_init); | 230 | keystone_timer_init); |
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c index d46108920b2c..70c149af8ee0 100644 --- a/drivers/clocksource/timer-nps.c +++ b/drivers/clocksource/timer-nps.c | |||
@@ -55,8 +55,8 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc) | |||
55 | return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]); | 55 | return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void __init nps_setup_clocksource(struct device_node *node, | 58 | static int __init nps_setup_clocksource(struct device_node *node, |
59 | struct clk *clk) | 59 | struct clk *clk) |
60 | { | 60 | { |
61 | int ret, cluster; | 61 | int ret, cluster; |
62 | 62 | ||
@@ -68,7 +68,7 @@ static void __init nps_setup_clocksource(struct device_node *node, | |||
68 | ret = clk_prepare_enable(clk); | 68 | ret = clk_prepare_enable(clk); |
69 | if (ret) { | 69 | if (ret) { |
70 | pr_err("Couldn't enable parent clock\n"); | 70 | pr_err("Couldn't enable parent clock\n"); |
71 | return; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
74 | nps_timer_rate = clk_get_rate(clk); | 74 | nps_timer_rate = clk_get_rate(clk); |
@@ -79,19 +79,21 @@ static void __init nps_setup_clocksource(struct device_node *node, | |||
79 | pr_err("Couldn't register clock source.\n"); | 79 | pr_err("Couldn't register clock source.\n"); |
80 | clk_disable_unprepare(clk); | 80 | clk_disable_unprepare(clk); |
81 | } | 81 | } |
82 | |||
83 | return ret; | ||
82 | } | 84 | } |
83 | 85 | ||
84 | static void __init nps_timer_init(struct device_node *node) | 86 | static int __init nps_timer_init(struct device_node *node) |
85 | { | 87 | { |
86 | struct clk *clk; | 88 | struct clk *clk; |
87 | 89 | ||
88 | clk = of_clk_get(node, 0); | 90 | clk = of_clk_get(node, 0); |
89 | if (IS_ERR(clk)) { | 91 | if (IS_ERR(clk)) { |
90 | pr_err("Can't get timer clock.\n"); | 92 | pr_err("Can't get timer clock.\n"); |
91 | return; | 93 | return PTR_ERR(clk); |
92 | } | 94 | } |
93 | 95 | ||
94 | nps_setup_clocksource(node, clk); | 96 | return nps_setup_clocksource(node, clk); |
95 | } | 97 | } |
96 | 98 | ||
97 | CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer", | 99 | CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer", |
diff --git a/drivers/clocksource/timer-oxnas-rps.c b/drivers/clocksource/timer-oxnas-rps.c new file mode 100644 index 000000000000..bd887e2a8cf8 --- /dev/null +++ b/drivers/clocksource/timer-oxnas-rps.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * drivers/clocksource/timer-oxnas-rps.c | ||
3 | * | ||
4 | * Copyright (C) 2009 Oxford Semiconductor Ltd | ||
5 | * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com> | ||
6 | * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/of_irq.h> | ||
30 | #include <linux/of_address.h> | ||
31 | #include <linux/clockchips.h> | ||
32 | #include <linux/sched_clock.h> | ||
33 | |||
34 | /* TIMER1 used as tick | ||
35 | * TIMER2 used as clocksource | ||
36 | */ | ||
37 | |||
38 | /* Registers definitions */ | ||
39 | |||
40 | #define TIMER_LOAD_REG 0x0 | ||
41 | #define TIMER_CURR_REG 0x4 | ||
42 | #define TIMER_CTRL_REG 0x8 | ||
43 | #define TIMER_CLRINT_REG 0xC | ||
44 | |||
45 | #define TIMER_BITS 24 | ||
46 | |||
47 | #define TIMER_MAX_VAL (BIT(TIMER_BITS) - 1) | ||
48 | |||
49 | #define TIMER_PERIODIC BIT(6) | ||
50 | #define TIMER_ENABLE BIT(7) | ||
51 | |||
52 | #define TIMER_DIV1 (0) | ||
53 | #define TIMER_DIV16 (1 << 2) | ||
54 | #define TIMER_DIV256 (2 << 2) | ||
55 | |||
56 | #define TIMER1_REG_OFFSET 0 | ||
57 | #define TIMER2_REG_OFFSET 0x20 | ||
58 | |||
59 | /* Clockevent & Clocksource data */ | ||
60 | |||
61 | struct oxnas_rps_timer { | ||
62 | struct clock_event_device clkevent; | ||
63 | void __iomem *clksrc_base; | ||
64 | void __iomem *clkevt_base; | ||
65 | unsigned long timer_period; | ||
66 | unsigned int timer_prescaler; | ||
67 | struct clk *clk; | ||
68 | int irq; | ||
69 | }; | ||
70 | |||
71 | static irqreturn_t oxnas_rps_timer_irq(int irq, void *dev_id) | ||
72 | { | ||
73 | struct oxnas_rps_timer *rps = dev_id; | ||
74 | |||
75 | writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG); | ||
76 | |||
77 | rps->clkevent.event_handler(&rps->clkevent); | ||
78 | |||
79 | return IRQ_HANDLED; | ||
80 | } | ||
81 | |||
82 | static void oxnas_rps_timer_config(struct oxnas_rps_timer *rps, | ||
83 | unsigned long period, | ||
84 | unsigned int periodic) | ||
85 | { | ||
86 | uint32_t cfg = rps->timer_prescaler; | ||
87 | |||
88 | if (period) | ||
89 | cfg |= TIMER_ENABLE; | ||
90 | |||
91 | if (periodic) | ||
92 | cfg |= TIMER_PERIODIC; | ||
93 | |||
94 | writel_relaxed(period, rps->clkevt_base + TIMER_LOAD_REG); | ||
95 | writel_relaxed(cfg, rps->clkevt_base + TIMER_CTRL_REG); | ||
96 | } | ||
97 | |||
98 | static int oxnas_rps_timer_shutdown(struct clock_event_device *evt) | ||
99 | { | ||
100 | struct oxnas_rps_timer *rps = | ||
101 | container_of(evt, struct oxnas_rps_timer, clkevent); | ||
102 | |||
103 | oxnas_rps_timer_config(rps, 0, 0); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int oxnas_rps_timer_set_periodic(struct clock_event_device *evt) | ||
109 | { | ||
110 | struct oxnas_rps_timer *rps = | ||
111 | container_of(evt, struct oxnas_rps_timer, clkevent); | ||
112 | |||
113 | oxnas_rps_timer_config(rps, rps->timer_period, 1); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int oxnas_rps_timer_set_oneshot(struct clock_event_device *evt) | ||
119 | { | ||
120 | struct oxnas_rps_timer *rps = | ||
121 | container_of(evt, struct oxnas_rps_timer, clkevent); | ||
122 | |||
123 | oxnas_rps_timer_config(rps, rps->timer_period, 0); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int oxnas_rps_timer_next_event(unsigned long delta, | ||
129 | struct clock_event_device *evt) | ||
130 | { | ||
131 | struct oxnas_rps_timer *rps = | ||
132 | container_of(evt, struct oxnas_rps_timer, clkevent); | ||
133 | |||
134 | oxnas_rps_timer_config(rps, delta, 0); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int __init oxnas_rps_clockevent_init(struct oxnas_rps_timer *rps) | ||
140 | { | ||
141 | ulong clk_rate = clk_get_rate(rps->clk); | ||
142 | ulong timer_rate; | ||
143 | |||
144 | /* Start with prescaler 1 */ | ||
145 | rps->timer_prescaler = TIMER_DIV1; | ||
146 | rps->timer_period = DIV_ROUND_UP(clk_rate, HZ); | ||
147 | timer_rate = clk_rate; | ||
148 | |||
149 | if (rps->timer_period > TIMER_MAX_VAL) { | ||
150 | rps->timer_prescaler = TIMER_DIV16; | ||
151 | timer_rate = clk_rate / 16; | ||
152 | rps->timer_period = DIV_ROUND_UP(timer_rate, HZ); | ||
153 | } | ||
154 | if (rps->timer_period > TIMER_MAX_VAL) { | ||
155 | rps->timer_prescaler = TIMER_DIV256; | ||
156 | timer_rate = clk_rate / 256; | ||
157 | rps->timer_period = DIV_ROUND_UP(timer_rate, HZ); | ||
158 | } | ||
159 | |||
160 | rps->clkevent.name = "oxnas-rps"; | ||
161 | rps->clkevent.features = CLOCK_EVT_FEAT_PERIODIC | | ||
162 | CLOCK_EVT_FEAT_ONESHOT | | ||
163 | CLOCK_EVT_FEAT_DYNIRQ; | ||
164 | rps->clkevent.tick_resume = oxnas_rps_timer_shutdown; | ||
165 | rps->clkevent.set_state_shutdown = oxnas_rps_timer_shutdown; | ||
166 | rps->clkevent.set_state_periodic = oxnas_rps_timer_set_periodic; | ||
167 | rps->clkevent.set_state_oneshot = oxnas_rps_timer_set_oneshot; | ||
168 | rps->clkevent.set_next_event = oxnas_rps_timer_next_event; | ||
169 | rps->clkevent.rating = 200; | ||
170 | rps->clkevent.cpumask = cpu_possible_mask; | ||
171 | rps->clkevent.irq = rps->irq; | ||
172 | clockevents_config_and_register(&rps->clkevent, | ||
173 | timer_rate, | ||
174 | 1, | ||
175 | TIMER_MAX_VAL); | ||
176 | |||
177 | pr_info("Registered clock event rate %luHz prescaler %x period %lu\n", | ||
178 | clk_rate, | ||
179 | rps->timer_prescaler, | ||
180 | rps->timer_period); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /* Clocksource */ | ||
186 | |||
187 | static void __iomem *timer_sched_base; | ||
188 | |||
189 | static u64 notrace oxnas_rps_read_sched_clock(void) | ||
190 | { | ||
191 | return ~readl_relaxed(timer_sched_base); | ||
192 | } | ||
193 | |||
194 | static int __init oxnas_rps_clocksource_init(struct oxnas_rps_timer *rps) | ||
195 | { | ||
196 | ulong clk_rate = clk_get_rate(rps->clk); | ||
197 | int ret; | ||
198 | |||
199 | /* use prescale 16 */ | ||
200 | clk_rate = clk_rate / 16; | ||
201 | |||
202 | writel_relaxed(TIMER_MAX_VAL, rps->clksrc_base + TIMER_LOAD_REG); | ||
203 | writel_relaxed(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16, | ||
204 | rps->clksrc_base + TIMER_CTRL_REG); | ||
205 | |||
206 | timer_sched_base = rps->clksrc_base + TIMER_CURR_REG; | ||
207 | sched_clock_register(oxnas_rps_read_sched_clock, | ||
208 | TIMER_BITS, clk_rate); | ||
209 | ret = clocksource_mmio_init(timer_sched_base, | ||
210 | "oxnas_rps_clocksource_timer", | ||
211 | clk_rate, 250, TIMER_BITS, | ||
212 | clocksource_mmio_readl_down); | ||
213 | if (WARN_ON(ret)) { | ||
214 | pr_err("can't register clocksource\n"); | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | pr_info("Registered clocksource rate %luHz\n", clk_rate); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int __init oxnas_rps_timer_init(struct device_node *np) | ||
224 | { | ||
225 | struct oxnas_rps_timer *rps; | ||
226 | void __iomem *base; | ||
227 | int ret; | ||
228 | |||
229 | rps = kzalloc(sizeof(*rps), GFP_KERNEL); | ||
230 | if (!rps) | ||
231 | return -ENOMEM; | ||
232 | |||
233 | rps->clk = of_clk_get(np, 0); | ||
234 | if (IS_ERR(rps->clk)) { | ||
235 | ret = PTR_ERR(rps->clk); | ||
236 | goto err_alloc; | ||
237 | } | ||
238 | |||
239 | ret = clk_prepare_enable(rps->clk); | ||
240 | if (ret) | ||
241 | goto err_clk; | ||
242 | |||
243 | base = of_iomap(np, 0); | ||
244 | if (!base) { | ||
245 | ret = -ENXIO; | ||
246 | goto err_clk_prepare; | ||
247 | } | ||
248 | |||
249 | rps->irq = irq_of_parse_and_map(np, 0); | ||
250 | if (rps->irq < 0) { | ||
251 | ret = -EINVAL; | ||
252 | goto err_iomap; | ||
253 | } | ||
254 | |||
255 | rps->clkevt_base = base + TIMER1_REG_OFFSET; | ||
256 | rps->clksrc_base = base + TIMER2_REG_OFFSET; | ||
257 | |||
258 | /* Disable timers */ | ||
259 | writel_relaxed(0, rps->clkevt_base + TIMER_CTRL_REG); | ||
260 | writel_relaxed(0, rps->clksrc_base + TIMER_CTRL_REG); | ||
261 | writel_relaxed(0, rps->clkevt_base + TIMER_LOAD_REG); | ||
262 | writel_relaxed(0, rps->clksrc_base + TIMER_LOAD_REG); | ||
263 | writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG); | ||
264 | writel_relaxed(0, rps->clksrc_base + TIMER_CLRINT_REG); | ||
265 | |||
266 | ret = request_irq(rps->irq, oxnas_rps_timer_irq, | ||
267 | IRQF_TIMER | IRQF_IRQPOLL, | ||
268 | "rps-timer", rps); | ||
269 | if (ret) | ||
270 | goto err_iomap; | ||
271 | |||
272 | ret = oxnas_rps_clocksource_init(rps); | ||
273 | if (ret) | ||
274 | goto err_irqreq; | ||
275 | |||
276 | ret = oxnas_rps_clockevent_init(rps); | ||
277 | if (ret) | ||
278 | goto err_irqreq; | ||
279 | |||
280 | return 0; | ||
281 | |||
282 | err_irqreq: | ||
283 | free_irq(rps->irq, rps); | ||
284 | err_iomap: | ||
285 | iounmap(base); | ||
286 | err_clk_prepare: | ||
287 | clk_disable_unprepare(rps->clk); | ||
288 | err_clk: | ||
289 | clk_put(rps->clk); | ||
290 | err_alloc: | ||
291 | kfree(rps); | ||
292 | |||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | CLOCKSOURCE_OF_DECLARE(ox810se_rps, | ||
297 | "oxsemi,ox810se-rps-timer", oxnas_rps_timer_init); | ||
diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c index 2854c663e8b5..c32148ec7a38 100644 --- a/drivers/clocksource/timer-prima2.c +++ b/drivers/clocksource/timer-prima2.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
21 | #include <linux/sched_clock.h> | 21 | #include <linux/sched_clock.h> |
22 | #include <asm/mach/time.h> | ||
23 | 22 | ||
24 | #define PRIMA2_CLOCK_FREQ 1000000 | 23 | #define PRIMA2_CLOCK_FREQ 1000000 |
25 | 24 | ||
@@ -189,24 +188,36 @@ static void __init sirfsoc_clockevent_init(void) | |||
189 | } | 188 | } |
190 | 189 | ||
191 | /* initialize the kernel jiffy timer source */ | 190 | /* initialize the kernel jiffy timer source */ |
192 | static void __init sirfsoc_prima2_timer_init(struct device_node *np) | 191 | static int __init sirfsoc_prima2_timer_init(struct device_node *np) |
193 | { | 192 | { |
194 | unsigned long rate; | 193 | unsigned long rate; |
195 | struct clk *clk; | 194 | struct clk *clk; |
195 | int ret; | ||
196 | 196 | ||
197 | clk = of_clk_get(np, 0); | 197 | clk = of_clk_get(np, 0); |
198 | BUG_ON(IS_ERR(clk)); | 198 | if (IS_ERR(clk)) { |
199 | pr_err("Failed to get clock"); | ||
200 | return PTR_ERR(clk); | ||
201 | } | ||
199 | 202 | ||
200 | BUG_ON(clk_prepare_enable(clk)); | 203 | ret = clk_prepare_enable(clk); |
204 | if (ret) { | ||
205 | pr_err("Failed to enable clock"); | ||
206 | return ret; | ||
207 | } | ||
201 | 208 | ||
202 | rate = clk_get_rate(clk); | 209 | rate = clk_get_rate(clk); |
203 | 210 | ||
204 | BUG_ON(rate < PRIMA2_CLOCK_FREQ); | 211 | if (rate < PRIMA2_CLOCK_FREQ || rate % PRIMA2_CLOCK_FREQ) { |
205 | BUG_ON(rate % PRIMA2_CLOCK_FREQ); | 212 | pr_err("Invalid clock rate"); |
213 | return -EINVAL; | ||
214 | } | ||
206 | 215 | ||
207 | sirfsoc_timer_base = of_iomap(np, 0); | 216 | sirfsoc_timer_base = of_iomap(np, 0); |
208 | if (!sirfsoc_timer_base) | 217 | if (!sirfsoc_timer_base) { |
209 | panic("unable to map timer cpu registers\n"); | 218 | pr_err("unable to map timer cpu registers\n"); |
219 | return -ENXIO; | ||
220 | } | ||
210 | 221 | ||
211 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); | 222 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); |
212 | 223 | ||
@@ -216,14 +227,23 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
216 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 227 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); |
217 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); | 228 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); |
218 | 229 | ||
219 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, | 230 | ret = clocksource_register_hz(&sirfsoc_clocksource, PRIMA2_CLOCK_FREQ); |
220 | PRIMA2_CLOCK_FREQ)); | 231 | if (ret) { |
232 | pr_err("Failed to register clocksource"); | ||
233 | return ret; | ||
234 | } | ||
221 | 235 | ||
222 | sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ); | 236 | sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ); |
223 | 237 | ||
224 | BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); | 238 | ret = setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq); |
239 | if (ret) { | ||
240 | pr_err("Failed to setup irq"); | ||
241 | return ret; | ||
242 | } | ||
225 | 243 | ||
226 | sirfsoc_clockevent_init(); | 244 | sirfsoc_clockevent_init(); |
245 | |||
246 | return 0; | ||
227 | } | 247 | } |
228 | CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer, | 248 | CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer, |
229 | "sirf,prima2-tick", sirfsoc_prima2_timer_init); | 249 | "sirf,prima2-tick", sirfsoc_prima2_timer_init); |
diff --git a/drivers/clocksource/timer-sp804.c b/drivers/clocksource/timer-sp804.c index 5f45b9adef60..d07863388e05 100644 --- a/drivers/clocksource/timer-sp804.c +++ b/drivers/clocksource/timer-sp804.c | |||
@@ -77,7 +77,7 @@ void __init sp804_timer_disable(void __iomem *base) | |||
77 | writel(0, base + TIMER_CTRL); | 77 | writel(0, base + TIMER_CTRL); |
78 | } | 78 | } |
79 | 79 | ||
80 | void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, | 80 | int __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, |
81 | const char *name, | 81 | const char *name, |
82 | struct clk *clk, | 82 | struct clk *clk, |
83 | int use_sched_clock) | 83 | int use_sched_clock) |
@@ -89,14 +89,13 @@ void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, | |||
89 | if (IS_ERR(clk)) { | 89 | if (IS_ERR(clk)) { |
90 | pr_err("sp804: clock not found: %d\n", | 90 | pr_err("sp804: clock not found: %d\n", |
91 | (int)PTR_ERR(clk)); | 91 | (int)PTR_ERR(clk)); |
92 | return; | 92 | return PTR_ERR(clk); |
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | rate = sp804_get_clock_rate(clk); | 96 | rate = sp804_get_clock_rate(clk); |
97 | |||
98 | if (rate < 0) | 97 | if (rate < 0) |
99 | return; | 98 | return -EINVAL; |
100 | 99 | ||
101 | /* setup timer 0 as free-running clocksource */ | 100 | /* setup timer 0 as free-running clocksource */ |
102 | writel(0, base + TIMER_CTRL); | 101 | writel(0, base + TIMER_CTRL); |
@@ -112,6 +111,8 @@ void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, | |||
112 | sched_clock_base = base; | 111 | sched_clock_base = base; |
113 | sched_clock_register(sp804_read, 32, rate); | 112 | sched_clock_register(sp804_read, 32, rate); |
114 | } | 113 | } |
114 | |||
115 | return 0; | ||
115 | } | 116 | } |
116 | 117 | ||
117 | 118 | ||
@@ -186,7 +187,7 @@ static struct irqaction sp804_timer_irq = { | |||
186 | .dev_id = &sp804_clockevent, | 187 | .dev_id = &sp804_clockevent, |
187 | }; | 188 | }; |
188 | 189 | ||
189 | void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name) | 190 | int __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name) |
190 | { | 191 | { |
191 | struct clock_event_device *evt = &sp804_clockevent; | 192 | struct clock_event_device *evt = &sp804_clockevent; |
192 | long rate; | 193 | long rate; |
@@ -196,12 +197,12 @@ void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struc | |||
196 | if (IS_ERR(clk)) { | 197 | if (IS_ERR(clk)) { |
197 | pr_err("sp804: %s clock not found: %d\n", name, | 198 | pr_err("sp804: %s clock not found: %d\n", name, |
198 | (int)PTR_ERR(clk)); | 199 | (int)PTR_ERR(clk)); |
199 | return; | 200 | return PTR_ERR(clk); |
200 | } | 201 | } |
201 | 202 | ||
202 | rate = sp804_get_clock_rate(clk); | 203 | rate = sp804_get_clock_rate(clk); |
203 | if (rate < 0) | 204 | if (rate < 0) |
204 | return; | 205 | return -EINVAL; |
205 | 206 | ||
206 | clkevt_base = base; | 207 | clkevt_base = base; |
207 | clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); | 208 | clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); |
@@ -213,27 +214,31 @@ void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struc | |||
213 | 214 | ||
214 | setup_irq(irq, &sp804_timer_irq); | 215 | setup_irq(irq, &sp804_timer_irq); |
215 | clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); | 216 | clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); |
217 | |||
218 | return 0; | ||
216 | } | 219 | } |
217 | 220 | ||
218 | static void __init sp804_of_init(struct device_node *np) | 221 | static int __init sp804_of_init(struct device_node *np) |
219 | { | 222 | { |
220 | static bool initialized = false; | 223 | static bool initialized = false; |
221 | void __iomem *base; | 224 | void __iomem *base; |
222 | int irq; | 225 | int irq, ret = -EINVAL; |
223 | u32 irq_num = 0; | 226 | u32 irq_num = 0; |
224 | struct clk *clk1, *clk2; | 227 | struct clk *clk1, *clk2; |
225 | const char *name = of_get_property(np, "compatible", NULL); | 228 | const char *name = of_get_property(np, "compatible", NULL); |
226 | 229 | ||
227 | base = of_iomap(np, 0); | 230 | base = of_iomap(np, 0); |
228 | if (WARN_ON(!base)) | 231 | if (!base) |
229 | return; | 232 | return -ENXIO; |
230 | 233 | ||
231 | /* Ensure timers are disabled */ | 234 | /* Ensure timers are disabled */ |
232 | writel(0, base + TIMER_CTRL); | 235 | writel(0, base + TIMER_CTRL); |
233 | writel(0, base + TIMER_2_BASE + TIMER_CTRL); | 236 | writel(0, base + TIMER_2_BASE + TIMER_CTRL); |
234 | 237 | ||
235 | if (initialized || !of_device_is_available(np)) | 238 | if (initialized || !of_device_is_available(np)) { |
239 | ret = -EINVAL; | ||
236 | goto err; | 240 | goto err; |
241 | } | ||
237 | 242 | ||
238 | clk1 = of_clk_get(np, 0); | 243 | clk1 = of_clk_get(np, 0); |
239 | if (IS_ERR(clk1)) | 244 | if (IS_ERR(clk1)) |
@@ -256,35 +261,53 @@ static void __init sp804_of_init(struct device_node *np) | |||
256 | 261 | ||
257 | of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); | 262 | of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); |
258 | if (irq_num == 2) { | 263 | if (irq_num == 2) { |
259 | __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name); | 264 | |
260 | __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1); | 265 | ret = __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name); |
266 | if (ret) | ||
267 | goto err; | ||
268 | |||
269 | ret = __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1); | ||
270 | if (ret) | ||
271 | goto err; | ||
261 | } else { | 272 | } else { |
262 | __sp804_clockevents_init(base, irq, clk1 , name); | 273 | |
263 | __sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, | 274 | ret = __sp804_clockevents_init(base, irq, clk1 , name); |
264 | name, clk2, 1); | 275 | if (ret) |
276 | goto err; | ||
277 | |||
278 | ret =__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, | ||
279 | name, clk2, 1); | ||
280 | if (ret) | ||
281 | goto err; | ||
265 | } | 282 | } |
266 | initialized = true; | 283 | initialized = true; |
267 | 284 | ||
268 | return; | 285 | return 0; |
269 | err: | 286 | err: |
270 | iounmap(base); | 287 | iounmap(base); |
288 | return ret; | ||
271 | } | 289 | } |
272 | CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init); | 290 | CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init); |
273 | 291 | ||
274 | static void __init integrator_cp_of_init(struct device_node *np) | 292 | static int __init integrator_cp_of_init(struct device_node *np) |
275 | { | 293 | { |
276 | static int init_count = 0; | 294 | static int init_count = 0; |
277 | void __iomem *base; | 295 | void __iomem *base; |
278 | int irq; | 296 | int irq, ret = -EINVAL; |
279 | const char *name = of_get_property(np, "compatible", NULL); | 297 | const char *name = of_get_property(np, "compatible", NULL); |
280 | struct clk *clk; | 298 | struct clk *clk; |
281 | 299 | ||
282 | base = of_iomap(np, 0); | 300 | base = of_iomap(np, 0); |
283 | if (WARN_ON(!base)) | 301 | if (!base) { |
284 | return; | 302 | pr_err("Failed to iomap"); |
303 | return -ENXIO; | ||
304 | } | ||
305 | |||
285 | clk = of_clk_get(np, 0); | 306 | clk = of_clk_get(np, 0); |
286 | if (WARN_ON(IS_ERR(clk))) | 307 | if (IS_ERR(clk)) { |
287 | return; | 308 | pr_err("Failed to get clock"); |
309 | return PTR_ERR(clk); | ||
310 | } | ||
288 | 311 | ||
289 | /* Ensure timer is disabled */ | 312 | /* Ensure timer is disabled */ |
290 | writel(0, base + TIMER_CTRL); | 313 | writel(0, base + TIMER_CTRL); |
@@ -292,19 +315,24 @@ static void __init integrator_cp_of_init(struct device_node *np) | |||
292 | if (init_count == 2 || !of_device_is_available(np)) | 315 | if (init_count == 2 || !of_device_is_available(np)) |
293 | goto err; | 316 | goto err; |
294 | 317 | ||
295 | if (!init_count) | 318 | if (!init_count) { |
296 | __sp804_clocksource_and_sched_clock_init(base, name, clk, 0); | 319 | ret = __sp804_clocksource_and_sched_clock_init(base, name, clk, 0); |
297 | else { | 320 | if (ret) |
321 | goto err; | ||
322 | } else { | ||
298 | irq = irq_of_parse_and_map(np, 0); | 323 | irq = irq_of_parse_and_map(np, 0); |
299 | if (irq <= 0) | 324 | if (irq <= 0) |
300 | goto err; | 325 | goto err; |
301 | 326 | ||
302 | __sp804_clockevents_init(base, irq, clk, name); | 327 | ret = __sp804_clockevents_init(base, irq, clk, name); |
328 | if (ret) | ||
329 | goto err; | ||
303 | } | 330 | } |
304 | 331 | ||
305 | init_count++; | 332 | init_count++; |
306 | return; | 333 | return 0; |
307 | err: | 334 | err: |
308 | iounmap(base); | 335 | iounmap(base); |
336 | return ret; | ||
309 | } | 337 | } |
310 | CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init); | 338 | CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init); |
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c index f3dcb76799b4..1b2574c4fb97 100644 --- a/drivers/clocksource/timer-stm32.c +++ b/drivers/clocksource/timer-stm32.c | |||
@@ -98,7 +98,7 @@ static struct stm32_clock_event_ddata clock_event_ddata = { | |||
98 | }, | 98 | }, |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static void __init stm32_clockevent_init(struct device_node *np) | 101 | static int __init stm32_clockevent_init(struct device_node *np) |
102 | { | 102 | { |
103 | struct stm32_clock_event_ddata *data = &clock_event_ddata; | 103 | struct stm32_clock_event_ddata *data = &clock_event_ddata; |
104 | struct clk *clk; | 104 | struct clk *clk; |
@@ -130,12 +130,14 @@ static void __init stm32_clockevent_init(struct device_node *np) | |||
130 | 130 | ||
131 | data->base = of_iomap(np, 0); | 131 | data->base = of_iomap(np, 0); |
132 | if (!data->base) { | 132 | if (!data->base) { |
133 | ret = -ENXIO; | ||
133 | pr_err("failed to map registers for clockevent\n"); | 134 | pr_err("failed to map registers for clockevent\n"); |
134 | goto err_iomap; | 135 | goto err_iomap; |
135 | } | 136 | } |
136 | 137 | ||
137 | irq = irq_of_parse_and_map(np, 0); | 138 | irq = irq_of_parse_and_map(np, 0); |
138 | if (!irq) { | 139 | if (!irq) { |
140 | ret = -EINVAL; | ||
139 | pr_err("%s: failed to get irq.\n", np->full_name); | 141 | pr_err("%s: failed to get irq.\n", np->full_name); |
140 | goto err_get_irq; | 142 | goto err_get_irq; |
141 | } | 143 | } |
@@ -173,7 +175,7 @@ static void __init stm32_clockevent_init(struct device_node *np) | |||
173 | pr_info("%s: STM32 clockevent driver initialized (%d bits)\n", | 175 | pr_info("%s: STM32 clockevent driver initialized (%d bits)\n", |
174 | np->full_name, bits); | 176 | np->full_name, bits); |
175 | 177 | ||
176 | return; | 178 | return ret; |
177 | 179 | ||
178 | err_get_irq: | 180 | err_get_irq: |
179 | iounmap(data->base); | 181 | iounmap(data->base); |
@@ -182,7 +184,7 @@ err_iomap: | |||
182 | err_clk_enable: | 184 | err_clk_enable: |
183 | clk_put(clk); | 185 | clk_put(clk); |
184 | err_clk_get: | 186 | err_clk_get: |
185 | return; | 187 | return ret; |
186 | } | 188 | } |
187 | 189 | ||
188 | CLOCKSOURCE_OF_DECLARE(stm32, "st,stm32-timer", stm32_clockevent_init); | 190 | CLOCKSOURCE_OF_DECLARE(stm32, "st,stm32-timer", stm32_clockevent_init); |
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c index 24c83f9efd87..c184eb84101e 100644 --- a/drivers/clocksource/timer-sun5i.c +++ b/drivers/clocksource/timer-sun5i.c | |||
@@ -311,33 +311,42 @@ err_free: | |||
311 | return ret; | 311 | return ret; |
312 | } | 312 | } |
313 | 313 | ||
314 | static void __init sun5i_timer_init(struct device_node *node) | 314 | static int __init sun5i_timer_init(struct device_node *node) |
315 | { | 315 | { |
316 | struct reset_control *rstc; | 316 | struct reset_control *rstc; |
317 | void __iomem *timer_base; | 317 | void __iomem *timer_base; |
318 | struct clk *clk; | 318 | struct clk *clk; |
319 | int irq; | 319 | int irq, ret; |
320 | 320 | ||
321 | timer_base = of_io_request_and_map(node, 0, of_node_full_name(node)); | 321 | timer_base = of_io_request_and_map(node, 0, of_node_full_name(node)); |
322 | if (IS_ERR(timer_base)) | 322 | if (IS_ERR(timer_base)) { |
323 | panic("Can't map registers"); | 323 | pr_err("Can't map registers"); |
324 | return PTR_ERR(timer_base);; | ||
325 | } | ||
324 | 326 | ||
325 | irq = irq_of_parse_and_map(node, 0); | 327 | irq = irq_of_parse_and_map(node, 0); |
326 | if (irq <= 0) | 328 | if (irq <= 0) { |
327 | panic("Can't parse IRQ"); | 329 | pr_err("Can't parse IRQ"); |
330 | return -EINVAL; | ||
331 | } | ||
328 | 332 | ||
329 | clk = of_clk_get(node, 0); | 333 | clk = of_clk_get(node, 0); |
330 | if (IS_ERR(clk)) | 334 | if (IS_ERR(clk)) { |
331 | panic("Can't get timer clock"); | 335 | pr_err("Can't get timer clock"); |
336 | return PTR_ERR(clk); | ||
337 | } | ||
332 | 338 | ||
333 | rstc = of_reset_control_get(node, NULL); | 339 | rstc = of_reset_control_get(node, NULL); |
334 | if (!IS_ERR(rstc)) | 340 | if (!IS_ERR(rstc)) |
335 | reset_control_deassert(rstc); | 341 | reset_control_deassert(rstc); |
336 | 342 | ||
337 | sun5i_setup_clocksource(node, timer_base, clk, irq); | 343 | ret = sun5i_setup_clocksource(node, timer_base, clk, irq); |
338 | sun5i_setup_clockevent(node, timer_base, clk, irq); | 344 | if (ret) |
345 | return ret; | ||
346 | |||
347 | return sun5i_setup_clockevent(node, timer_base, clk, irq); | ||
339 | } | 348 | } |
340 | CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer", | 349 | CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer", |
341 | sun5i_timer_init); | 350 | sun5i_timer_init); |
342 | CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer", | 351 | CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer", |
343 | sun5i_timer_init); | 352 | sun5i_timer_init); |
diff --git a/drivers/clocksource/timer-ti-32k.c b/drivers/clocksource/timer-ti-32k.c index 8518d9dfba5c..92b7e390f6c8 100644 --- a/drivers/clocksource/timer-ti-32k.c +++ b/drivers/clocksource/timer-ti-32k.c | |||
@@ -88,14 +88,14 @@ static u64 notrace omap_32k_read_sched_clock(void) | |||
88 | return ti_32k_read_cycles(&ti_32k_timer.cs); | 88 | return ti_32k_read_cycles(&ti_32k_timer.cs); |
89 | } | 89 | } |
90 | 90 | ||
91 | static void __init ti_32k_timer_init(struct device_node *np) | 91 | static int __init ti_32k_timer_init(struct device_node *np) |
92 | { | 92 | { |
93 | int ret; | 93 | int ret; |
94 | 94 | ||
95 | ti_32k_timer.base = of_iomap(np, 0); | 95 | ti_32k_timer.base = of_iomap(np, 0); |
96 | if (!ti_32k_timer.base) { | 96 | if (!ti_32k_timer.base) { |
97 | pr_err("Can't ioremap 32k timer base\n"); | 97 | pr_err("Can't ioremap 32k timer base\n"); |
98 | return; | 98 | return -ENXIO; |
99 | } | 99 | } |
100 | 100 | ||
101 | ti_32k_timer.counter = ti_32k_timer.base; | 101 | ti_32k_timer.counter = ti_32k_timer.base; |
@@ -116,11 +116,13 @@ static void __init ti_32k_timer_init(struct device_node *np) | |||
116 | ret = clocksource_register_hz(&ti_32k_timer.cs, 32768); | 116 | ret = clocksource_register_hz(&ti_32k_timer.cs, 32768); |
117 | if (ret) { | 117 | if (ret) { |
118 | pr_err("32k_counter: can't register clocksource\n"); | 118 | pr_err("32k_counter: can't register clocksource\n"); |
119 | return; | 119 | return ret; |
120 | } | 120 | } |
121 | 121 | ||
122 | sched_clock_register(omap_32k_read_sched_clock, 32, 32768); | 122 | sched_clock_register(omap_32k_read_sched_clock, 32, 32768); |
123 | pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n"); | 123 | pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n"); |
124 | |||
125 | return 0; | ||
124 | } | 126 | } |
125 | CLOCKSOURCE_OF_DECLARE(ti_32k_timer, "ti,omap-counter32k", | 127 | CLOCKSOURCE_OF_DECLARE(ti_32k_timer, "ti,omap-counter32k", |
126 | ti_32k_timer_init); | 128 | ti_32k_timer_init); |
diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c index 1744b243898a..704e40c6f151 100644 --- a/drivers/clocksource/timer-u300.c +++ b/drivers/clocksource/timer-u300.c | |||
@@ -359,27 +359,37 @@ static struct delay_timer u300_delay_timer; | |||
359 | /* | 359 | /* |
360 | * This sets up the system timers, clock source and clock event. | 360 | * This sets up the system timers, clock source and clock event. |
361 | */ | 361 | */ |
362 | static void __init u300_timer_init_of(struct device_node *np) | 362 | static int __init u300_timer_init_of(struct device_node *np) |
363 | { | 363 | { |
364 | unsigned int irq; | 364 | unsigned int irq; |
365 | struct clk *clk; | 365 | struct clk *clk; |
366 | unsigned long rate; | 366 | unsigned long rate; |
367 | int ret; | ||
367 | 368 | ||
368 | u300_timer_base = of_iomap(np, 0); | 369 | u300_timer_base = of_iomap(np, 0); |
369 | if (!u300_timer_base) | 370 | if (!u300_timer_base) { |
370 | panic("could not ioremap system timer\n"); | 371 | pr_err("could not ioremap system timer\n"); |
372 | return -ENXIO; | ||
373 | } | ||
371 | 374 | ||
372 | /* Get the IRQ for the GP1 timer */ | 375 | /* Get the IRQ for the GP1 timer */ |
373 | irq = irq_of_parse_and_map(np, 2); | 376 | irq = irq_of_parse_and_map(np, 2); |
374 | if (!irq) | 377 | if (!irq) { |
375 | panic("no IRQ for system timer\n"); | 378 | pr_err("no IRQ for system timer\n"); |
379 | return -EINVAL; | ||
380 | } | ||
376 | 381 | ||
377 | pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq); | 382 | pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq); |
378 | 383 | ||
379 | /* Clock the interrupt controller */ | 384 | /* Clock the interrupt controller */ |
380 | clk = of_clk_get(np, 0); | 385 | clk = of_clk_get(np, 0); |
381 | BUG_ON(IS_ERR(clk)); | 386 | if (IS_ERR(clk)) |
382 | clk_prepare_enable(clk); | 387 | return PTR_ERR(clk); |
388 | |||
389 | ret = clk_prepare_enable(clk); | ||
390 | if (ret) | ||
391 | return ret; | ||
392 | |||
383 | rate = clk_get_rate(clk); | 393 | rate = clk_get_rate(clk); |
384 | 394 | ||
385 | u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); | 395 | u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); |
@@ -410,7 +420,9 @@ static void __init u300_timer_init_of(struct device_node *np) | |||
410 | u300_timer_base + U300_TIMER_APP_RGPT1); | 420 | u300_timer_base + U300_TIMER_APP_RGPT1); |
411 | 421 | ||
412 | /* Set up the IRQ handler */ | 422 | /* Set up the IRQ handler */ |
413 | setup_irq(irq, &u300_timer_irq); | 423 | ret = setup_irq(irq, &u300_timer_irq); |
424 | if (ret) | ||
425 | return ret; | ||
414 | 426 | ||
415 | /* Reset the General Purpose timer 2 */ | 427 | /* Reset the General Purpose timer 2 */ |
416 | writel(U300_TIMER_APP_RGPT2_TIMER_RESET, | 428 | writel(U300_TIMER_APP_RGPT2_TIMER_RESET, |
@@ -428,9 +440,12 @@ static void __init u300_timer_init_of(struct device_node *np) | |||
428 | u300_timer_base + U300_TIMER_APP_EGPT2); | 440 | u300_timer_base + U300_TIMER_APP_EGPT2); |
429 | 441 | ||
430 | /* Use general purpose timer 2 as clock source */ | 442 | /* Use general purpose timer 2 as clock source */ |
431 | if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, | 443 | ret = clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, |
432 | "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) | 444 | "GPT2", rate, 300, 32, clocksource_mmio_readl_up); |
445 | if (ret) { | ||
433 | pr_err("timer: failed to initialize U300 clock source\n"); | 446 | pr_err("timer: failed to initialize U300 clock source\n"); |
447 | return ret; | ||
448 | } | ||
434 | 449 | ||
435 | /* Configure and register the clockevent */ | 450 | /* Configure and register the clockevent */ |
436 | clockevents_config_and_register(&u300_clockevent_data.cevd, rate, | 451 | clockevents_config_and_register(&u300_clockevent_data.cevd, rate, |
@@ -440,6 +455,7 @@ static void __init u300_timer_init_of(struct device_node *np) | |||
440 | * TODO: init and register the rest of the timers too, they can be | 455 | * TODO: init and register the rest of the timers too, they can be |
441 | * used by hrtimers! | 456 | * used by hrtimers! |
442 | */ | 457 | */ |
458 | return 0; | ||
443 | } | 459 | } |
444 | 460 | ||
445 | CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", | 461 | CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", |
diff --git a/drivers/clocksource/versatile.c b/drivers/clocksource/versatile.c index 0a26d3dde6c0..220b490a8142 100644 --- a/drivers/clocksource/versatile.c +++ b/drivers/clocksource/versatile.c | |||
@@ -25,16 +25,18 @@ static u64 notrace versatile_sys_24mhz_read(void) | |||
25 | return readl(versatile_sys_24mhz); | 25 | return readl(versatile_sys_24mhz); |
26 | } | 26 | } |
27 | 27 | ||
28 | static void __init versatile_sched_clock_init(struct device_node *node) | 28 | static int __init versatile_sched_clock_init(struct device_node *node) |
29 | { | 29 | { |
30 | void __iomem *base = of_iomap(node, 0); | 30 | void __iomem *base = of_iomap(node, 0); |
31 | 31 | ||
32 | if (!base) | 32 | if (!base) |
33 | return; | 33 | return -ENXIO; |
34 | 34 | ||
35 | versatile_sys_24mhz = base + SYS_24MHZ; | 35 | versatile_sys_24mhz = base + SYS_24MHZ; |
36 | 36 | ||
37 | sched_clock_register(versatile_sys_24mhz_read, 32, 24000000); | 37 | sched_clock_register(versatile_sys_24mhz_read, 32, 24000000); |
38 | |||
39 | return 0; | ||
38 | } | 40 | } |
39 | CLOCKSOURCE_OF_DECLARE(vexpress, "arm,vexpress-sysreg", | 41 | CLOCKSOURCE_OF_DECLARE(vexpress, "arm,vexpress-sysreg", |
40 | versatile_sched_clock_init); | 42 | versatile_sched_clock_init); |
diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c index a0e6c68536a1..55d8d8402d90 100644 --- a/drivers/clocksource/vf_pit_timer.c +++ b/drivers/clocksource/vf_pit_timer.c | |||
@@ -156,15 +156,18 @@ static int __init pit_clockevent_init(unsigned long rate, int irq) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static void __init pit_timer_init(struct device_node *np) | 159 | static int __init pit_timer_init(struct device_node *np) |
160 | { | 160 | { |
161 | struct clk *pit_clk; | 161 | struct clk *pit_clk; |
162 | void __iomem *timer_base; | 162 | void __iomem *timer_base; |
163 | unsigned long clk_rate; | 163 | unsigned long clk_rate; |
164 | int irq; | 164 | int irq, ret; |
165 | 165 | ||
166 | timer_base = of_iomap(np, 0); | 166 | timer_base = of_iomap(np, 0); |
167 | BUG_ON(!timer_base); | 167 | if (!timer_base) { |
168 | pr_err("Failed to iomap"); | ||
169 | return -ENXIO; | ||
170 | } | ||
168 | 171 | ||
169 | /* | 172 | /* |
170 | * PIT0 and PIT1 can be chained to build a 64-bit timer, | 173 | * PIT0 and PIT1 can be chained to build a 64-bit timer, |
@@ -175,12 +178,16 @@ static void __init pit_timer_init(struct device_node *np) | |||
175 | clkevt_base = timer_base + PITn_OFFSET(3); | 178 | clkevt_base = timer_base + PITn_OFFSET(3); |
176 | 179 | ||
177 | irq = irq_of_parse_and_map(np, 0); | 180 | irq = irq_of_parse_and_map(np, 0); |
178 | BUG_ON(irq <= 0); | 181 | if (irq <= 0) |
182 | return -EINVAL; | ||
179 | 183 | ||
180 | pit_clk = of_clk_get(np, 0); | 184 | pit_clk = of_clk_get(np, 0); |
181 | BUG_ON(IS_ERR(pit_clk)); | 185 | if (IS_ERR(pit_clk)) |
186 | return PTR_ERR(pit_clk); | ||
182 | 187 | ||
183 | BUG_ON(clk_prepare_enable(pit_clk)); | 188 | ret = clk_prepare_enable(pit_clk); |
189 | if (ret) | ||
190 | return ret; | ||
184 | 191 | ||
185 | clk_rate = clk_get_rate(pit_clk); | 192 | clk_rate = clk_get_rate(pit_clk); |
186 | cycle_per_jiffy = clk_rate / (HZ); | 193 | cycle_per_jiffy = clk_rate / (HZ); |
@@ -188,8 +195,10 @@ static void __init pit_timer_init(struct device_node *np) | |||
188 | /* enable the pit module */ | 195 | /* enable the pit module */ |
189 | __raw_writel(~PITMCR_MDIS, timer_base + PITMCR); | 196 | __raw_writel(~PITMCR_MDIS, timer_base + PITMCR); |
190 | 197 | ||
191 | BUG_ON(pit_clocksource_init(clk_rate)); | 198 | ret = pit_clocksource_init(clk_rate); |
199 | if (ret) | ||
200 | return ret; | ||
192 | 201 | ||
193 | pit_clockevent_init(clk_rate, irq); | 202 | return pit_clockevent_init(clk_rate, irq); |
194 | } | 203 | } |
195 | CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init); | 204 | CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init); |
diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c index ddb409274f45..b15069483fbd 100644 --- a/drivers/clocksource/vt8500_timer.c +++ b/drivers/clocksource/vt8500_timer.c | |||
@@ -121,38 +121,48 @@ static struct irqaction irq = { | |||
121 | .dev_id = &clockevent, | 121 | .dev_id = &clockevent, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static void __init vt8500_timer_init(struct device_node *np) | 124 | static int __init vt8500_timer_init(struct device_node *np) |
125 | { | 125 | { |
126 | int timer_irq; | 126 | int timer_irq, ret; |
127 | 127 | ||
128 | regbase = of_iomap(np, 0); | 128 | regbase = of_iomap(np, 0); |
129 | if (!regbase) { | 129 | if (!regbase) { |
130 | pr_err("%s: Missing iobase description in Device Tree\n", | 130 | pr_err("%s: Missing iobase description in Device Tree\n", |
131 | __func__); | 131 | __func__); |
132 | return; | 132 | return -ENXIO; |
133 | } | 133 | } |
134 | |||
134 | timer_irq = irq_of_parse_and_map(np, 0); | 135 | timer_irq = irq_of_parse_and_map(np, 0); |
135 | if (!timer_irq) { | 136 | if (!timer_irq) { |
136 | pr_err("%s: Missing irq description in Device Tree\n", | 137 | pr_err("%s: Missing irq description in Device Tree\n", |
137 | __func__); | 138 | __func__); |
138 | return; | 139 | return -EINVAL; |
139 | } | 140 | } |
140 | 141 | ||
141 | writel(1, regbase + TIMER_CTRL_VAL); | 142 | writel(1, regbase + TIMER_CTRL_VAL); |
142 | writel(0xf, regbase + TIMER_STATUS_VAL); | 143 | writel(0xf, regbase + TIMER_STATUS_VAL); |
143 | writel(~0, regbase + TIMER_MATCH_VAL); | 144 | writel(~0, regbase + TIMER_MATCH_VAL); |
144 | 145 | ||
145 | if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ)) | 146 | ret = clocksource_register_hz(&clocksource, VT8500_TIMER_HZ); |
147 | if (ret) { | ||
146 | pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n", | 148 | pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n", |
147 | __func__, clocksource.name); | 149 | __func__, clocksource.name); |
150 | return ret; | ||
151 | } | ||
148 | 152 | ||
149 | clockevent.cpumask = cpumask_of(0); | 153 | clockevent.cpumask = cpumask_of(0); |
150 | 154 | ||
151 | if (setup_irq(timer_irq, &irq)) | 155 | ret = setup_irq(timer_irq, &irq); |
156 | if (ret) { | ||
152 | pr_err("%s: setup_irq failed for %s\n", __func__, | 157 | pr_err("%s: setup_irq failed for %s\n", __func__, |
153 | clockevent.name); | 158 | clockevent.name); |
159 | return ret; | ||
160 | } | ||
161 | |||
154 | clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ, | 162 | clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ, |
155 | MIN_OSCR_DELTA * 2, 0xf0000000); | 163 | MIN_OSCR_DELTA * 2, 0xf0000000); |
164 | |||
165 | return 0; | ||
156 | } | 166 | } |
157 | 167 | ||
158 | CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); | 168 | CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); |
diff --git a/drivers/clocksource/zevio-timer.c b/drivers/clocksource/zevio-timer.c index ceaa6133f9c2..9a53f5ef6157 100644 --- a/drivers/clocksource/zevio-timer.c +++ b/drivers/clocksource/zevio-timer.c | |||
@@ -210,9 +210,9 @@ error_free: | |||
210 | return ret; | 210 | return ret; |
211 | } | 211 | } |
212 | 212 | ||
213 | static void __init zevio_timer_init(struct device_node *node) | 213 | static int __init zevio_timer_init(struct device_node *node) |
214 | { | 214 | { |
215 | BUG_ON(zevio_timer_add(node)); | 215 | return zevio_timer_add(node); |
216 | } | 216 | } |
217 | 217 | ||
218 | CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init); | 218 | CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init); |
diff --git a/include/clocksource/timer-sp804.h b/include/clocksource/timer-sp804.h index 1f8a1caa7cb4..7654d71243dd 100644 --- a/include/clocksource/timer-sp804.h +++ b/include/clocksource/timer-sp804.h | |||
@@ -3,10 +3,10 @@ | |||
3 | 3 | ||
4 | struct clk; | 4 | struct clk; |
5 | 5 | ||
6 | void __sp804_clocksource_and_sched_clock_init(void __iomem *, | 6 | int __sp804_clocksource_and_sched_clock_init(void __iomem *, |
7 | const char *, struct clk *, int); | 7 | const char *, struct clk *, int); |
8 | void __sp804_clockevents_init(void __iomem *, unsigned int, | 8 | int __sp804_clockevents_init(void __iomem *, unsigned int, |
9 | struct clk *, const char *); | 9 | struct clk *, const char *); |
10 | void sp804_timer_disable(void __iomem *); | 10 | void sp804_timer_disable(void __iomem *); |
11 | 11 | ||
12 | static inline void sp804_clocksource_init(void __iomem *base, const char *name) | 12 | static inline void sp804_clocksource_init(void __iomem *base, const char *name) |
diff --git a/include/linux/clk.h b/include/linux/clk.h index 0df4a51e1a78..834179f3fa72 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h | |||
@@ -461,6 +461,10 @@ static inline struct clk *clk_get_parent(struct clk *clk) | |||
461 | return NULL; | 461 | return NULL; |
462 | } | 462 | } |
463 | 463 | ||
464 | static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id) | ||
465 | { | ||
466 | return NULL; | ||
467 | } | ||
464 | #endif | 468 | #endif |
465 | 469 | ||
466 | /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ | 470 | /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ |
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 44a1aff22566..08398182f56e 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -244,7 +244,7 @@ extern int clocksource_mmio_init(void __iomem *, const char *, | |||
244 | extern int clocksource_i8253_init(void); | 244 | extern int clocksource_i8253_init(void); |
245 | 245 | ||
246 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ | 246 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ |
247 | OF_DECLARE_1(clksrc, name, compat, fn) | 247 | OF_DECLARE_1_RET(clksrc, name, compat, fn) |
248 | 248 | ||
249 | #ifdef CONFIG_CLKSRC_PROBE | 249 | #ifdef CONFIG_CLKSRC_PROBE |
250 | extern void clocksource_probe(void); | 250 | extern void clocksource_probe(void); |
diff --git a/include/linux/of.h b/include/linux/of.h index 74eb28cadbef..15c43f076b23 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -1009,10 +1009,13 @@ static inline int of_get_available_child_count(const struct device_node *np) | |||
1009 | #endif | 1009 | #endif |
1010 | 1010 | ||
1011 | typedef int (*of_init_fn_2)(struct device_node *, struct device_node *); | 1011 | typedef int (*of_init_fn_2)(struct device_node *, struct device_node *); |
1012 | typedef int (*of_init_fn_1_ret)(struct device_node *); | ||
1012 | typedef void (*of_init_fn_1)(struct device_node *); | 1013 | typedef void (*of_init_fn_1)(struct device_node *); |
1013 | 1014 | ||
1014 | #define OF_DECLARE_1(table, name, compat, fn) \ | 1015 | #define OF_DECLARE_1(table, name, compat, fn) \ |
1015 | _OF_DECLARE(table, name, compat, fn, of_init_fn_1) | 1016 | _OF_DECLARE(table, name, compat, fn, of_init_fn_1) |
1017 | #define OF_DECLARE_1_RET(table, name, compat, fn) \ | ||
1018 | _OF_DECLARE(table, name, compat, fn, of_init_fn_1_ret) | ||
1016 | #define OF_DECLARE_2(table, name, compat, fn) \ | 1019 | #define OF_DECLARE_2(table, name, compat, fn) \ |
1017 | _OF_DECLARE(table, name, compat, fn, of_init_fn_2) | 1020 | _OF_DECLARE(table, name, compat, fn, of_init_fn_2) |
1018 | 1021 | ||