diff options
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/Kconfig | 50 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 66 | ||||
-rw-r--r-- | drivers/clocksource/bcm2835_timer.c | 2 | ||||
-rw-r--r-- | drivers/clocksource/cs5535-clockevt.c | 3 | ||||
-rw-r--r-- | drivers/clocksource/h8300_timer16.c | 1 | ||||
-rw-r--r-- | drivers/clocksource/h8300_timer8.c | 1 | ||||
-rw-r--r-- | drivers/clocksource/h8300_tpu.c | 1 | ||||
-rw-r--r-- | drivers/clocksource/i8253.c | 1 | ||||
-rw-r--r-- | drivers/clocksource/mips-gic-timer.c | 12 | ||||
-rw-r--r-- | drivers/clocksource/owl-timer.c | 4 | ||||
-rw-r--r-- | drivers/clocksource/rockchip_timer.c | 2 | ||||
-rw-r--r-- | drivers/clocksource/sh_cmt.c | 76 | ||||
-rw-r--r-- | drivers/clocksource/tango_xtal.c | 1 | ||||
-rw-r--r-- | drivers/clocksource/tcb_clksrc.c | 1 | ||||
-rw-r--r-- | drivers/clocksource/timer-fttmr010.c | 5 | ||||
-rw-r--r-- | drivers/clocksource/timer-of.c | 12 | ||||
-rw-r--r-- | drivers/clocksource/timer-of.h | 4 | ||||
-rw-r--r-- | drivers/clocksource/timer-sp.h | 1 |
19 files changed, 126 insertions, 118 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cc6062049170..c729a88007d0 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -1,9 +1,8 @@ menu "Clock Source drivers" - depends on !ARCH_USES_GETTIMEOFFSET + depends on GENERIC_CLOCKEVENTS config TIMER_OF bool - depends on GENERIC_CLOCKEVENTS select TIMER_PROBE config TIMER_ACPI @@ -30,21 +29,18 @@ config CLKSRC_MMIO config BCM2835_TIMER bool "BCM2835 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables the support for the BCM2835 timer driver. config BCM_KONA_TIMER bool "BCM mobile timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables the support for the BCM Kona mobile timer driver. config DIGICOLOR_TIMER bool "Digicolor timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO depends on HAS_IOMEM help @@ -52,7 +48,6 @@ config DIGICOLOR_TIMER config DW_APB_TIMER bool "DW APB timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS help Enables the support for the dw_apb timer. @@ -63,7 +58,6 @@ config DW_APB_TIMER_OF config FTTMR010_TIMER bool "Faraday Technology timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM select CLKSRC_MMIO select TIMER_OF @@ -90,7 +84,6 @@ config ARMADA_370_XP_TIMER config MESON6_TIMER bool "Meson6 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables the support for the Meson6 timer driver. @@ -105,14 +98,12 @@ config ORION_TIMER config OWL_TIMER bool "Owl timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables the support for the Actions Semi Owl timer driver. config SUN4I_TIMER bool "Sun4i timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM select CLKSRC_MMIO select TIMER_OF @@ -135,7 +126,6 @@ config TEGRA_TIMER config VT8500_TIMER bool "VT8500 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM help Enables support for the VT8500 driver. @@ -148,7 +138,6 @@ config CADENCE_TTC_TIMER config ASM9260_TIMER bool "ASM9260 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO select TIMER_OF help @@ -171,28 +160,24 @@ config CLKSRC_NOMADIK_MTU_SCHED_CLOCK config CLKSRC_DBX500_PRCMU bool "Clocksource PRCMU Timer" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM help Use the always on PRCMU Timer as clocksource config CLPS711X_TIMER bool "Cirrus logic timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables support for the Cirrus Logic PS711 timer. config ATLAS7_TIMER bool "Atlas7 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables support for the Atlas7 timer. config MXS_TIMER bool "Mxs timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO select STMP_DEVICE help @@ -200,14 +185,12 @@ config MXS_TIMER config PRIMA2_TIMER bool "Prima2 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables support for the Prima2 timer. config U300_TIMER bool "U300 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on ARM select CLKSRC_MMIO help @@ -215,14 +198,12 @@ config U300_TIMER config NSPIRE_TIMER bool "NSpire timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables support for the Nspire timer. config KEYSTONE_TIMER bool "Keystone timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on ARM || ARM64 select CLKSRC_MMIO help @@ -230,7 +211,6 @@ config KEYSTONE_TIMER config INTEGRATOR_AP_TIMER bool "Integrator-ap timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables support for the Integrator-ap timer. @@ -253,7 +233,7 @@ config CLKSRC_EFM32 config CLKSRC_LPC32XX bool "Clocksource for LPC32XX" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM depends on ARM select CLKSRC_MMIO select TIMER_OF @@ -262,7 +242,7 @@ config CLKSRC_LPC32XX config CLKSRC_PISTACHIO bool "Clocksource for Pistachio SoC" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM select TIMER_OF help Enables the clocksource for the Pistachio SoC. @@ -298,7 +278,6 @@ config CLKSRC_MPS2 config ARC_TIMERS bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select TIMER_OF help These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores @@ -307,7 +286,6 @@ config ARC_TIMERS config ARC_TIMERS_64BIT bool "Support for 64-bit counters in ARC HS38 cores" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on ARC_TIMERS select TIMER_OF help @@ -407,7 +385,6 @@ config ATMEL_PIT config ATMEL_ST bool "Atmel ST timer support" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select TIMER_OF select MFD_SYSCON help @@ -426,7 +403,6 @@ config CLKSRC_EXYNOS_MCT config CLKSRC_SAMSUNG_PWM bool "PWM timer driver for Samsung S3C, S5P" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM help This is a new clocksource driver for the PWM timer found in @@ -436,7 +412,6 @@ config CLKSRC_SAMSUNG_PWM config FSL_FTM_TIMER bool "Freescale FlexTimer Module driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM select CLKSRC_MMIO help @@ -450,7 +425,6 @@ config VF_PIT_TIMER config OXNAS_RPS_TIMER bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select TIMER_OF select CLKSRC_MMIO help @@ -461,7 +435,7 @@ config SYS_SUPPORTS_SH_CMT config MTK_TIMER bool "Mediatek timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM select TIMER_OF select CLKSRC_MMIO help @@ -479,7 +453,6 @@ config SYS_SUPPORTS_EM_STI config CLKSRC_JCORE_PIT bool "J-Core PIT timer driver" if COMPILE_TEST depends on OF - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM select CLKSRC_MMIO help @@ -488,7 +461,6 @@ config CLKSRC_JCORE_PIT config SH_TIMER_CMT bool "Renesas CMT timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM default SYS_SUPPORTS_SH_CMT help @@ -498,7 +470,6 @@ config SH_TIMER_CMT config SH_TIMER_MTU2 bool "Renesas MTU2 timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM default SYS_SUPPORTS_SH_MTU2 help @@ -508,14 +479,12 @@ config SH_TIMER_MTU2 config RENESAS_OSTM bool "Renesas OSTM timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS select CLKSRC_MMIO help Enables the support for the Renesas OSTM. config SH_TIMER_TMU bool "Renesas TMU timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM default SYS_SUPPORTS_SH_TMU help @@ -525,7 +494,7 @@ config SH_TIMER_TMU config EM_TIMER_STI bool "Renesas STI timer driver" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM default SYS_SUPPORTS_EM_STI help This enables build of a clocksource and clockevent driver for @@ -566,7 +535,6 @@ config CLKSRC_TANGO_XTAL config CLKSRC_PXA bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS depends on HAS_IOMEM select CLKSRC_MMIO help @@ -575,20 +543,20 @@ config CLKSRC_PXA config H8300_TMR8 bool "Clockevent timer for the H8300 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM help This enables the 8 bits timer for the H8300 platform. config H8300_TMR16 bool "Clockevent timer for the H83069 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM help This enables the 16 bits timer for the H8300 platform with the H83069 cpu. config H8300_TPU bool "Clocksource for the H8300 platform" if COMPILE_TEST - depends on GENERIC_CLOCKEVENTS && HAS_IOMEM + depends on HAS_IOMEM help This enables the clocksource for the H8300 platform with the H8S2678 cpu. @@ -600,7 +568,7 @@ config CLKSRC_IMX_GPT config CLKSRC_IMX_TPM bool "Clocksource using i.MX TPM" if COMPILE_TEST - depends on ARM && CLKDEV_LOOKUP && GENERIC_CLOCKEVENTS + depends on ARM && CLKDEV_LOOKUP select CLKSRC_MMIO help Enable this option to use IMX Timer/PWM Module (TPM) timer as diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dbc1ad14515e..72711f1491e3 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TIMER_OF) += timer-of.o obj-$(CONFIG_TIMER_PROBE) += timer-probe.o obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 061476e92db7..57cb2f00fc07 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -77,6 +77,7 @@ static bool arch_timer_mem_use_virtual; static bool arch_counter_suspend_stop; static bool vdso_default = true; +static cpumask_t evtstrm_available = CPU_MASK_NONE; static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); static int __init early_evtstrm_cfg(char *buf) @@ -319,8 +320,7 @@ static u64 notrace arm64_858921_read_cntvct_el0(void) #endif #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND -DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, - timer_unstable_counter_workaround); +DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround); EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled); @@ -767,6 +767,7 @@ static void arch_timer_evtstrm_enable(int divider) #ifdef CONFIG_COMPAT compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; #endif + cpumask_set_cpu(smp_processor_id(), &evtstrm_available); } static void arch_timer_configure_evtstream(void) @@ -891,6 +892,16 @@ u32 arch_timer_get_rate(void) return arch_timer_rate; } +bool arch_timer_evtstrm_available(void) +{ + /* + * We might get called from a preemptible context. This is fine + * because availability of the event stream should be always the same + * for a preemptible context and context where we might resume a task. + */ + return cpumask_test_cpu(raw_smp_processor_id(), &evtstrm_available); +} + static u64 arch_counter_get_cntvct_mem(void) { u32 vct_lo, vct_hi, tmp_hi; @@ -956,6 +967,8 @@ static int arch_timer_dying_cpu(unsigned int cpu) { struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt); + cpumask_clear_cpu(smp_processor_id(), &evtstrm_available); + arch_timer_stop(clk); return 0; } @@ -965,10 +978,16 @@ static DEFINE_PER_CPU(unsigned long, saved_cntkctl); static int arch_timer_cpu_pm_notify(struct notifier_block *self, unsigned long action, void *hcpu) { - if (action == CPU_PM_ENTER) + if (action == CPU_PM_ENTER) { __this_cpu_write(saved_cntkctl, arch_timer_get_cntkctl()); - else if (action == CPU_PM_ENTER_FAILED || action == CPU_PM_EXIT) + + cpumask_clear_cpu(smp_processor_id(), &evtstrm_available); + } else if (action == CPU_PM_ENTER_FAILED || action == CPU_PM_EXIT) { arch_timer_set_cntkctl(__this_cpu_read(saved_cntkctl)); + + if (elf_hwcap & HWCAP_EVTSTRM) + cpumask_set_cpu(smp_processor_id(), &evtstrm_available); + } return NOTIFY_OK; } @@ -1044,7 +1063,6 @@ static int __init arch_timer_register(void) if (err) goto out_unreg_notify; - /* Register and immediately configure the timer on the boot CPU */ err = cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_STARTING, "clockevents/arm/arch_timer:starting", @@ -1295,10 +1313,6 @@ arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem) iounmap(cntctlbase); - if (!best_frame) - pr_err("Unable to find a suitable frame in timer @ %pa\n", - &timer_mem->cntctlbase); - return best_frame; } @@ -1399,6 +1413,8 @@ static int __init arch_timer_mem_of_init(struct device_node *np) frame = arch_timer_mem_find_best_frame(timer_mem); if (!frame) { + pr_err("Unable to find a suitable frame in timer @ %pa\n", + &timer_mem->cntctlbase); ret = -EINVAL; goto out; } @@ -1447,7 +1463,7 @@ arch_timer_mem_verify_cntfrq(struct arch_timer_mem *timer_mem) static int __init arch_timer_mem_acpi_init(int platform_timer_count) { struct arch_timer_mem *timers, *timer; - struct arch_timer_mem_frame *frame; + struct arch_timer_mem_frame *frame, *best_frame = NULL; int timer_count, i, ret = 0; timers = kcalloc(platform_timer_count, sizeof(*timers), @@ -1459,14 +1475,6 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count) if (ret || !timer_count) goto out; - for (i = 0; i < timer_count; i++) { - ret = arch_timer_mem_verify_cntfrq(&timers[i]); - if (ret) { - pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n"); - goto out; - } - } - /* * While unlikely, it's theoretically possible that none of the frames * in a timer expose the combination of feature we want. @@ -1475,12 +1483,26 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count) timer = &timers[i]; frame = arch_timer_mem_find_best_frame(timer); - if (frame) - break; + if (!best_frame) + best_frame = frame; + + ret = arch_timer_mem_verify_cntfrq(timer); + if (ret) { + pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n"); + goto out; + } + + if (!best_frame) /* implies !frame */ + /* + * Only complain about missing suitable frames if we + * haven't already found one in a previous iteration. + */ + pr_err("Unable to find a suitable frame in timer @ %pa\n", + &timer->cntctlbase); } - if (frame) - ret = arch_timer_mem_frame_register(frame); + if (best_frame) + ret = arch_timer_mem_frame_register(best_frame); out: kfree(timers); return ret; diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c index 39e489a96ad7..60da2537bef9 100644 --- a/drivers/clocksource/bcm2835_timer.c +++ b/drivers/clocksource/bcm2835_timer.c @@ -71,7 +71,7 @@ static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id) if (readl_relaxed(timer->control) & timer->match_mask) { writel_relaxed(timer->match_mask, timer->control); - event_handler = ACCESS_ONCE(timer->evt.event_handler); + event_handler = READ_ONCE(timer->evt.event_handler); if (event_handler) event_handler(&timer->evt); return IRQ_HANDLED; diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index a1df588343f2..1de8cac99a0e 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c @@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) /* Turn off the clock (and clear the event) */ disable_timer(cs5535_event_clock); - if (clockevent_state_shutdown(&cs5535_clockevent)) + if (clockevent_state_detached(&cs5535_clockevent) || + clockevent_state_shutdown(&cs5535_clockevent)) return IRQ_HANDLED; /* Clear the counter */ diff --git a/drivers/clocksource/h8300_timer16.c b/drivers/clocksource/h8300_timer16.c index dfbd4f8051cb..86ca91451b2e 100644 --- a/drivers/clocksource/h8300_timer16.c +++ b/drivers/clocksource/h8300_timer16.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * H8/300 16bit Timer driver * diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c index f6ffb0cef091..1d740a8c42ab 100644 --- a/drivers/clocksource/h8300_timer8.c +++ b/drivers/clocksource/h8300_timer8.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/kernel/cpu/timer/timer8.c * diff --git a/drivers/clocksource/h8300_tpu.c b/drivers/clocksource/h8300_tpu.c index 45a8d17dac1e..17d4ab0f6ad1 100644 --- a/drivers/clocksource/h8300_tpu.c +++ b/drivers/clocksource/h8300_tpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * H8S TPU Driver * diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c index 64f6490740d7..9c38895542f4 100644 --- a/drivers/clocksource/i8253.c +++ b/drivers/clocksource/i8253.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * i8253 PIT clocksource */ diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index ae3167c28b12..a04808a21d4e 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -39,16 +39,18 @@ static u64 notrace gic_read_count(void) static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { - unsigned long flags; + int cpu = cpumask_first(evt->cpumask); u64 cnt; int res; cnt = gic_read_count(); cnt += (u64)delta; - local_irq_save(flags); - write_gic_vl_other(mips_cm_vp_id(cpumask_first(evt->cpumask))); - write_gic_vo_compare(cnt); - local_irq_restore(flags); + if (cpu == raw_smp_processor_id()) { + write_gic_vl_compare(cnt); + } else { + write_gic_vl_other(mips_cm_vp_id(cpu)); + write_gic_vo_compare(cnt); + } res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; return res; } diff --git a/drivers/clocksource/owl-timer.c b/drivers/clocksource/owl-timer.c index d19c53c11094..c68630565079 100644 --- a/drivers/clocksource/owl-timer.c +++ b/drivers/clocksource/owl-timer.c @@ -125,7 +125,7 @@ static int __init owl_timer_init(struct device_node *node) owl_timer_base = of_io_request_and_map(node, 0, "owl-timer"); if (IS_ERR(owl_timer_base)) { - pr_err("Can't map timer registers"); + pr_err("Can't map timer registers\n"); return PTR_ERR(owl_timer_base); } @@ -134,7 +134,7 @@ static int __init owl_timer_init(struct device_node *node) timer1_irq = of_irq_get_byname(node, "timer1"); if (timer1_irq <= 0) { - pr_err("Can't parse timer1 IRQ"); + pr_err("Can't parse timer1 IRQ\n"); return -EINVAL; } diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c index c27f4c850d83..33f370dbd0d6 100644 --- a/drivers/clocksource/rockchip_timer.c +++ b/drivers/clocksource/rockchip_timer.c @@ -274,7 +274,7 @@ static int __init rk_clksrc_init(struct device_node *np) TIMER_NAME, rk_clksrc->freq, 250, 32, clocksource_mmio_readl_down); if (ret) { - pr_err("Failed to register clocksource"); + pr_err("Failed to register clocksource\n"); goto out_clocksource; } diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index e09e8bf0bb9b..70b3cf8e23d0 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -25,6 +25,7 @@ #include <linux/irq.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> @@ -39,16 +40,16 @@ struct sh_cmt_device; * SoC but also on the particular instance. The following table lists the main * characteristics of those flavours. * - * 16B 32B 32B-F 48B 48B-2 + * 16B 32B 32B-F 48B R-Car Gen2 * ----------------------------------------------------------------------------- * Channels 2 1/4 1 6 2/8 * Control Width 16 16 16 16 32 * Counter Width 16 32 32 32/48 32/48 * Shared Start/Stop Y Y Y Y N * - * The 48-bit gen2 version has a per-channel start/stop register located in the - * channel registers block. All other versions have a shared start/stop register - * located in the global space. + * The r8a73a4 / R-Car Gen2 version has a per-channel start/stop register + * located in the channel registers block. All other versions have a shared + * start/stop register located in the global space. * * Channels are indexed from 0 to N-1 in the documentation. The channel index * infers the start/stop bit position in the control register and the channel @@ -66,14 +67,16 @@ struct sh_cmt_device; enum sh_cmt_model { SH_CMT_16BIT, SH_CMT_32BIT, - SH_CMT_32BIT_FAST, SH_CMT_48BIT, - SH_CMT_48BIT_GEN2, + SH_CMT0_RCAR_GEN2, + SH_CMT1_RCAR_GEN2, }; struct sh_cmt_info { enum sh_cmt_model model; + unsigned int channels_mask; + unsigned long width; /* 16 or 32 bit version of hardware block */ unsigned long overflow_bit; unsigned long clear_bits; @@ -200,18 +203,20 @@ static const struct sh_cmt_info sh_cmt_info[] = { .read_count = sh_cmt_read32, .write_count = sh_cmt_write32, }, - [SH_CMT_32BIT_FAST] = { - .model = SH_CMT_32BIT_FAST, + [SH_CMT_48BIT] = { + .model = SH_CMT_48BIT, + .channels_mask = 0x3f, .width = 32, .overflow_bit = SH_CMT32_CMCSR_CMF, .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF), - .read_control = sh_cmt_read16, - .write_control = sh_cmt_write16, + .read_control = sh_cmt_read32, + .write_control = sh_cmt_write32, .read_count = sh_cmt_read32, .write_count = sh_cmt_write32, }, - [SH_CMT_48BIT] = { - .model = SH_CMT_48BIT, + [SH_CMT0_RCAR_GEN2] = { + .model = SH_CMT0_RCAR_GEN2, + .channels_mask = 0x60, .width = 32, .overflow_bit = SH_CMT32_CMCSR_CMF, .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF), @@ -220,8 +225,9 @@ static const struct sh_cmt_info sh_cmt_info[] = { .read_count = sh_cmt_read32, .write_count = sh_cmt_write32, }, - [SH_CMT_48BIT_GEN2] = { - .model = SH_CMT_48BIT_GEN2, + [SH_CMT1_RCAR_GEN2] = { + .model = SH_CMT1_RCAR_GEN2, + .channels_mask = 0xff, .width = 32, .overflow_bit = SH_CMT32_CMCSR_CMF, .clear_bits = ~(SH_CMT32_CMCSR_CMF | SH_CMT32_CMCSR_OVF), @@ -859,6 +865,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index, ch->cmt = cmt; ch->index = index; ch->hwidx = hwidx; + ch->timer_bit = hwidx; /* * Compute the address of the channel control register block. For the @@ -873,16 +880,11 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index, case SH_CMT_48BIT: ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10; break; - case SH_CMT_32BIT_FAST: - /* - * The 32-bit "fast" timer has a single channel at hwidx 5 but - * is located at offset 0x40 instead of 0x60 for some reason. - */ - ch->ioctrl = cmt->mapbase + 0x40; - break; - case SH_CMT_48BIT_GEN2: + case SH_CMT0_RCAR_GEN2: + case SH_CMT1_RCAR_GEN2: ch->iostart = cmt->mapbase + ch->hwidx * 0x100; ch->ioctrl = ch->iostart + 0x10; + ch->timer_bit = 0; break; } @@ -894,8 +896,6 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index, ch->match_value = ch->max_match_value; raw_spin_lock_init(&ch->lock); - ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2 ? 0 : ch->hwidx; - ret = sh_cmt_register(ch, dev_name(&cmt->pdev->dev), clockevent, clocksource); if (ret) { @@ -935,22 +935,18 @@ static const struct platform_device_id sh_cmt_id_table[] = { MODULE_DEVICE_TABLE(platform, sh_cmt_id_table); static const struct of_device_id sh_cmt_of_table[] __maybe_unused = { - { .compatible = "renesas,cmt-32", .data = &sh_cmt_info[SH_CMT_32BIT] }, - { .compatible = "renesas,cmt-32-fast", .data = &sh_cmt_info[SH_CMT_32BIT_FAST] }, { .compatible = "renesas,cmt-48", .data = &sh_cmt_info[SH_CMT_48BIT] }, - { .compatible = "renesas,cmt-48-gen2", .data = &sh_cmt_info[SH_CMT_48BIT_GEN2] }, + { + /* deprecated, preserved for backward compatibility */ + .compatible = "renesas,cmt-48-gen2", + .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2] + }, + { .compatible = "renesas,rcar-gen2-cmt0", .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2] }, + { .compatible = "renesas,rcar-gen2-cmt1", .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2] }, { } }; MODULE_DEVICE_TABLE(of, sh_cmt_of_table); -static int sh_cmt_parse_dt(struct sh_cmt_device *cmt) -{ - struct device_node *np = cmt->pdev->dev.of_node; - - return of_property_read_u32(np, "renesas,channels-mask", - &cmt->hw_channels); -} - static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) { unsigned int mask; @@ -961,14 +957,8 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) raw_spin_lock_init(&cmt->lock); if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { - const struct of_device_id *id; - - id = of_match_node(sh_cmt_of_table, pdev->dev.of_node); - cmt->info = id->data; - - ret = sh_cmt_parse_dt(cmt); - if (ret < 0) - return ret; + cmt->info = of_device_get_match_data(&pdev->dev); + cmt->hw_channels = cmt->info->channels_mask; } else if (pdev->dev.platform_data) { struct sh_timer_config *cfg = pdev->dev.platform_data; const struct platform_device_id *id = pdev->id_entry; diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c index 6a8d9838ce33..3f94e454ef99 100644 --- a/drivers/clocksource/tango_xtal.c +++ b/drivers/clocksource/tango_xtal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/clocksource.h> #include <linux/sched_clock.h> #include <linux/of_address.h> diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 59e8aee0ec16..9de47d4d2d9e 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/init.h> #include <linux/clocksource.h> #include <linux/clockchips.h> diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c index 66dd909960c6..c020038ebfab 100644 --- a/drivers/clocksource/timer-fttmr010.c +++ b/drivers/clocksource/timer-fttmr010.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Faraday Technology FTTMR010 timer driver * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> @@ -263,14 +264,14 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) fttmr010->base = of_iomap(np, 0); if (!fttmr010->base) { - pr_err("Can't remap registers"); + pr_err("Can't remap registers\n"); ret = -ENXIO; goto out_free; } /* IRQ for timer 1 */ irq = irq_of_parse_and_map(np, 0); if (irq <= 0) { - pr_err("Can't parse IRQ"); + pr_err("Can't parse IRQ\n"); ret = -EINVAL; goto out_unmap; } diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c index c79122d8e10d..7c64a5c1bfc1 100644 --- a/drivers/clocksource/timer-of.c +++ b/drivers/clocksource/timer-of.c @@ -176,3 +176,15 @@ out_fail: timer_base_exit(&to->of_base); return ret; } + +void timer_of_exit(struct timer_of *to) +{ + if (to->flags & TIMER_OF_IRQ) + timer_irq_exit(&to->of_irq); + + if (to->flags & TIMER_OF_CLOCK) + timer_clk_exit(&to->of_clk); + + if (to->flags & TIMER_OF_BASE) + timer_base_exit(&to->of_base); +} diff --git a/drivers/clocksource/timer-of.h b/drivers/clocksource/timer-of.h index e0d727255f72..43f5ba3f8979 100644 --- a/drivers/clocksource/timer-of.h +++ b/drivers/clocksource/timer-of.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TIMER_OF_H__ #define __TIMER_OF_H__ @@ -66,4 +67,7 @@ static inline unsigned long timer_of_period(struct timer_of *to) extern int __init timer_of_init(struct device_node *np, struct timer_of *to); + +extern void timer_of_exit(struct timer_of *to); + #endif diff --git a/drivers/clocksource/timer-sp.h b/drivers/clocksource/timer-sp.h index 050d88561e9c..b2037eb94a41 100644 --- a/drivers/clocksource/timer-sp.h +++ b/drivers/clocksource/timer-sp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ARM timer implementation, found in Integrator, Versatile and Realview * platforms. Not all platforms support all registers and bits in these |