diff options
Diffstat (limited to 'drivers/clocksource')
26 files changed, 363 insertions, 194 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 7bc69afd78..5ee83d2b38 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "Clocksource" config ARCH_HAS_IMX_GPT @@ -41,11 +42,11 @@ config CLOCKSOURCE_DUMMY_RATE config CLOCKSOURCE_EFI bool "Generic EFI Driver" - depends on EFI_BOOTUP + depends on EFI_PAYLOAD config CLOCKSOURCE_EFI_X86 bool "EFI X86 HW driver" - depends on EFI_BOOTUP && X86 + depends on EFI_PAYLOAD && X86 config CLOCKSOURCE_KVX bool "KVX core timer clocksource" @@ -108,10 +109,19 @@ config RISCV_TIMER required for all RISC-V systems. config CLINT_TIMER - bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST - depends on OFDEVICE + bool "CLINT Timer for the RISC-V platform" + depends on RISCV && OFDEVICE help This option enables the CLINT timer for RISC-V systems. The CLINT driver is usually used for NoMMU RISC-V systems. +config ARMV7M_SYSTICK + bool "Support for the ARMv7M system timer" if COMPILE_TEST + help + This option enables support for the ARMv7M system timer unit. + +config CLKSRC_STM32 + bool "Clocksource for STM32 SoCs" + depends on OFDEVICE && (ARCH_STM32 || COMPILE_TEST) + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index e3d243eb94..eceaa990d4 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_AMBA_SP804) += amba-sp804.o obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o obj-$(CONFIG_CLOCKSOURCE_BCM283X) += bcm2835.o @@ -23,3 +24,5 @@ obj-$(CONFIG_CLOCKSOURCE_TI_DM) += timer-ti-dm.o obj-$(CONFIG_CLOCKSOURCE_TI_32K) += timer-ti-32k.o obj-$(CONFIG_CLINT_TIMER) += timer-clint.o obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o +obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o +obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o diff --git a/drivers/clocksource/amba-sp804.c b/drivers/clocksource/amba-sp804.c index 0c0ecaa83a..fcb2b0254b 100644 --- a/drivers/clocksource/amba-sp804.c +++ b/drivers/clocksource/amba-sp804.c @@ -1,7 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> - * - * Under GPL v2 */ #include <common.h> #include <init.h> @@ -27,6 +26,7 @@ static struct clocksource sp804_clksrc = { .read = sp804_read, .shift = 20, .mask = CLOCKSOURCE_MASK(32), + .priority = 60, }; static int sp804_probe(struct amba_device *dev, const struct amba_id *id) diff --git a/drivers/clocksource/arm_architected_timer.c b/drivers/clocksource/arm_architected_timer.c index 3ca7dfd17d..9a1f2d2b79 100644 --- a/drivers/clocksource/arm_architected_timer.c +++ b/drivers/clocksource/arm_architected_timer.c @@ -1,16 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2018 Sascha Hauer <s.hauer@pengutronix.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -29,9 +19,10 @@ static struct clocksource cs = { .read = arm_arch_clocksource_read, .mask = CLOCKSOURCE_MASK(64), .shift = 0, + .priority = 70, }; -static int arm_arch_timer_probe(struct device_d *dev) +static int arm_arch_timer_probe(struct device *dev) { cs.mult = clocksource_hz2mult(get_cntfrq(), cs.shift); @@ -43,8 +34,9 @@ static struct of_device_id arm_arch_timer_dt_ids[] = { { .compatible = "arm,armv8-timer", }, { } }; +MODULE_DEVICE_TABLE(of, arm_arch_timer_dt_ids); -static struct driver_d arm_arch_timer_driver = { +static struct driver arm_arch_timer_driver = { .name = "arm-architected-timer", .probe = arm_arch_timer_probe, .of_compatible = DRV_OF_COMPAT(arm_arch_timer_dt_ids), diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index 78cd72d3eb..969985f24e 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Clocksource driver for generic Cortex A9 timer block @@ -60,9 +60,10 @@ static struct clocksource cs = { .read = arm_global_clocksource_read, .mask = CLOCKSOURCE_MASK(64), .shift = 0, + .priority = 70, }; -static int arm_global_timer_probe(struct device_d *dev) +static int arm_global_timer_probe(struct device *dev) { struct resource *iores; struct clk *clk; @@ -102,8 +103,9 @@ static struct of_device_id arm_global_timer_dt_ids[] = { { .compatible = "arm,cortex-a9-global-timer", }, { } }; +MODULE_DEVICE_TABLE(of, arm_global_timer_dt_ids); -static struct driver_d arm_global_timer_driver = { +static struct driver arm_global_timer_driver = { .name = "arm-global-timer", .probe = arm_global_timer_probe, .of_compatible = DRV_OF_COMPAT(arm_global_timer_dt_ids), diff --git a/drivers/clocksource/arm_smp_twd.c b/drivers/clocksource/arm_smp_twd.c index 5a1e5a7921..e677acf136 100644 --- a/drivers/clocksource/arm_smp_twd.c +++ b/drivers/clocksource/arm_smp_twd.c @@ -1,7 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> - * - * Under GPL v2 */ #include <common.h> #include <init.h> @@ -36,11 +35,12 @@ static struct clocksource smp_twd_clksrc = { .read = smp_twd_read, .shift = 20, .mask = CLOCKSOURCE_MASK(32), + .priority = 60, }; #define SMP_TWD_MAX_FREQ (25 *1000 * 1000) -static int smp_twd_probe(struct device_d *dev) +static int smp_twd_probe(struct device *dev) { struct resource *iores; u32 tick_rate; @@ -98,8 +98,9 @@ static __maybe_unused struct of_device_id smp_twd_compatible[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, smp_twd_compatible); -static struct driver_d smp_twd_driver = { +static struct driver smp_twd_driver = { .name = "smp_twd", .probe = smp_twd_probe, .of_compatible = DRV_OF_COMPAT(smp_twd_compatible), diff --git a/drivers/clocksource/armv7m_systick.c b/drivers/clocksource/armv7m_systick.c new file mode 100644 index 0000000000..eee028d12a --- /dev/null +++ b/drivers/clocksource/armv7m_systick.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) Maxime Coquelin 2015 + * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> + */ + +#include <common.h> +#include <init.h> +#include <clock.h> +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> + +#define SYST_CSR 0x00 +#define SYST_RVR 0x04 +#define SYST_CVR 0x08 +#define SYST_CALIB 0x0c + +#define SYSTICK_CTRL_EN BIT(0) +/* Clock source: 0 = Ref clock, 1 = CPU clock */ +#define SYSTICK_CTRL_CPU_CLK BIT(2) +#define SYSTICK_CAL_NOREF BIT(31) + +#define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF + +static __iomem void *systick_base; + +static u64 armv7m_systick_clocksource_read(void) +{ + return SYSTICK_LOAD_RELOAD_MASK - readl(systick_base + SYST_CVR); +} + +static struct clocksource cs = { + .read = armv7m_systick_clocksource_read, + .mask = CLOCKSOURCE_MASK(24), + .shift = 0, + .priority = 70, +}; + +static int armv7m_systick_probe(struct device *dev) +{ + struct clk *clk = NULL; + u32 rate, cal; + int ret; + + systick_base = dev_request_mem_region_err_null(dev, 0); + if (!systick_base) + return -ENOENT; + + ret = of_property_read_u32(dev->of_node, "clock-frequency", &rate); + if (ret) { + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + ret = clk_enable(clk); + if (ret) + return ret; + + rate = clk_get_rate(clk); + if (!rate) + return -EINVAL; + } + + writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, systick_base + SYST_RVR); + + cal = readl(systick_base + SYST_CALIB); + if (cal & SYSTICK_CAL_NOREF) + writel(SYSTICK_CTRL_EN | SYSTICK_CTRL_CPU_CLK, systick_base + SYST_CSR); + else + writel(SYSTICK_CTRL_EN, systick_base + SYST_CSR); + + cs.mult = clocksource_hz2mult(rate, cs.shift); + + return init_clock(&cs); +} + +static struct of_device_id armv7m_systick_dt_ids[] = { + { .compatible = "arm,armv7m-systick", }, + { } +}; +MODULE_DEVICE_TABLE(of, armv7m_systick_dt_ids); + +static struct driver armv7m_systick_driver = { + .name = "armv7m-systick-timer", + .probe = armv7m_systick_probe, + .of_compatible = DRV_OF_COMPAT(armv7m_systick_dt_ids), +}; +postcore_platform_driver(armv7m_systick_driver); diff --git a/drivers/clocksource/bcm2835.c b/drivers/clocksource/bcm2835.c index 179109aee2..73f4e8f411 100644 --- a/drivers/clocksource/bcm2835.c +++ b/drivers/clocksource/bcm2835.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Author: Carlo Caione <carlo@carlocaione.org> * * Based on clocksource for nomadik - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ @@ -38,9 +28,11 @@ static uint64_t stc_read_cycles(void) static struct clocksource bcm2835_stc = { .read = stc_read_cycles, .mask = CLOCKSOURCE_MASK(32), + /* Give the architected timer precedence on AArch64 */ + .priority = IS_ENABLED(CONFIG_CPU_V8) ? 60 : 80, }; -static int bcm2835_cs_probe(struct device_d *dev) +static int bcm2835_cs_probe(struct device *dev) { struct resource *iores; static struct clk *stc_clk; @@ -49,7 +41,7 @@ static int bcm2835_cs_probe(struct device_d *dev) /* try to read rate from DT property first */ if (IS_ENABLED(CONFIG_OFTREE)) - of_property_read_u32(dev->device_node, "clock-frequency", + of_property_read_u32(dev->of_node, "clock-frequency", &rate); /* if rate is still empty, try to get rate from clk */ @@ -88,8 +80,9 @@ static __maybe_unused struct of_device_id bcm2835_cs_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, bcm2835_cs_dt_ids); -static struct driver_d bcm2835_cs_driver = { +static struct driver bcm2835_cs_driver = { .name = "bcm2835-cs", .probe = bcm2835_cs_probe, .of_compatible = DRV_OF_COMPAT(bcm2835_cs_dt_ids), diff --git a/drivers/clocksource/clps711x.c b/drivers/clocksource/clps711x.c index a99147f30c..f8bdc06ea8 100644 --- a/drivers/clocksource/clps711x.c +++ b/drivers/clocksource/clps711x.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0-or-later /* Author: Alexander Shiyan <shc_work@mail.ru> */ #include <common.h> @@ -19,13 +19,19 @@ static uint64_t clps711x_cs_read(void) static struct clocksource clps711x_cs = { .read = clps711x_cs_read, .mask = CLOCKSOURCE_MASK(16), + .priority = 60, }; -static int clps711x_cs_probe(struct device_d *dev) +static int clps711x_cs_probe(struct device *dev) { struct resource *iores; u32 rate; struct clk *timer_clk; + int id; + + id = of_alias_get_id(dev->of_node, "timer"); + if (id != 1) + return 0; timer_clk = clk_get(dev, NULL); if (IS_ERR(timer_clk)) @@ -45,12 +51,13 @@ static int clps711x_cs_probe(struct device_d *dev) return init_clock(&clps711x_cs); } -static __maybe_unused struct of_device_id clps711x_timer_dt_ids[] = { +static const struct of_device_id __maybe_unused clps711x_timer_dt_ids[] = { { .compatible = "cirrus,ep7209-timer", }, { } }; +MODULE_DEVICE_TABLE(of, clps711x_timer_dt_ids); -static struct driver_d clps711x_cs_driver = { +static struct driver clps711x_cs_driver = { .name = "clps711x-cs", .probe = clps711x_cs_probe, .of_compatible = DRV_OF_COMPAT(clps711x_timer_dt_ids), diff --git a/drivers/clocksource/digic.c b/drivers/clocksource/digic.c index 9079733eba..38c4bd7dd2 100644 --- a/drivers/clocksource/digic.c +++ b/drivers/clocksource/digic.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2013, 2014 Antony Pavlov <antonynpavlov@gmail.com> * * This file is part of barebox. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -35,9 +26,10 @@ static uint64_t digic_cs_read(void) static struct clocksource digic_cs = { .read = digic_cs_read, .mask = CLOCKSOURCE_MASK(16), + .priority = 60, }; -static int digic_timer_probe(struct device_d *dev) +static int digic_timer_probe(struct device *dev) { struct resource *iores; /* use only one timer */ @@ -81,8 +73,9 @@ static __maybe_unused struct of_device_id digic_timer_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, digic_timer_dt_ids); -static struct driver_d digic_timer_driver = { +static struct driver digic_timer_driver = { .probe = digic_timer_probe, .name = "digic-timer", .of_compatible = DRV_OF_COMPAT(digic_timer_dt_ids), diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index 82ad6bccbc..3826c7490d 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c @@ -1,16 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * (C) Copyright 2009 Intel Corporation * Author: Jacob Pan (jacob.jun.pan@intel.com) * * Shared with ARM platforms, Jamie Iles, Picochip 2011 * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Support for the Synopsys DesignWare APB Timers. * - * * Taken from linux-4.9 kernel and adapted to barebox. */ #include <common.h> @@ -98,11 +94,12 @@ static struct clocksource dw_apb_clksrc = { .read = dw_apb_clocksource_read, .mask = CLOCKSOURCE_MASK(32), .shift = 0, + .priority = 50, }; -static int dw_apb_timer_probe(struct device_d *dev) +static int dw_apb_timer_probe(struct device *dev) { - struct device_node *np = dev->device_node; + struct device_node *np = dev->of_node; struct resource *iores; struct clk *clk; uint32_t clk_freq; @@ -138,8 +135,9 @@ static struct of_device_id dw_apb_timer_dt_ids[] = { { .compatible = "snps,dw-apb-timer", }, { } }; +MODULE_DEVICE_TABLE(of, dw_apb_timer_dt_ids); -static struct driver_d dw_apb_timer_driver = { +static struct driver dw_apb_timer_driver = { .name = "dw-apb-timer", .probe = dw_apb_timer_probe, .of_compatible = DRV_OF_COMPAT(dw_apb_timer_dt_ids), diff --git a/drivers/clocksource/efi.c b/drivers/clocksource/efi.c index 658d146fb5..1ac587a715 100644 --- a/drivers/clocksource/efi.c +++ b/drivers/clocksource/efi.c @@ -1,26 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> - * - * Under GPL v2 */ #include <common.h> #include <init.h> #include <driver.h> #include <clock.h> #include <efi.h> -#include <efi/efi.h> +#include <efi/efi-payload.h> #include <efi/efi-device.h> #include <linux/err.h> static uint64_t ticks = 1; -static void *efi_cs_evt; +static struct efi_event *efi_cs_evt; static uint64_t efi_cs_read(void) { return ticks; } -static void efi_cs_inc(void *event, void *ctx) +static void efi_cs_inc(struct efi_event *event, void *ctx) { ticks++; } @@ -94,14 +93,15 @@ static struct clocksource efi_cs = { .mask = CLOCKSOURCE_MASK(64), .shift = 0, .init = efi_cs_init, + .priority = 80, }; -static int efi_cs_probe(struct device_d *dev) +static int efi_cs_probe(struct device *dev) { return init_clock(&efi_cs); } -static struct driver_d efi_cs_driver = { +static struct driver efi_cs_driver = { .name = "efi-cs", .probe = efi_cs_probe, }; diff --git a/drivers/clocksource/efi_x86.c b/drivers/clocksource/efi_x86.c index 364e1ef8e1..f5a822eef7 100644 --- a/drivers/clocksource/efi_x86.c +++ b/drivers/clocksource/efi_x86.c @@ -1,8 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only #include <common.h> #include <init.h> #include <driver.h> #include <efi.h> -#include <efi/efi.h> +#include <efi/efi-payload.h> #include <clock.h> #ifdef __x86_64__ @@ -61,12 +62,12 @@ static struct clocksource efi_x86_cs = { .init = efi_x86_cs_init, }; -static int efi_x86_cs_probe(struct device_d *dev) +static int efi_x86_cs_probe(struct device *dev) { return init_clock(&efi_x86_cs); } -static struct driver_d efi_x86_cs_driver = { +static struct driver efi_x86_cs_driver = { .name = "efi-cs-x86", .probe = efi_x86_cs_probe, }; diff --git a/drivers/clocksource/kvx_timer.c b/drivers/clocksource/kvx_timer.c index 4125ddbee0..eaa8f63b1e 100644 --- a/drivers/clocksource/kvx_timer.c +++ b/drivers/clocksource/kvx_timer.c @@ -21,9 +21,10 @@ static struct clocksource kvx_clksrc = { .read = kvx_pm_read, .mask = CLOCKSOURCE_MASK(64), .shift = 0, + .priority = 70, }; -static int kvx_timer_probe(struct device_d *dev) +static int kvx_timer_probe(struct device *dev) { struct clk *clk; uint32_t clk_freq; @@ -48,11 +49,12 @@ static struct of_device_id kvx_timer_dt_ids[] = { { .compatible = "kalray,kvx-core-timer", }, { } }; +MODULE_DEVICE_TABLE(of, kvx_timer_dt_ids); -static struct driver_d kvx_timer_driver = { +static struct driver kvx_timer_driver = { .name = "kvx-timer", .probe = kvx_timer_probe, .of_compatible = DRV_OF_COMPAT(kvx_timer_dt_ids), }; -device_platform_driver(kvx_timer_driver); +postcore_platform_driver(kvx_timer_driver); diff --git a/drivers/clocksource/mvebu.c b/drivers/clocksource/mvebu.c index 5a47d6f217..6a1c3d58de 100644 --- a/drivers/clocksource/mvebu.c +++ b/drivers/clocksource/mvebu.c @@ -1,16 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -52,9 +42,10 @@ static struct clocksource cs = { .read = mvebu_clocksource_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 70, }; -static int mvebu_timer_probe(struct device_d *dev) +static int mvebu_timer_probe(struct device *dev) { struct resource *iores; struct clk *clk; @@ -67,7 +58,7 @@ static int mvebu_timer_probe(struct device_d *dev) val = __raw_readl(timer_base + TIMER_CTRL_OFF); val &= ~(TIMER0_25MHZ | TIMER0_DIV_MASK); - if (of_device_is_compatible(dev->device_node, + if (of_device_is_compatible(dev->of_node, "marvell,armada-370-timer")) { clk = clk_get(dev, NULL); div = TIMER_DIVIDER; @@ -98,8 +89,9 @@ static struct of_device_id mvebu_timer_dt_ids[] = { { .compatible = "marvell,armada-xp-timer", }, { } }; +MODULE_DEVICE_TABLE(of, mvebu_timer_dt_ids); -static struct driver_d mvebu_timer_driver = { +static struct driver mvebu_timer_driver = { .name = "mvebu-timer", .probe = mvebu_timer_probe, .of_compatible = DRV_OF_COMPAT(mvebu_timer_dt_ids), diff --git a/drivers/clocksource/nomadik.c b/drivers/clocksource/nomadik.c index 7d5d9f9f77..cffe9cdd03 100644 --- a/drivers/clocksource/nomadik.c +++ b/drivers/clocksource/nomadik.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * linux/arch/arm/mach-nomadik/timer.c * * Copyright (C) 2008 STMicroelectronics * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. */ #include <common.h> #include <clock.h> @@ -74,6 +71,7 @@ static struct clocksource nmdk_clksrc = { .read = nmdk_read_timer, .shift = 20, .mask = CLOCKSOURCE_MASK(32), + .priority = 60, }; static void nmdk_timer_reset(void) @@ -92,7 +90,7 @@ static void nmdk_timer_reset(void) writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); } -static int nmdk_mtu_probe(struct device_d *dev) +static int nmdk_mtu_probe(struct device *dev) { struct resource *iores; static struct clk *mtu_clk; @@ -137,7 +135,7 @@ static int nmdk_mtu_probe(struct device_d *dev) return init_clock(&nmdk_clksrc); } -static struct driver_d nmdk_mtu_driver = { +static struct driver nmdk_mtu_driver = { .name = "nomadik_mtu", .probe = nmdk_mtu_probe, }; diff --git a/drivers/clocksource/orion.c b/drivers/clocksource/orion.c index c9f50b729e..caa314e884 100644 --- a/drivers/clocksource/orion.c +++ b/drivers/clocksource/orion.c @@ -1,17 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright * (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -41,9 +31,10 @@ static struct clocksource clksrc = { .read = orion_clocksource_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 70, }; -static int orion_timer_probe(struct device_d *dev) +static int orion_timer_probe(struct device *dev) { struct resource *iores; struct clk *tclk; @@ -72,8 +63,9 @@ static struct of_device_id orion_timer_dt_ids[] = { { .compatible = "marvell,orion-timer", }, { } }; +MODULE_DEVICE_TABLE(of, orion_timer_dt_ids); -static struct driver_d orion_timer_driver = { +static struct driver orion_timer_driver = { .name = "orion-timer", .probe = orion_timer_probe, .of_compatible = DRV_OF_COMPAT(orion_timer_dt_ids), diff --git a/drivers/clocksource/rk_timer.c b/drivers/clocksource/rk_timer.c index 5cc8d32b60..eb6c886af0 100644 --- a/drivers/clocksource/rk_timer.c +++ b/drivers/clocksource/rk_timer.c @@ -10,12 +10,20 @@ #include <clock.h> #include <init.h> #include <io.h> -#include <mach/timer.h> #include <stdio.h> -#include <mach/hardware.h> -#include <mach/cru_rk3288.h> +#include <mach/rockchip/hardware.h> +#include <mach/rockchip/cru_rk3288.h> #include <common.h> +struct rk_timer { + unsigned int timer_load_count0; + unsigned int timer_load_count1; + unsigned int timer_curr_value0; + unsigned int timer_curr_value1; + unsigned int timer_ctrl_reg; + unsigned int timer_int_status; +}; + struct rk_timer *timer_ptr; static uint64_t rockchip_get_ticks(void) @@ -32,9 +40,10 @@ static struct clocksource rkcs = { .read = rockchip_get_ticks, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 80, }; -static int rockchip_timer_probe(struct device_d *dev) +static int rockchip_timer_probe(struct device *dev) { struct resource *iores; @@ -59,8 +68,9 @@ static __maybe_unused struct of_device_id rktimer_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, rktimer_dt_ids); -static struct driver_d rktimer_driver = { +static struct driver rktimer_driver = { .name = "rockchip-timer", .probe = rockchip_timer_probe, .of_compatible = DRV_OF_COMPAT(rktimer_dt_ids), diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index 368aae2450..9d2ff32c48 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -9,24 +10,13 @@ * * (C) Copyright 2002 * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> #include <init.h> #include <clock.h> -#include <mach/hardware.h> -#include <mach/at91_pit.h> +#include <mach/at91/hardware.h> +#include <mach/at91/at91_pit.h> #include <io.h> #include <linux/clk.h> #include <linux/err.h> @@ -46,6 +36,7 @@ static struct clocksource cs = { .read = at91sam9_clocksource_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 70, }; static void at91_pit_stop(void) @@ -65,7 +56,7 @@ static void at91sam926x_pit_reset(void) pit_write(AT91_PIT_MR, 0xfffff | AT91_PIT_PITEN); } -static int at91_pit_probe(struct device_d *dev) +static int at91_pit_probe(struct device *dev) { struct clk *clk; u32 pit_rate; @@ -105,8 +96,9 @@ const static __maybe_unused struct of_device_id at91_pit_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, at91_pit_dt_ids); -static struct driver_d at91_pit_driver = { +static struct driver at91_pit_driver = { .name = "at91-pit", .probe = at91_pit_probe, .of_compatible = DRV_OF_COMPAT(at91_pit_dt_ids), diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c index 412ce3e1e9..f264eb4cee 100644 --- a/drivers/clocksource/timer-clint.c +++ b/drivers/clocksource/timer-clint.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2020 Western Digital Corporation or its affiliates. * @@ -60,7 +60,7 @@ static struct clocksource clint_clocksource = { .priority = 200, }; -static int clint_timer_init_dt(struct device_d* dev) +static int clint_timer_init_dt(struct device * dev) { struct resource *iores; @@ -85,8 +85,9 @@ static struct of_device_id timer_clint_dt_ids[] = { { .compatible = "sifive,clint0" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, timer_clint_dt_ids); -static struct driver_d clint_timer_driver = { +static struct driver clint_timer_driver = { .name = "clint-timer", .probe = clint_timer_init_dt, .of_compatible = timer_clint_dt_ids, diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c index 6be0afed4d..6cf60ed3fc 100644 --- a/drivers/clocksource/timer-imx-gpt.c +++ b/drivers/clocksource/timer-imx-gpt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -9,17 +10,6 @@ * * (C) Copyright 2002 * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -74,6 +64,7 @@ static struct clocksource cs = { .read = imx_clocksource_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 70, }; static int imx_clocksource_clock_change(struct notifier_block *nb, unsigned long event, void *data) @@ -86,7 +77,7 @@ static struct notifier_block imx_clock_notifier = { .notifier_call = imx_clocksource_clock_change, }; -static int imx_gpt_probe(struct device_d *dev) +static int imx_gpt_probe(struct device *dev) { struct resource *iores; int i; @@ -162,6 +153,7 @@ static __maybe_unused struct of_device_id imx_gpt_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx_gpt_dt_ids); static struct platform_device_id imx_gpt_ids[] = { { @@ -175,7 +167,7 @@ static struct platform_device_id imx_gpt_ids[] = { }, }; -static struct driver_d imx_gpt_driver = { +static struct driver imx_gpt_driver = { .name = "imx-gpt", .probe = imx_gpt_probe, .of_compatible = DRV_OF_COMPAT(imx_gpt_dt_ids), diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index 96637f988a..93f88711dc 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2012 Regents of the University of California * Copyright (C) 2017 SiFive @@ -48,7 +48,7 @@ static struct clocksource riscv_clocksource = { .priority = 100, }; -static int riscv_timer_init(struct device_d* dev) +static int riscv_timer_init(struct device * dev) { struct device_node *cpu; @@ -67,7 +67,7 @@ static int riscv_timer_init(struct device_d* dev) return init_clock(&riscv_clocksource); } -static struct driver_d riscv_timer_driver = { +static struct driver riscv_timer_driver = { .name = "riscv-timer", .probe = riscv_timer_init, }; diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c new file mode 100644 index 0000000000..d653beb0eb --- /dev/null +++ b/drivers/clocksource/timer-stm32.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. + */ + +#include <common.h> +#include <linux/clk.h> +#include <clock.h> +#include <init.h> +#include <io.h> + +/* Timer control1 register */ +#define CR1_CEN BIT(0) +#define CR1_ARPE BIT(7) + +/* Event Generation Register register */ +#define EGR_UG BIT(0) + +/* Auto reload register for free running config */ +#define GPT_FREE_RUNNING 0xFFFFFFFF + +#define MHZ_1 1000000 + +struct stm32_timer_regs { + u32 cr1; + u32 cr2; + u32 smcr; + u32 dier; + u32 sr; + u32 egr; + u32 ccmr1; + u32 ccmr2; + u32 ccer; + u32 cnt; + u32 psc; + u32 arr; + u32 reserved; + u32 ccr1; + u32 ccr2; + u32 ccr3; + u32 ccr4; + u32 reserved1; + u32 dcr; + u32 dmar; + u32 tim2_5_or; +}; + +static struct stm32_timer_regs *timer_base; + +static u64 stm32_timer_read(void) +{ + return readl(&timer_base->cnt); +} + +/* A bit obvious isn't it? */ +static struct clocksource cs = { + .read = stm32_timer_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 0, + .priority = 100, +}; + +static int stm32_timer_probe(struct device *dev) +{ + struct resource *iores; + struct clk *clk; + u32 rate, psc; + int ret; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + + timer_base = IOMEM(iores->start); + + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + ret = clk_enable(clk); + if (ret) + return ret; + + /* Stop the timer */ + clrbits_le32(&timer_base->cr1, CR1_CEN); + + /* get timer clock */ + rate = clk_get_rate(clk); + + /* we set timer prescaler to obtain a 1MHz timer counter frequency */ + psc = (rate / MHZ_1) - 1; + writel(psc, &timer_base->psc); + + /* Configure timer for auto-reload */ + setbits_le32(&timer_base->cr1, CR1_ARPE); + + /* load value for auto reload */ + writel(GPT_FREE_RUNNING, &timer_base->arr); + + /* start timer */ + setbits_le32(&timer_base->cr1, CR1_CEN); + + /* Update generation */ + setbits_le32(&timer_base->egr, EGR_UG); + + cs.mult = clocksource_hz2mult(MHZ_1, cs.shift); + + return init_clock(&cs); +} + +static struct of_device_id stm32_timer_dt_ids[] = { + { .compatible = "st,stm32-timer" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, stm32_timer_dt_ids); + +static struct driver stm32_timer_driver = { + .name = "stm32-timer", + .probe = stm32_timer_probe, + .of_compatible = stm32_timer_dt_ids, +}; +postcore_platform_driver(stm32_timer_driver); diff --git a/drivers/clocksource/timer-ti-32k.c b/drivers/clocksource/timer-ti-32k.c index 755c78095f..1880082066 100644 --- a/drivers/clocksource/timer-ti-32k.c +++ b/drivers/clocksource/timer-ti-32k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /** * @file * @brief Provide @ref clocksource functionality for OMAP @@ -9,28 +10,18 @@ * (C) Copyright 2008 * Texas Instruments, <www.ti.com> * Nishanth Menon <x0nishan@ti.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <common.h> #include <clock.h> #include <init.h> #include <io.h> -#include <mach/omap3-silicon.h> -#include <mach/omap4-silicon.h> -#include <mach/clocks.h> -#include <mach/timers.h> -#include <mach/sys_info.h> -#include <mach/syslib.h> +#include <mach/omap/omap3-silicon.h> +#include <mach/omap/omap4-silicon.h> +#include <mach/omap/clocks.h> +#include <mach/omap/timers.h> +#include <mach/omap/sys_info.h> +#include <mach/omap/syslib.h> /** Sync 32Khz Timer registers */ #define S32K_CR 0x10 @@ -56,6 +47,7 @@ static struct clocksource s32k_cs = { .read = s32k_clocksource_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 70, }; /** @@ -67,7 +59,7 @@ static struct clocksource s32k_cs = { * * @return result of @ref init_clock */ -static int omap_32ktimer_probe(struct device_d *dev) +static int omap_32ktimer_probe(struct device *dev) { struct resource *iores; @@ -92,8 +84,9 @@ static __maybe_unused struct of_device_id omap_32ktimer_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, omap_32ktimer_dt_ids); -static struct driver_d omap_32ktimer_driver = { +static struct driver omap_32ktimer_driver = { .name = "omap-32ktimer", .probe = omap_32ktimer_probe, .of_compatible = DRV_OF_COMPAT(omap_32ktimer_dt_ids), diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index 86882fcaf5..8473cf733d 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /** * @file * @brief Support DMTimer counter @@ -14,25 +15,14 @@ * Author: Teresa Gámez <t.gamez@phytec.de> * (C) Copyright 2015 Phytec Messtechnik GmbH * Author: Daniel Schultz <d.schultz@phytec.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> #include <clock.h> #include <init.h> #include <io.h> -#include <mach/am33xx-silicon.h> -#include <mach/am33xx-clock.h> +#include <mach/omap/am33xx-silicon.h> +#include <mach/omap/am33xx-clock.h> #include <stdio.h> @@ -72,9 +62,10 @@ static struct clocksource dmtimer_cs = { .read = dmtimer_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, + .priority = 70, }; -static int omap_dmtimer_probe(struct device_d *dev) +static int omap_dmtimer_probe(struct device *dev) { struct resource *iores; u64 clk_speed; @@ -105,8 +96,9 @@ static __maybe_unused struct of_device_id omap_dmtimer_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, omap_dmtimer_dt_ids); -static struct driver_d omap_dmtimer_driver = { +static struct driver omap_dmtimer_driver = { .name = "omap-dmtimer", .probe = omap_dmtimer_probe, .of_compatible = DRV_OF_COMPAT(omap_dmtimer_dt_ids), diff --git a/drivers/clocksource/uemd.c b/drivers/clocksource/uemd.c index 02fa8a1c5b..283fb6d4aa 100644 --- a/drivers/clocksource/uemd.c +++ b/drivers/clocksource/uemd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com> * @@ -6,16 +7,6 @@ * (C) 2011 RC Module, Sergey Mironov <ierton@gmail.com> * * This file is part of barebox. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -61,9 +52,10 @@ static uint64_t uemd_timer_cs_read(void) static struct clocksource uemd_cs = { .read = uemd_timer_cs_read, .mask = CLOCKSOURCE_MASK(32), + .priority = 60, }; -static int uemd_timer_probe(struct device_d *dev) +static int uemd_timer_probe(struct device *dev) { struct resource *iores; int mode; @@ -116,8 +108,9 @@ static __maybe_unused struct of_device_id uemd_timer_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, uemd_timer_dt_ids); -static struct driver_d uemd_timer_driver = { +static struct driver uemd_timer_driver = { .probe = uemd_timer_probe, .name = "uemd-timer", .of_compatible = DRV_OF_COMPAT(uemd_timer_dt_ids), |