mirror of https://gitee.com/openkylin/linux.git
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "The timer department delivers the following christmas presents: Core code: - Use proper seqcount initializer to make lockdep happy - SPDX annotations and cleanup of license boilerplates - Use DEFINE_SHOW_ATTRIBUTE() instead of open coding it - Minor cleanups Driver code: - Add the sched_clock for the arc timer (Alexey Brodkin) - Change the file timer names for riscv, rockchip, tegra20, sun4i and meson6 (Daniel Lezcano) - Add the DT bindings for r8a7796, r8a77470 and r8a774a1 (Biju Das) - Remove the early platform driver registration for timer-ti-dm (Bartosz Golaszewski) - Provide the sched_clock for the riscv timer (Anup Patel) - Add support for ARM64 for the imx-gpt and convert the imx-tpm to the timer-of API (Anson Huang) - Remove useless irq protection for the imx-gpt (Clément Péron) - Remove a duplicate function name for the vt8500 (Dan Carpenter) - Remove obsolete inclusion of <asm/smp_twd.h> for the tegra20 (Geert Uytterhoeven) - Demote the prcmu and the custom sched_clock for the dbx500 and the ux500 (Linus Walleij) - Add a new timer clock for the RDA8810PL (Manivannan Sadhasivam) - Rename the macro to stick to the register name and add the delay timer (Martin Blumenstingl) - Switch the bcm2835 to the SPDX identifier (Stefan Wahren) - Fix the interrupt register access on the fttmr010 (Tao Ren) - Add missing of_node_put in the initialization path on the integrator-ap (Yangtao Li)" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (39 commits) dt-bindings: timer: Document RDA8810PL SoC timer clocksource/drivers/rda: Add clock driver for RDA8810PL SoC clocksource/drivers/meson6: Change name meson6_timer timer-meson6 clocksource/drivers/sun4i: Change name sun4i_timer to timer-sun4i clocksource/drivers/tegra20: Change name tegra20_timer to timer-tegra20 clocksource/drivers/rockchip: Change name rockchip_timer to timer-rockchip clocksource/drivers/riscv: Change name riscv_timer to timer-riscv clocksource/drivers/riscv_timer: Provide the sched_clock clocksource/drivers/timer-imx-tpm: Specify clock name for timer-of clocksource/drivers/fttmr010: Fix invalid interrupt register access clocksource/drivers/integrator-ap: Add missing of_node_put() clocksource/drivers/bcm2835: Switch to SPDX identifier dt-bindings: timer: renesas, cmt: Document r8a774a1 CMT support clocksource/drivers/timer-imx-tpm: Convert the driver to timer-of clocksource/drivers/arc_timer: Utilize generic sched_clock dt-bindings: timer: renesas, cmt: Document r8a77470 CMT support dt-bindings: timer: renesas, cmt: Document r8a7796 CMT support clocksource/drivers/imx-gpt: Remove unnecessary irq protection clocksource/drivers/imx-gpt: Add support for ARM64 clocksource/drivers/meson6_timer: Implement the ARM delay timer ...
This commit is contained in:
commit
9f687dddc4
|
@ -0,0 +1,20 @@
|
|||
RDA Micro RDA8810PL Timer
|
||||
|
||||
Required properties:
|
||||
- compatible : "rda,8810pl-timer"
|
||||
- reg : Offset and length of the register set for the device.
|
||||
- interrupts : Should contain two interrupts.
|
||||
- interrupt-names : Should be "hwtimer", "ostimer".
|
||||
|
||||
Example:
|
||||
|
||||
apb@20900000 {
|
||||
compatible = "simple-bus";
|
||||
...
|
||||
timer@10000 {
|
||||
compatible = "rda,8810pl-timer";
|
||||
reg = <0x10000 0x1000>;
|
||||
interrupts = <16 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "hwtimer", "ostimer";
|
||||
};
|
|
@ -28,6 +28,10 @@ Required Properties:
|
|||
- "renesas,r8a7744-cmt1" for the 48-bit CMT1 device included in r8a7744.
|
||||
- "renesas,r8a7745-cmt0" for the 32-bit CMT0 device included in r8a7745.
|
||||
- "renesas,r8a7745-cmt1" for the 48-bit CMT1 device included in r8a7745.
|
||||
- "renesas,r8a77470-cmt0" for the 32-bit CMT0 device included in r8a77470.
|
||||
- "renesas,r8a77470-cmt1" for the 48-bit CMT1 device included in r8a77470.
|
||||
- "renesas,r8a774a1-cmt0" for the 32-bit CMT0 device included in r8a774a1.
|
||||
- "renesas,r8a774a1-cmt1" for the 48-bit CMT1 device included in r8a774a1.
|
||||
- "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
|
||||
- "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790.
|
||||
- "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791.
|
||||
|
@ -36,6 +40,8 @@ Required Properties:
|
|||
- "renesas,r8a7793-cmt1" for the 48-bit CMT1 device included in r8a7793.
|
||||
- "renesas,r8a7794-cmt0" for the 32-bit CMT0 device included in r8a7794.
|
||||
- "renesas,r8a7794-cmt1" for the 48-bit CMT1 device included in r8a7794.
|
||||
- "renesas,r8a7796-cmt0" for the 32-bit CMT0 device included in r8a7796.
|
||||
- "renesas,r8a7796-cmt1" for the 48-bit CMT1 device included in r8a7796.
|
||||
- "renesas,r8a77970-cmt0" for the 32-bit CMT0 device included in r8a77970.
|
||||
- "renesas,r8a77970-cmt1" for the 48-bit CMT1 device included in r8a77970.
|
||||
- "renesas,r8a77980-cmt0" for the 32-bit CMT0 device included in r8a77980.
|
||||
|
@ -47,9 +53,12 @@ Required Properties:
|
|||
and RZ/G1.
|
||||
These are fallbacks for r8a73a4, R-Car Gen2 and RZ/G1 entries
|
||||
listed above.
|
||||
- "renesas,rcar-gen3-cmt0" for 32-bit CMT0 devices included in R-Car Gen3.
|
||||
- "renesas,rcar-gen3-cmt1" for 48-bit CMT1 devices included in R-Car Gen3.
|
||||
These are fallbacks for R-Car Gen3 entries listed above.
|
||||
- "renesas,rcar-gen3-cmt0" for 32-bit CMT0 devices included in R-Car Gen3
|
||||
and RZ/G2.
|
||||
- "renesas,rcar-gen3-cmt1" for 48-bit CMT1 devices included in R-Car Gen3
|
||||
and RZ/G2.
|
||||
These are fallbacks for R-Car Gen3 and RZ/G2 entries listed
|
||||
above.
|
||||
|
||||
- reg: base address and length of the registers block for the timer module.
|
||||
- interrupts: interrupt-specifier for the timer, one per channel.
|
||||
|
|
|
@ -26,6 +26,7 @@ config ARC
|
|||
select GENERIC_IRQ_SHOW
|
||||
select GENERIC_PCI_IOMAP
|
||||
select GENERIC_PENDING_IRQ if SMP
|
||||
select GENERIC_SCHED_CLOCK
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select HAVE_ARCH_KGDB
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
|
|
|
@ -105,6 +105,14 @@ config OWL_TIMER
|
|||
help
|
||||
Enables the support for the Actions Semi Owl timer driver.
|
||||
|
||||
config RDA_TIMER
|
||||
bool "RDA timer driver" if COMPILE_TEST
|
||||
depends on GENERIC_CLOCKEVENTS
|
||||
select CLKSRC_MMIO
|
||||
select TIMER_OF
|
||||
help
|
||||
Enables the support for the RDA Micro timer driver.
|
||||
|
||||
config SUN4I_TIMER
|
||||
bool "Sun4i timer driver" if COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
|
@ -163,12 +171,6 @@ config CLKSRC_NOMADIK_MTU
|
|||
to multiple interrupt generating programmable
|
||||
32-bit free running decrementing counters.
|
||||
|
||||
config CLKSRC_NOMADIK_MTU_SCHED_CLOCK
|
||||
bool
|
||||
depends on CLKSRC_NOMADIK_MTU
|
||||
help
|
||||
Use the Multi Timer Unit as the sched_clock.
|
||||
|
||||
config CLKSRC_DBX500_PRCMU
|
||||
bool "Clocksource PRCMU Timer" if COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
|
@ -226,13 +228,6 @@ config INTEGRATOR_AP_TIMER
|
|||
help
|
||||
Enables support for the Integrator-ap timer.
|
||||
|
||||
config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
|
||||
bool "Clocksource PRCMU Timer sched_clock"
|
||||
depends on (CLKSRC_DBX500_PRCMU && !CLKSRC_NOMADIK_MTU_SCHED_CLOCK)
|
||||
default y
|
||||
help
|
||||
Use the always on PRCMU Timer as sched_clock
|
||||
|
||||
config CLKSRC_EFM32
|
||||
bool "Clocksource for Energy Micro's EFM32 SoCs" if !ARCH_EFM32
|
||||
depends on OF && ARM && (ARCH_EFM32 || COMPILE_TEST)
|
||||
|
@ -290,6 +285,7 @@ config CLKSRC_MPS2
|
|||
|
||||
config ARC_TIMERS
|
||||
bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST
|
||||
depends on GENERIC_SCHED_CLOCK
|
||||
select TIMER_OF
|
||||
help
|
||||
These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores
|
||||
|
@ -580,7 +576,7 @@ config H8300_TPU
|
|||
|
||||
config CLKSRC_IMX_GPT
|
||||
bool "Clocksource using i.MX GPT" if COMPILE_TEST
|
||||
depends on ARM && CLKDEV_LOOKUP
|
||||
depends on (ARM || ARM64) && CLKDEV_LOOKUP
|
||||
select CLKSRC_MMIO
|
||||
|
||||
config CLKSRC_IMX_TPM
|
||||
|
@ -611,7 +607,7 @@ config ATCPIT100_TIMER
|
|||
|
||||
config RISCV_TIMER
|
||||
bool "Timer for the RISC-V platform"
|
||||
depends on RISCV
|
||||
depends on GENERIC_SCHED_CLOCK && RISCV
|
||||
default y
|
||||
select TIMER_PROBE
|
||||
select TIMER_OF
|
||||
|
|
|
@ -20,7 +20,7 @@ obj-$(CONFIG_OMAP_DM_TIMER) += timer-ti-dm.o
|
|||
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
|
||||
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
|
||||
obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o
|
||||
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
|
||||
obj-$(CONFIG_ROCKCHIP_TIMER) += timer-rockchip.o
|
||||
obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o
|
||||
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
|
||||
obj-$(CONFIG_ARMADA_370_XP_TIMER) += timer-armada-370-xp.o
|
||||
|
@ -32,10 +32,10 @@ obj-$(CONFIG_MXS_TIMER) += mxs_timer.o
|
|||
obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o
|
||||
obj-$(CONFIG_PRIMA2_TIMER) += timer-prima2.o
|
||||
obj-$(CONFIG_U300_TIMER) += timer-u300.o
|
||||
obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
|
||||
obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
|
||||
obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o
|
||||
obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o
|
||||
obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o
|
||||
obj-$(CONFIG_MESON6_TIMER) += timer-meson6.o
|
||||
obj-$(CONFIG_TEGRA_TIMER) += timer-tegra20.o
|
||||
obj-$(CONFIG_VT8500_TIMER) += timer-vt8500.o
|
||||
obj-$(CONFIG_NSPIRE_TIMER) += timer-zevio.o
|
||||
obj-$(CONFIG_BCM_KONA_TIMER) += bcm_kona_timer.o
|
||||
|
@ -57,6 +57,7 @@ obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o
|
|||
obj-$(CONFIG_OWL_TIMER) += timer-owl.o
|
||||
obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o
|
||||
obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o
|
||||
obj-$(CONFIG_RDA_TIMER) += timer-rda.o
|
||||
|
||||
obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
|
||||
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
|
||||
|
@ -78,6 +79,6 @@ obj-$(CONFIG_H8300_TPU) += h8300_tpu.o
|
|||
obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
|
||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||
obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o
|
||||
obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o
|
||||
obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
|
||||
obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
|
||||
obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/cpu.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/sched_clock.h>
|
||||
|
||||
#include <soc/arc/timers.h>
|
||||
#include <soc/arc/mcip.h>
|
||||
|
@ -88,6 +89,11 @@ static u64 arc_read_gfrc(struct clocksource *cs)
|
|||
return (((u64)h) << 32) | l;
|
||||
}
|
||||
|
||||
static notrace u64 arc_gfrc_clock_read(void)
|
||||
{
|
||||
return arc_read_gfrc(NULL);
|
||||
}
|
||||
|
||||
static struct clocksource arc_counter_gfrc = {
|
||||
.name = "ARConnect GFRC",
|
||||
.rating = 400,
|
||||
|
@ -111,6 +117,8 @@ static int __init arc_cs_setup_gfrc(struct device_node *node)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
sched_clock_register(arc_gfrc_clock_read, 64, arc_timer_freq);
|
||||
|
||||
return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
|
||||
}
|
||||
TIMER_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
|
||||
|
@ -139,6 +147,11 @@ static u64 arc_read_rtc(struct clocksource *cs)
|
|||
return (((u64)h) << 32) | l;
|
||||
}
|
||||
|
||||
static notrace u64 arc_rtc_clock_read(void)
|
||||
{
|
||||
return arc_read_rtc(NULL);
|
||||
}
|
||||
|
||||
static struct clocksource arc_counter_rtc = {
|
||||
.name = "ARCv2 RTC",
|
||||
.rating = 350,
|
||||
|
@ -170,6 +183,8 @@ static int __init arc_cs_setup_rtc(struct device_node *node)
|
|||
|
||||
write_aux_reg(AUX_RTC_CTRL, 1);
|
||||
|
||||
sched_clock_register(arc_rtc_clock_read, 64, arc_timer_freq);
|
||||
|
||||
return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
|
||||
}
|
||||
TIMER_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc);
|
||||
|
@ -185,6 +200,11 @@ static u64 arc_read_timer1(struct clocksource *cs)
|
|||
return (u64) read_aux_reg(ARC_REG_TIMER1_CNT);
|
||||
}
|
||||
|
||||
static notrace u64 arc_timer1_clock_read(void)
|
||||
{
|
||||
return arc_read_timer1(NULL);
|
||||
}
|
||||
|
||||
static struct clocksource arc_counter_timer1 = {
|
||||
.name = "ARC Timer1",
|
||||
.rating = 300,
|
||||
|
@ -209,6 +229,8 @@ static int __init arc_cs_setup_timer1(struct device_node *node)
|
|||
write_aux_reg(ARC_REG_TIMER1_CNT, 0);
|
||||
write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
|
||||
|
||||
sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq);
|
||||
|
||||
return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2012 Simon Arlott
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/sched_clock.h>
|
||||
|
||||
#define RATE_32K 32768
|
||||
|
||||
|
@ -26,8 +25,6 @@
|
|||
#define PRCMU_TIMER_DOWNCOUNT 0x4
|
||||
#define PRCMU_TIMER_MODE 0x8
|
||||
|
||||
#define SCHED_CLOCK_MIN_WRAP 131072 /* 2^32 / 32768 */
|
||||
|
||||
static void __iomem *clksrc_dbx500_timer_base;
|
||||
|
||||
static u64 notrace clksrc_dbx500_prcmu_read(struct clocksource *cs)
|
||||
|
@ -46,24 +43,12 @@ static u64 notrace clksrc_dbx500_prcmu_read(struct clocksource *cs)
|
|||
|
||||
static struct clocksource clocksource_dbx500_prcmu = {
|
||||
.name = "dbx500-prcmu-timer",
|
||||
.rating = 300,
|
||||
.rating = 100,
|
||||
.read = clksrc_dbx500_prcmu_read,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK
|
||||
|
||||
static u64 notrace dbx500_prcmu_sched_clock_read(void)
|
||||
{
|
||||
if (unlikely(!clksrc_dbx500_timer_base))
|
||||
return 0;
|
||||
|
||||
return clksrc_dbx500_prcmu_read(&clocksource_dbx500_prcmu);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int __init clksrc_dbx500_prcmu_init(struct device_node *node)
|
||||
{
|
||||
clksrc_dbx500_timer_base = of_iomap(node, 0);
|
||||
|
@ -81,9 +66,6 @@ static int __init clksrc_dbx500_prcmu_init(struct device_node *node)
|
|||
writel(TIMER_DOWNCOUNT_VAL,
|
||||
clksrc_dbx500_timer_base + PRCMU_TIMER_REF);
|
||||
}
|
||||
#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK
|
||||
sched_clock_register(dbx500_prcmu_sched_clock_read, 32, RATE_32K);
|
||||
#endif
|
||||
return clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K);
|
||||
}
|
||||
TIMER_OF_DECLARE(dbx500_prcmu, "stericsson,db8500-prcmu-timer-4",
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
/*
|
||||
* Amlogic Meson6 SoCs timer handling.
|
||||
*
|
||||
* Copyright (C) 2014 Carlo Caione <carlo@caione.org>
|
||||
*
|
||||
* Based on code from Amlogic, Inc
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/sched_clock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#define CED_ID 0
|
||||
#define CSD_ID 4
|
||||
|
||||
#define TIMER_ISA_MUX 0
|
||||
#define TIMER_ISA_VAL(t) (((t) + 1) << 2)
|
||||
|
||||
#define TIMER_INPUT_BIT(t) (2 * (t))
|
||||
#define TIMER_ENABLE_BIT(t) (16 + (t))
|
||||
#define TIMER_PERIODIC_BIT(t) (12 + (t))
|
||||
|
||||
#define TIMER_CED_INPUT_MASK (3UL << TIMER_INPUT_BIT(CED_ID))
|
||||
#define TIMER_CSD_INPUT_MASK (7UL << TIMER_INPUT_BIT(CSD_ID))
|
||||
|
||||
#define TIMER_CED_UNIT_1US 0
|
||||
#define TIMER_CSD_UNIT_1US 1
|
||||
|
||||
static void __iomem *timer_base;
|
||||
|
||||
static u64 notrace meson6_timer_sched_read(void)
|
||||
{
|
||||
return (u64)readl(timer_base + TIMER_ISA_VAL(CSD_ID));
|
||||
}
|
||||
|
||||
static void meson6_clkevt_time_stop(unsigned char timer)
|
||||
{
|
||||
u32 val = readl(timer_base + TIMER_ISA_MUX);
|
||||
|
||||
writel(val & ~TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX);
|
||||
}
|
||||
|
||||
static void meson6_clkevt_time_setup(unsigned char timer, unsigned long delay)
|
||||
{
|
||||
writel(delay, timer_base + TIMER_ISA_VAL(timer));
|
||||
}
|
||||
|
||||
static void meson6_clkevt_time_start(unsigned char timer, bool periodic)
|
||||
{
|
||||
u32 val = readl(timer_base + TIMER_ISA_MUX);
|
||||
|
||||
if (periodic)
|
||||
val |= TIMER_PERIODIC_BIT(timer);
|
||||
else
|
||||
val &= ~TIMER_PERIODIC_BIT(timer);
|
||||
|
||||
writel(val | TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX);
|
||||
}
|
||||
|
||||
static int meson6_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
meson6_clkevt_time_stop(CED_ID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson6_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
meson6_clkevt_time_stop(CED_ID);
|
||||
meson6_clkevt_time_start(CED_ID, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson6_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
meson6_clkevt_time_stop(CED_ID);
|
||||
meson6_clkevt_time_setup(CED_ID, USEC_PER_SEC / HZ - 1);
|
||||
meson6_clkevt_time_start(CED_ID, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson6_clkevt_next_event(unsigned long evt,
|
||||
struct clock_event_device *unused)
|
||||
{
|
||||
meson6_clkevt_time_stop(CED_ID);
|
||||
meson6_clkevt_time_setup(CED_ID, evt);
|
||||
meson6_clkevt_time_start(CED_ID, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device meson6_clockevent = {
|
||||
.name = "meson6_tick",
|
||||
.rating = 400,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = meson6_shutdown,
|
||||
.set_state_periodic = meson6_set_periodic,
|
||||
.set_state_oneshot = meson6_set_oneshot,
|
||||
.tick_resume = meson6_shutdown,
|
||||
.set_next_event = meson6_clkevt_next_event,
|
||||
};
|
||||
|
||||
static irqreturn_t meson6_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = (struct clock_event_device *)dev_id;
|
||||
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction meson6_timer_irq = {
|
||||
.name = "meson6_timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = meson6_timer_interrupt,
|
||||
.dev_id = &meson6_clockevent,
|
||||
};
|
||||
|
||||
static int __init meson6_timer_init(struct device_node *node)
|
||||
{
|
||||
u32 val;
|
||||
int ret, irq;
|
||||
|
||||
timer_base = of_io_request_and_map(node, 0, "meson6-timer");
|
||||
if (IS_ERR(timer_base)) {
|
||||
pr_err("Can't map registers\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
irq = irq_of_parse_and_map(node, 0);
|
||||
if (irq <= 0) {
|
||||
pr_err("Can't parse IRQ\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set 1us for timer E */
|
||||
val = readl(timer_base + TIMER_ISA_MUX);
|
||||
val &= ~TIMER_CSD_INPUT_MASK;
|
||||
val |= TIMER_CSD_UNIT_1US << TIMER_INPUT_BIT(CSD_ID);
|
||||
writel(val, timer_base + TIMER_ISA_MUX);
|
||||
|
||||
sched_clock_register(meson6_timer_sched_read, 32, USEC_PER_SEC);
|
||||
clocksource_mmio_init(timer_base + TIMER_ISA_VAL(CSD_ID), node->name,
|
||||
1000 * 1000, 300, 32, clocksource_mmio_readl_up);
|
||||
|
||||
/* Timer A base 1us */
|
||||
val &= ~TIMER_CED_INPUT_MASK;
|
||||
val |= TIMER_CED_UNIT_1US << TIMER_INPUT_BIT(CED_ID);
|
||||
writel(val, timer_base + TIMER_ISA_MUX);
|
||||
|
||||
/* Stop the timer A */
|
||||
meson6_clkevt_time_stop(CED_ID);
|
||||
|
||||
ret = setup_irq(irq, &meson6_timer_irq);
|
||||
if (ret) {
|
||||
pr_warn("failed to setup irq %d\n", irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
meson6_clockevent.cpumask = cpu_possible_mask;
|
||||
meson6_clockevent.irq = irq;
|
||||
|
||||
clockevents_config_and_register(&meson6_clockevent, USEC_PER_SEC,
|
||||
1, 0xfffe);
|
||||
return 0;
|
||||
}
|
||||
TIMER_OF_DECLARE(meson6, "amlogic,meson6-timer",
|
||||
meson6_timer_init);
|
|
@ -69,7 +69,6 @@ static u32 clk_prescale;
|
|||
static u32 nmdk_cycle; /* write-once */
|
||||
static struct delay_timer mtu_delay_timer;
|
||||
|
||||
#ifdef CONFIG_CLKSRC_NOMADIK_MTU_SCHED_CLOCK
|
||||
/*
|
||||
* Override the global weak sched_clock symbol with this
|
||||
* local implementation which uses the clocksource to get some
|
||||
|
@ -82,7 +81,6 @@ static u64 notrace nomadik_read_sched_clock(void)
|
|||
|
||||
return -readl(mtu_base + MTU_VAL(0));
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned long nmdk_timer_read_current_timer(void)
|
||||
{
|
||||
|
@ -234,9 +232,7 @@ static int __init nmdk_timer_init(void __iomem *base, int irq,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLKSRC_NOMADIK_MTU_SCHED_CLOCK
|
||||
sched_clock_register(nomadik_read_sched_clock, 32, rate);
|
||||
#endif
|
||||
|
||||
/* Timer 1 is used for events, register irq and clockevents */
|
||||
setup_irq(irq, &nmdk_timer_irq);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <linux/delay.h>
|
||||
|
||||
/*
|
||||
* Register definitions for the timers
|
||||
* Register definitions common for all the timer variants.
|
||||
*/
|
||||
#define TIMER1_COUNT (0x00)
|
||||
#define TIMER1_LOAD (0x04)
|
||||
|
@ -36,9 +36,10 @@
|
|||
#define TIMER3_MATCH1 (0x28)
|
||||
#define TIMER3_MATCH2 (0x2c)
|
||||
#define TIMER_CR (0x30)
|
||||
#define TIMER_INTR_STATE (0x34)
|
||||
#define TIMER_INTR_MASK (0x38)
|
||||
|
||||
/*
|
||||
* Control register (TMC30) bit fields for fttmr010/gemini/moxart timers.
|
||||
*/
|
||||
#define TIMER_1_CR_ENABLE BIT(0)
|
||||
#define TIMER_1_CR_CLOCK BIT(1)
|
||||
#define TIMER_1_CR_INT BIT(2)
|
||||
|
@ -53,8 +54,9 @@
|
|||
#define TIMER_3_CR_UPDOWN BIT(11)
|
||||
|
||||
/*
|
||||
* The Aspeed AST2400 moves bits around in the control register
|
||||
* and lacks bits for setting the timer to count upwards.
|
||||
* Control register (TMC30) bit fields for aspeed ast2400/ast2500 timers.
|
||||
* The aspeed timers move bits around in the control register and lacks
|
||||
* bits for setting the timer to count upwards.
|
||||
*/
|
||||
#define TIMER_1_CR_ASPEED_ENABLE BIT(0)
|
||||
#define TIMER_1_CR_ASPEED_CLOCK BIT(1)
|
||||
|
@ -66,6 +68,18 @@
|
|||
#define TIMER_3_CR_ASPEED_CLOCK BIT(9)
|
||||
#define TIMER_3_CR_ASPEED_INT BIT(10)
|
||||
|
||||
/*
|
||||
* Interrupt status/mask register definitions for fttmr010/gemini/moxart
|
||||
* timers.
|
||||
* The registers don't exist and they are not needed on aspeed timers
|
||||
* because:
|
||||
* - aspeed timer overflow interrupt is controlled by bits in Control
|
||||
* Register (TMC30).
|
||||
* - aspeed timers always generate interrupt when either one of the
|
||||
* Match registers equals to Status register.
|
||||
*/
|
||||
#define TIMER_INTR_STATE (0x34)
|
||||
#define TIMER_INTR_MASK (0x38)
|
||||
#define TIMER_1_INT_MATCH1 BIT(0)
|
||||
#define TIMER_1_INT_MATCH2 BIT(1)
|
||||
#define TIMER_1_INT_OVERFLOW BIT(2)
|
||||
|
@ -80,7 +94,7 @@
|
|||
struct fttmr010 {
|
||||
void __iomem *base;
|
||||
unsigned int tick_rate;
|
||||
bool count_down;
|
||||
bool is_aspeed;
|
||||
u32 t1_enable_val;
|
||||
struct clock_event_device clkevt;
|
||||
#ifdef CONFIG_ARM
|
||||
|
@ -130,7 +144,7 @@ static int fttmr010_timer_set_next_event(unsigned long cycles,
|
|||
cr &= ~fttmr010->t1_enable_val;
|
||||
writel(cr, fttmr010->base + TIMER_CR);
|
||||
|
||||
if (fttmr010->count_down) {
|
||||
if (fttmr010->is_aspeed) {
|
||||
/*
|
||||
* ASPEED Timer Controller will load TIMER1_LOAD register
|
||||
* into TIMER1_COUNT register when the timer is re-enabled.
|
||||
|
@ -175,16 +189,17 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
|
|||
|
||||
/* Setup counter start from 0 or ~0 */
|
||||
writel(0, fttmr010->base + TIMER1_COUNT);
|
||||
if (fttmr010->count_down)
|
||||
if (fttmr010->is_aspeed) {
|
||||
writel(~0, fttmr010->base + TIMER1_LOAD);
|
||||
else
|
||||
} else {
|
||||
writel(0, fttmr010->base + TIMER1_LOAD);
|
||||
|
||||
/* Enable interrupt */
|
||||
cr = readl(fttmr010->base + TIMER_INTR_MASK);
|
||||
cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2);
|
||||
cr |= TIMER_1_INT_MATCH1;
|
||||
writel(cr, fttmr010->base + TIMER_INTR_MASK);
|
||||
/* Enable interrupt */
|
||||
cr = readl(fttmr010->base + TIMER_INTR_MASK);
|
||||
cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2);
|
||||
cr |= TIMER_1_INT_MATCH1;
|
||||
writel(cr, fttmr010->base + TIMER_INTR_MASK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -201,9 +216,8 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
|
|||
writel(cr, fttmr010->base + TIMER_CR);
|
||||
|
||||
/* Setup timer to fire at 1/HZ intervals. */
|
||||
if (fttmr010->count_down) {
|
||||
if (fttmr010->is_aspeed) {
|
||||
writel(period, fttmr010->base + TIMER1_LOAD);
|
||||
writel(0, fttmr010->base + TIMER1_MATCH1);
|
||||
} else {
|
||||
cr = 0xffffffff - (period - 1);
|
||||
writel(cr, fttmr010->base + TIMER1_COUNT);
|
||||
|
@ -281,23 +295,21 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed)
|
|||
}
|
||||
|
||||
/*
|
||||
* The Aspeed AST2400 moves bits around in the control register,
|
||||
* otherwise it works the same.
|
||||
* The Aspeed timers move bits around in the control register.
|
||||
*/
|
||||
if (is_aspeed) {
|
||||
fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
|
||||
TIMER_1_CR_ASPEED_INT;
|
||||
/* Downward not available */
|
||||
fttmr010->count_down = true;
|
||||
fttmr010->is_aspeed = true;
|
||||
} else {
|
||||
fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the interrupt mask and status
|
||||
*/
|
||||
writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
|
||||
writel(0, fttmr010->base + TIMER_INTR_STATE);
|
||||
/*
|
||||
* Reset the interrupt mask and status
|
||||
*/
|
||||
writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
|
||||
writel(0, fttmr010->base + TIMER_INTR_STATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable timer 1 count up, timer 2 count up, except on Aspeed,
|
||||
|
@ -306,9 +318,8 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed)
|
|||
if (is_aspeed)
|
||||
val = TIMER_2_CR_ASPEED_ENABLE;
|
||||
else {
|
||||
val = TIMER_2_CR_ENABLE;
|
||||
if (!fttmr010->count_down)
|
||||
val |= TIMER_1_CR_UPDOWN | TIMER_2_CR_UPDOWN;
|
||||
val = TIMER_2_CR_ENABLE | TIMER_1_CR_UPDOWN |
|
||||
TIMER_2_CR_UPDOWN;
|
||||
}
|
||||
writel(val, fttmr010->base + TIMER_CR);
|
||||
|
||||
|
@ -321,7 +332,7 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed)
|
|||
writel(0, fttmr010->base + TIMER2_MATCH1);
|
||||
writel(0, fttmr010->base + TIMER2_MATCH2);
|
||||
|
||||
if (fttmr010->count_down) {
|
||||
if (fttmr010->is_aspeed) {
|
||||
writel(~0, fttmr010->base + TIMER2_LOAD);
|
||||
clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
|
||||
"FTTMR010-TIMER2",
|
||||
|
@ -371,7 +382,7 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed)
|
|||
|
||||
#ifdef CONFIG_ARM
|
||||
/* Also use this timer for delays */
|
||||
if (fttmr010->count_down)
|
||||
if (fttmr010->is_aspeed)
|
||||
fttmr010->delay_timer.read_current_timer =
|
||||
fttmr010_read_current_timer_down;
|
||||
else
|
||||
|
|
|
@ -141,21 +141,25 @@ static u64 notrace mxc_read_sched_clock(void)
|
|||
return sched_clock_reg ? readl_relaxed(sched_clock_reg) : 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARM)
|
||||
static struct delay_timer imx_delay_timer;
|
||||
|
||||
static unsigned long imx_read_current_timer(void)
|
||||
{
|
||||
return readl_relaxed(sched_clock_reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init mxc_clocksource_init(struct imx_timer *imxtm)
|
||||
{
|
||||
unsigned int c = clk_get_rate(imxtm->clk_per);
|
||||
void __iomem *reg = imxtm->base + imxtm->gpt->reg_tcn;
|
||||
|
||||
#if defined(CONFIG_ARM)
|
||||
imx_delay_timer.read_current_timer = &imx_read_current_timer;
|
||||
imx_delay_timer.freq = c;
|
||||
register_current_timer_delay(&imx_delay_timer);
|
||||
#endif
|
||||
|
||||
sched_clock_reg = reg;
|
||||
|
||||
|
@ -198,15 +202,8 @@ static int v2_set_next_event(unsigned long evt,
|
|||
static int mxc_shutdown(struct clock_event_device *ced)
|
||||
{
|
||||
struct imx_timer *imxtm = to_imx_timer(ced);
|
||||
unsigned long flags;
|
||||
u32 tcn;
|
||||
|
||||
/*
|
||||
* The timer interrupt generation is disabled at least
|
||||
* for enough time to call mxc_set_next_event()
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Disable interrupt in GPT module */
|
||||
imxtm->gpt->gpt_irq_disable(imxtm);
|
||||
|
||||
|
@ -221,21 +218,12 @@ static int mxc_shutdown(struct clock_event_device *ced)
|
|||
printk(KERN_INFO "%s: changing mode\n", __func__);
|
||||
#endif /* DEBUG */
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_set_oneshot(struct clock_event_device *ced)
|
||||
{
|
||||
struct imx_timer *imxtm = to_imx_timer(ced);
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* The timer interrupt generation is disabled at least
|
||||
* for enough time to call mxc_set_next_event()
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Disable interrupt in GPT module */
|
||||
imxtm->gpt->gpt_irq_disable(imxtm);
|
||||
|
@ -260,7 +248,6 @@ static int mxc_set_oneshot(struct clock_event_device *ced)
|
|||
* mode switching
|
||||
*/
|
||||
imxtm->gpt->gpt_irq_enable(imxtm);
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <linux/of_irq.h>
|
||||
#include <linux/sched_clock.h>
|
||||
|
||||
#include "timer-of.h"
|
||||
|
||||
#define TPM_PARAM 0x4
|
||||
#define TPM_PARAM_WIDTH_SHIFT 16
|
||||
#define TPM_PARAM_WIDTH_MASK (0xff << 16)
|
||||
|
@ -33,9 +35,7 @@
|
|||
#define TPM_C0V 0x24
|
||||
|
||||
static int counter_width;
|
||||
static int rating;
|
||||
static void __iomem *timer_base;
|
||||
static struct clock_event_device clockevent_tpm;
|
||||
|
||||
static inline void tpm_timer_disable(void)
|
||||
{
|
||||
|
@ -80,19 +80,6 @@ static u64 notrace tpm_read_sched_clock(void)
|
|||
return tpm_read_counter();
|
||||
}
|
||||
|
||||
static int __init tpm_clocksource_init(unsigned long rate)
|
||||
{
|
||||
tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
|
||||
tpm_delay_timer.freq = rate;
|
||||
register_current_timer_delay(&tpm_delay_timer);
|
||||
|
||||
sched_clock_register(tpm_read_sched_clock, counter_width, rate);
|
||||
|
||||
return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm",
|
||||
rate, rating, counter_width,
|
||||
clocksource_mmio_readl_up);
|
||||
}
|
||||
|
||||
static int tpm_set_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
|
@ -137,74 +124,80 @@ static irqreturn_t tpm_timer_interrupt(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_tpm = {
|
||||
.name = "i.MX7ULP TPM Timer",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_oneshot = tpm_set_state_oneshot,
|
||||
.set_next_event = tpm_set_next_event,
|
||||
.set_state_shutdown = tpm_set_state_shutdown,
|
||||
static struct timer_of to_tpm = {
|
||||
.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
|
||||
.clkevt = {
|
||||
.name = "i.MX7ULP TPM Timer",
|
||||
.rating = 200,
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = tpm_set_state_shutdown,
|
||||
.set_state_oneshot = tpm_set_state_oneshot,
|
||||
.set_next_event = tpm_set_next_event,
|
||||
.cpumask = cpu_possible_mask,
|
||||
},
|
||||
.of_irq = {
|
||||
.handler = tpm_timer_interrupt,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
},
|
||||
.of_clk = {
|
||||
.name = "per",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init tpm_clockevent_init(unsigned long rate, int irq)
|
||||
static int __init tpm_clocksource_init(void)
|
||||
{
|
||||
int ret;
|
||||
tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
|
||||
tpm_delay_timer.freq = timer_of_rate(&to_tpm) >> 3;
|
||||
register_current_timer_delay(&tpm_delay_timer);
|
||||
|
||||
ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
|
||||
"i.MX7ULP TPM Timer", &clockevent_tpm);
|
||||
sched_clock_register(tpm_read_sched_clock, counter_width,
|
||||
timer_of_rate(&to_tpm) >> 3);
|
||||
|
||||
clockevent_tpm.rating = rating;
|
||||
clockevent_tpm.cpumask = cpumask_of(0);
|
||||
clockevent_tpm.irq = irq;
|
||||
clockevents_config_and_register(&clockevent_tpm, rate, 300,
|
||||
GENMASK(counter_width - 1, 1));
|
||||
return clocksource_mmio_init(timer_base + TPM_CNT,
|
||||
"imx-tpm",
|
||||
timer_of_rate(&to_tpm) >> 3,
|
||||
to_tpm.clkevt.rating,
|
||||
counter_width,
|
||||
clocksource_mmio_readl_up);
|
||||
}
|
||||
|
||||
return ret;
|
||||
static void __init tpm_clockevent_init(void)
|
||||
{
|
||||
clockevents_config_and_register(&to_tpm.clkevt,
|
||||
timer_of_rate(&to_tpm) >> 3,
|
||||
300,
|
||||
GENMASK(counter_width - 1,
|
||||
1));
|
||||
}
|
||||
|
||||
static int __init tpm_timer_init(struct device_node *np)
|
||||
{
|
||||
struct clk *ipg, *per;
|
||||
int irq, ret;
|
||||
u32 rate;
|
||||
|
||||
timer_base = of_iomap(np, 0);
|
||||
if (!timer_base) {
|
||||
pr_err("tpm: failed to get base address\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
if (!irq) {
|
||||
pr_err("tpm: failed to get irq\n");
|
||||
ret = -ENOENT;
|
||||
goto err_iomap;
|
||||
}
|
||||
struct clk *ipg;
|
||||
int ret;
|
||||
|
||||
ipg = of_clk_get_by_name(np, "ipg");
|
||||
per = of_clk_get_by_name(np, "per");
|
||||
if (IS_ERR(ipg) || IS_ERR(per)) {
|
||||
pr_err("tpm: failed to get ipg or per clk\n");
|
||||
ret = -ENODEV;
|
||||
goto err_clk_get;
|
||||
if (IS_ERR(ipg)) {
|
||||
pr_err("tpm: failed to get ipg clk\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* enable clk before accessing registers */
|
||||
ret = clk_prepare_enable(ipg);
|
||||
if (ret) {
|
||||
pr_err("tpm: ipg clock enable failed (%d)\n", ret);
|
||||
goto err_clk_get;
|
||||
clk_put(ipg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(per);
|
||||
if (ret) {
|
||||
pr_err("tpm: per clock enable failed (%d)\n", ret);
|
||||
goto err_per_clk_enable;
|
||||
}
|
||||
ret = timer_of_init(np, &to_tpm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
counter_width = (readl(timer_base + TPM_PARAM) & TPM_PARAM_WIDTH_MASK)
|
||||
>> TPM_PARAM_WIDTH_SHIFT;
|
||||
timer_base = timer_of_base(&to_tpm);
|
||||
|
||||
counter_width = (readl(timer_base + TPM_PARAM)
|
||||
& TPM_PARAM_WIDTH_MASK) >> TPM_PARAM_WIDTH_SHIFT;
|
||||
/* use rating 200 for 32-bit counter and 150 for 16-bit counter */
|
||||
rating = counter_width == 0x20 ? 200 : 150;
|
||||
to_tpm.clkevt.rating = counter_width == 0x20 ? 200 : 150;
|
||||
|
||||
/*
|
||||
* Initialize tpm module to a known state
|
||||
|
@ -229,29 +222,13 @@ static int __init tpm_timer_init(struct device_node *np)
|
|||
writel(TPM_SC_CMOD_INC_PER_CNT |
|
||||
(counter_width == 0x20 ?
|
||||
TPM_SC_CMOD_DIV_DEFAULT : TPM_SC_CMOD_DIV_MAX),
|
||||
timer_base + TPM_SC);
|
||||
timer_base + TPM_SC);
|
||||
|
||||
/* set MOD register to maximum for free running mode */
|
||||
writel(GENMASK(counter_width - 1, 0), timer_base + TPM_MOD);
|
||||
|
||||
rate = clk_get_rate(per) >> 3;
|
||||
ret = tpm_clocksource_init(rate);
|
||||
if (ret)
|
||||
goto err_per_clk_enable;
|
||||
tpm_clockevent_init();
|
||||
|
||||
ret = tpm_clockevent_init(rate, irq);
|
||||
if (ret)
|
||||
goto err_per_clk_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_per_clk_enable:
|
||||
clk_disable_unprepare(ipg);
|
||||
err_clk_get:
|
||||
clk_put(per);
|
||||
clk_put(ipg);
|
||||
err_iomap:
|
||||
iounmap(timer_base);
|
||||
return ret;
|
||||
return tpm_clocksource_init();
|
||||
}
|
||||
TIMER_OF_DECLARE(imx7ulp, "fsl,imx7ulp-tpm", tpm_timer_init);
|
||||
|
|
|
@ -181,8 +181,7 @@ static int __init integrator_ap_timer_init_of(struct device_node *node)
|
|||
int irq;
|
||||
struct clk *clk;
|
||||
unsigned long rate;
|
||||
struct device_node *pri_node;
|
||||
struct device_node *sec_node;
|
||||
struct device_node *alias_node;
|
||||
|
||||
base = of_io_request_and_map(node, 0, "integrator-timer");
|
||||
if (IS_ERR(base))
|
||||
|
@ -204,7 +203,18 @@ static int __init integrator_ap_timer_init_of(struct device_node *node)
|
|||
return err;
|
||||
}
|
||||
|
||||
pri_node = of_find_node_by_path(path);
|
||||
alias_node = of_find_node_by_path(path);
|
||||
|
||||
/*
|
||||
* The pointer is used as an identifier not as a pointer, we
|
||||
* can drop the refcount on the of__node immediately after
|
||||
* getting it.
|
||||
*/
|
||||
of_node_put(alias_node);
|
||||
|
||||
if (node == alias_node)
|
||||
/* The primary timer lacks IRQ, use as clocksource */
|
||||
return integrator_clocksource_init(rate, base);
|
||||
|
||||
err = of_property_read_string(of_aliases,
|
||||
"arm,timer-secondary", &path);
|
||||
|
@ -213,14 +223,11 @@ static int __init integrator_ap_timer_init_of(struct device_node *node)
|
|||
return err;
|
||||
}
|
||||
|
||||
alias_node = of_find_node_by_path(path);
|
||||
|
||||
sec_node = of_find_node_by_path(path);
|
||||
of_node_put(alias_node);
|
||||
|
||||
if (node == pri_node)
|
||||
/* The primary timer lacks IRQ, use as clocksource */
|
||||
return integrator_clocksource_init(rate, base);
|
||||
|
||||
if (node == sec_node) {
|
||||
if (node == alias_node) {
|
||||
/* The secondary timer will drive the clock event */
|
||||
irq = irq_of_parse_and_map(node, 0);
|
||||
return integrator_clockevent_init(rate, base, irq);
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Amlogic Meson6 SoCs timer handling.
|
||||
*
|
||||
* Copyright (C) 2014 Carlo Caione <carlo@caione.org>
|
||||
*
|
||||
* Based on code from Amlogic, Inc
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/sched_clock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
#include <linux/delay.h>
|
||||
#endif
|
||||
|
||||
#define MESON_ISA_TIMER_MUX 0x00
|
||||
#define MESON_ISA_TIMER_MUX_TIMERD_EN BIT(19)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERC_EN BIT(18)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERB_EN BIT(17)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERA_EN BIT(16)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERD_MODE BIT(15)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERC_MODE BIT(14)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERB_MODE BIT(13)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERA_MODE BIT(12)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_MASK GENMASK(10, 8)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_SYSTEM_CLOCK 0x0
|
||||
#define MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_1US 0x1
|
||||
#define MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_10US 0x2
|
||||
#define MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_100US 0x3
|
||||
#define MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_1MS 0x4
|
||||
#define MESON_ISA_TIMER_MUX_TIMERD_INPUT_CLOCK_MASK GENMASK(7, 6)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERC_INPUT_CLOCK_MASK GENMASK(5, 4)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERB_INPUT_CLOCK_MASK GENMASK(3, 2)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERA_INPUT_CLOCK_MASK GENMASK(1, 0)
|
||||
#define MESON_ISA_TIMER_MUX_TIMERABCD_INPUT_CLOCK_1US 0x0
|
||||
#define MESON_ISA_TIMER_MUX_TIMERABCD_INPUT_CLOCK_10US 0x1
|
||||
#define MESON_ISA_TIMER_MUX_TIMERABCD_INPUT_CLOCK_100US 0x0
|
||||
#define MESON_ISA_TIMER_MUX_TIMERABCD_INPUT_CLOCK_1MS 0x3
|
||||
|
||||
#define MESON_ISA_TIMERA 0x04
|
||||
#define MESON_ISA_TIMERB 0x08
|
||||
#define MESON_ISA_TIMERC 0x0c
|
||||
#define MESON_ISA_TIMERD 0x10
|
||||
#define MESON_ISA_TIMERE 0x14
|
||||
|
||||
static void __iomem *timer_base;
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
static unsigned long meson6_read_current_timer(void)
|
||||
{
|
||||
return readl_relaxed(timer_base + MESON_ISA_TIMERE);
|
||||
}
|
||||
|
||||
static struct delay_timer meson6_delay_timer = {
|
||||
.read_current_timer = meson6_read_current_timer,
|
||||
.freq = 1000 * 1000,
|
||||
};
|
||||
#endif
|
||||
|
||||
static u64 notrace meson6_timer_sched_read(void)
|
||||
{
|
||||
return (u64)readl(timer_base + MESON_ISA_TIMERE);
|
||||
}
|
||||
|
||||
static void meson6_clkevt_time_stop(void)
|
||||
{
|
||||
u32 val = readl(timer_base + MESON_ISA_TIMER_MUX);
|
||||
|
||||
writel(val & ~MESON_ISA_TIMER_MUX_TIMERA_EN,
|
||||
timer_base + MESON_ISA_TIMER_MUX);
|
||||
}
|
||||
|
||||
static void meson6_clkevt_time_setup(unsigned long delay)
|
||||
{
|
||||
writel(delay, timer_base + MESON_ISA_TIMERA);
|
||||
}
|
||||
|
||||
static void meson6_clkevt_time_start(bool periodic)
|
||||
{
|
||||
u32 val = readl(timer_base + MESON_ISA_TIMER_MUX);
|
||||
|
||||
if (periodic)
|
||||
val |= MESON_ISA_TIMER_MUX_TIMERA_MODE;
|
||||
else
|
||||
val &= ~MESON_ISA_TIMER_MUX_TIMERA_MODE;
|
||||
|
||||
writel(val | MESON_ISA_TIMER_MUX_TIMERA_EN,
|
||||
timer_base + MESON_ISA_TIMER_MUX);
|
||||
}
|
||||
|
||||
static int meson6_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
meson6_clkevt_time_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson6_set_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
meson6_clkevt_time_stop();
|
||||
meson6_clkevt_time_start(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson6_set_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
meson6_clkevt_time_stop();
|
||||
meson6_clkevt_time_setup(USEC_PER_SEC / HZ - 1);
|
||||
meson6_clkevt_time_start(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson6_clkevt_next_event(unsigned long evt,
|
||||
struct clock_event_device *unused)
|
||||
{
|
||||
meson6_clkevt_time_stop();
|
||||
meson6_clkevt_time_setup(evt);
|
||||
meson6_clkevt_time_start(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device meson6_clockevent = {
|
||||
.name = "meson6_tick",
|
||||
.rating = 400,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_state_shutdown = meson6_shutdown,
|
||||
.set_state_periodic = meson6_set_periodic,
|
||||
.set_state_oneshot = meson6_set_oneshot,
|
||||
.tick_resume = meson6_shutdown,
|
||||
.set_next_event = meson6_clkevt_next_event,
|
||||
};
|
||||
|
||||
static irqreturn_t meson6_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = (struct clock_event_device *)dev_id;
|
||||
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction meson6_timer_irq = {
|
||||
.name = "meson6_timer",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = meson6_timer_interrupt,
|
||||
.dev_id = &meson6_clockevent,
|
||||
};
|
||||
|
||||
static int __init meson6_timer_init(struct device_node *node)
|
||||
{
|
||||
u32 val;
|
||||
int ret, irq;
|
||||
|
||||
timer_base = of_io_request_and_map(node, 0, "meson6-timer");
|
||||
if (IS_ERR(timer_base)) {
|
||||
pr_err("Can't map registers\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
irq = irq_of_parse_and_map(node, 0);
|
||||
if (irq <= 0) {
|
||||
pr_err("Can't parse IRQ\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set 1us for timer E */
|
||||
val = readl(timer_base + MESON_ISA_TIMER_MUX);
|
||||
val &= ~MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_MASK;
|
||||
val |= FIELD_PREP(MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_MASK,
|
||||
MESON_ISA_TIMER_MUX_TIMERE_INPUT_CLOCK_1US);
|
||||
writel(val, timer_base + MESON_ISA_TIMER_MUX);
|
||||
|
||||
sched_clock_register(meson6_timer_sched_read, 32, USEC_PER_SEC);
|
||||
clocksource_mmio_init(timer_base + MESON_ISA_TIMERE, node->name,
|
||||
1000 * 1000, 300, 32, clocksource_mmio_readl_up);
|
||||
|
||||
/* Timer A base 1us */
|
||||
val &= ~MESON_ISA_TIMER_MUX_TIMERA_INPUT_CLOCK_MASK;
|
||||
val |= FIELD_PREP(MESON_ISA_TIMER_MUX_TIMERA_INPUT_CLOCK_MASK,
|
||||
MESON_ISA_TIMER_MUX_TIMERABCD_INPUT_CLOCK_1US);
|
||||
writel(val, timer_base + MESON_ISA_TIMER_MUX);
|
||||
|
||||
/* Stop the timer A */
|
||||
meson6_clkevt_time_stop();
|
||||
|
||||
ret = setup_irq(irq, &meson6_timer_irq);
|
||||
if (ret) {
|
||||
pr_warn("failed to setup irq %d\n", irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
meson6_clockevent.cpumask = cpu_possible_mask;
|
||||
meson6_clockevent.irq = irq;
|
||||
|
||||
clockevents_config_and_register(&meson6_clockevent, USEC_PER_SEC,
|
||||
1, 0xfffe);
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
/* Also use MESON_ISA_TIMERE for delays */
|
||||
register_current_timer_delay(&meson6_delay_timer);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
TIMER_OF_DECLARE(meson6, "amlogic,meson6-timer",
|
||||
meson6_timer_init);
|
|
@ -0,0 +1,195 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* RDA8810PL SoC timer driver
|
||||
*
|
||||
* Copyright RDA Microelectronics Company Limited
|
||||
* Copyright (c) 2017 Andreas Färber
|
||||
* Copyright (c) 2018 Manivannan Sadhasivam
|
||||
*
|
||||
* RDA8810PL has two independent timers: OSTIMER (56 bit) and HWTIMER (64 bit).
|
||||
* Each timer provides optional interrupt support. In this driver, OSTIMER is
|
||||
* used for clockevents and HWTIMER is used for clocksource.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "timer-of.h"
|
||||
|
||||
#define RDA_OSTIMER_LOADVAL_L 0x000
|
||||
#define RDA_OSTIMER_CTRL 0x004
|
||||
#define RDA_HWTIMER_LOCKVAL_L 0x024
|
||||
#define RDA_HWTIMER_LOCKVAL_H 0x028
|
||||
#define RDA_TIMER_IRQ_MASK_SET 0x02c
|
||||
#define RDA_TIMER_IRQ_MASK_CLR 0x030
|
||||
#define RDA_TIMER_IRQ_CLR 0x034
|
||||
|
||||
#define RDA_OSTIMER_CTRL_ENABLE BIT(24)
|
||||
#define RDA_OSTIMER_CTRL_REPEAT BIT(28)
|
||||
#define RDA_OSTIMER_CTRL_LOAD BIT(30)
|
||||
|
||||
#define RDA_TIMER_IRQ_MASK_OSTIMER BIT(0)
|
||||
|
||||
#define RDA_TIMER_IRQ_CLR_OSTIMER BIT(0)
|
||||
|
||||
static int rda_ostimer_start(void __iomem *base, bool periodic, u64 cycles)
|
||||
{
|
||||
u32 ctrl, load_l;
|
||||
|
||||
load_l = (u32)cycles;
|
||||
ctrl = ((cycles >> 32) & 0xffffff);
|
||||
ctrl |= RDA_OSTIMER_CTRL_LOAD | RDA_OSTIMER_CTRL_ENABLE;
|
||||
if (periodic)
|
||||
ctrl |= RDA_OSTIMER_CTRL_REPEAT;
|
||||
|
||||
/* Enable ostimer interrupt first */
|
||||
writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER,
|
||||
base + RDA_TIMER_IRQ_MASK_SET);
|
||||
|
||||
/* Write low 32 bits first, high 24 bits are with ctrl */
|
||||
writel_relaxed(load_l, base + RDA_OSTIMER_LOADVAL_L);
|
||||
writel_relaxed(ctrl, base + RDA_OSTIMER_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rda_ostimer_stop(void __iomem *base)
|
||||
{
|
||||
/* Disable ostimer interrupt first */
|
||||
writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER,
|
||||
base + RDA_TIMER_IRQ_MASK_CLR);
|
||||
|
||||
writel_relaxed(0, base + RDA_OSTIMER_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rda_ostimer_set_state_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
|
||||
rda_ostimer_stop(timer_of_base(to));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rda_ostimer_set_state_oneshot(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
|
||||
rda_ostimer_stop(timer_of_base(to));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rda_ostimer_set_state_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
unsigned long cycles_per_jiffy;
|
||||
|
||||
rda_ostimer_stop(timer_of_base(to));
|
||||
|
||||
cycles_per_jiffy = ((unsigned long long)NSEC_PER_SEC / HZ *
|
||||
evt->mult) >> evt->shift;
|
||||
rda_ostimer_start(timer_of_base(to), true, cycles_per_jiffy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rda_ostimer_tick_resume(struct clock_event_device *evt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rda_ostimer_set_next_event(unsigned long evt,
|
||||
struct clock_event_device *ev)
|
||||
{
|
||||
struct timer_of *to = to_timer_of(ev);
|
||||
|
||||
rda_ostimer_start(timer_of_base(to), false, evt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rda_ostimer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = dev_id;
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
|
||||
/* clear timer int */
|
||||
writel_relaxed(RDA_TIMER_IRQ_CLR_OSTIMER,
|
||||
timer_of_base(to) + RDA_TIMER_IRQ_CLR);
|
||||
|
||||
if (evt->event_handler)
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct timer_of rda_ostimer_of = {
|
||||
.flags = TIMER_OF_IRQ | TIMER_OF_BASE,
|
||||
|
||||
.clkevt = {
|
||||
.name = "rda-ostimer",
|
||||
.rating = 250,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
|
||||
CLOCK_EVT_FEAT_DYNIRQ,
|
||||
.set_state_shutdown = rda_ostimer_set_state_shutdown,
|
||||
.set_state_oneshot = rda_ostimer_set_state_oneshot,
|
||||
.set_state_periodic = rda_ostimer_set_state_periodic,
|
||||
.tick_resume = rda_ostimer_tick_resume,
|
||||
.set_next_event = rda_ostimer_set_next_event,
|
||||
},
|
||||
|
||||
.of_base = {
|
||||
.name = "rda-timer",
|
||||
.index = 0,
|
||||
},
|
||||
|
||||
.of_irq = {
|
||||
.name = "ostimer",
|
||||
.handler = rda_ostimer_interrupt,
|
||||
.flags = IRQF_TIMER,
|
||||
},
|
||||
};
|
||||
|
||||
static u64 rda_hwtimer_read(struct clocksource *cs)
|
||||
{
|
||||
void __iomem *base = timer_of_base(&rda_ostimer_of);
|
||||
u32 lo, hi;
|
||||
|
||||
/* Always read low 32 bits first */
|
||||
do {
|
||||
lo = readl_relaxed(base + RDA_HWTIMER_LOCKVAL_L);
|
||||
hi = readl_relaxed(base + RDA_HWTIMER_LOCKVAL_H);
|
||||
} while (hi != readl_relaxed(base + RDA_HWTIMER_LOCKVAL_H));
|
||||
|
||||
return ((u64)hi << 32) | lo;
|
||||
}
|
||||
|
||||
static struct clocksource rda_hwtimer_clocksource = {
|
||||
.name = "rda-timer",
|
||||
.rating = 400,
|
||||
.read = rda_hwtimer_read,
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static int __init rda_timer_init(struct device_node *np)
|
||||
{
|
||||
unsigned long rate = 2000000;
|
||||
int ret;
|
||||
|
||||
ret = timer_of_init(np, &rda_ostimer_of);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clocksource_register_hz(&rda_hwtimer_clocksource, rate);
|
||||
|
||||
clockevents_config_and_register(&rda_ostimer_of.clkevt, rate,
|
||||
0x2, UINT_MAX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TIMER_OF_DECLARE(rda8810pl, "rda,8810pl-timer", rda_timer_init);
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/cpu.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/sched_clock.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/sbi.h>
|
||||
|
||||
|
@ -49,6 +50,11 @@ static unsigned long long riscv_clocksource_rdtime(struct clocksource *cs)
|
|||
return get_cycles64();
|
||||
}
|
||||
|
||||
static u64 riscv_sched_clock(void)
|
||||
{
|
||||
return get_cycles64();
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct clocksource, riscv_clocksource) = {
|
||||
.name = "riscv_clocksource",
|
||||
.rating = 300,
|
||||
|
@ -97,6 +103,9 @@ static int __init riscv_timer_init_dt(struct device_node *n)
|
|||
cs = per_cpu_ptr(&riscv_clocksource, cpuid);
|
||||
clocksource_register_hz(cs, riscv_timebase);
|
||||
|
||||
sched_clock_register(riscv_sched_clock,
|
||||
BITS_PER_LONG, riscv_timebase);
|
||||
|
||||
error = cpuhp_setup_state(CPUHP_AP_RISCV_TIMER_STARTING,
|
||||
"clockevents/riscv/timer:starting",
|
||||
riscv_timer_starting_cpu, riscv_timer_dying_cpu);
|
|
@ -30,7 +30,6 @@
|
|||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
#define RTC_SECONDS 0x08
|
||||
#define RTC_SHADOW_SECONDS 0x0c
|
|
@ -991,7 +991,6 @@ static struct platform_driver omap_dm_timer_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
early_platform_init("earlytimer", &omap_dm_timer_driver);
|
||||
module_platform_driver(omap_dm_timer_driver);
|
||||
|
||||
MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
|
||||
|
|
|
@ -145,7 +145,7 @@ static int __init vt8500_timer_init(struct device_node *np)
|
|||
|
||||
ret = clocksource_register_hz(&clocksource, VT8500_TIMER_HZ);
|
||||
if (ret) {
|
||||
pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n",
|
||||
pr_err("%s: clocksource_register failed for %s\n",
|
||||
__func__, clocksource.name);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* include/linux/hrtimer.h
|
||||
*
|
||||
* hrtimers - High-resolution kernel timers
|
||||
*
|
||||
* Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
|
||||
|
@ -9,8 +8,6 @@
|
|||
* data type definitions, declarations, prototypes
|
||||
*
|
||||
* Started by: Thomas Gleixner and Ingo Molnar
|
||||
*
|
||||
* For licencing details see kernel-base/COPYING
|
||||
*/
|
||||
#ifndef _LINUX_HRTIMER_H
|
||||
#define _LINUX_HRTIMER_H
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Alarmtimer interface
|
||||
*
|
||||
|
@ -10,10 +11,6 @@
|
|||
* Copyright (C) 2010 IBM Corperation
|
||||
*
|
||||
* Author: John Stultz <john.stultz@linaro.org>
|
||||
*
|
||||
* 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 <linux/time.h>
|
||||
#include <linux/hrtimer.h>
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/clockevents.c
|
||||
*
|
||||
* This file contains functions which manage clock event devices.
|
||||
*
|
||||
* Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
|
||||
* Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
|
||||
*
|
||||
* This code is licenced under the GPL version 2. For details see
|
||||
* kernel-base/COPYING.
|
||||
*/
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
|
@ -39,10 +35,8 @@ static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt,
|
|||
u64 clc = (u64) latch << evt->shift;
|
||||
u64 rnd;
|
||||
|
||||
if (unlikely(!evt->mult)) {
|
||||
if (WARN_ON(!evt->mult))
|
||||
evt->mult = 1;
|
||||
WARN_ON(1);
|
||||
}
|
||||
rnd = (u64) evt->mult - 1;
|
||||
|
||||
/*
|
||||
|
@ -164,10 +158,8 @@ void clockevents_switch_state(struct clock_event_device *dev,
|
|||
* on it, so fix it up and emit a warning:
|
||||
*/
|
||||
if (clockevent_state_oneshot(dev)) {
|
||||
if (unlikely(!dev->mult)) {
|
||||
if (WARN_ON(!dev->mult))
|
||||
dev->mult = 1;
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -315,10 +307,8 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
|
|||
int64_t delta;
|
||||
int rc;
|
||||
|
||||
if (unlikely(expires < 0)) {
|
||||
WARN_ON_ONCE(1);
|
||||
if (WARN_ON_ONCE(expires < 0))
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
dev->next_event = expires;
|
||||
|
||||
|
|
|
@ -1,26 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* linux/kernel/time/clocksource.c
|
||||
*
|
||||
* This file contains the functions which manage clocksource drivers.
|
||||
*
|
||||
* Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* TODO WishList:
|
||||
* o Allow clocksource drivers to be unregistered
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
|
|
@ -1,34 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/hrtimer.c
|
||||
*
|
||||
* Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
|
||||
* Copyright(C) 2006-2007 Timesys Corp., Thomas Gleixner
|
||||
*
|
||||
* High-resolution kernel timers
|
||||
*
|
||||
* In contrast to the low-resolution timeout API implemented in
|
||||
* kernel/timer.c, hrtimers provide finer resolution and accuracy
|
||||
* depending on system configuration and capabilities.
|
||||
*
|
||||
* These timers are currently used for:
|
||||
* - itimers
|
||||
* - POSIX timers
|
||||
* - nanosleep
|
||||
* - precise in-kernel timing
|
||||
* In contrast to the low-resolution timeout API, aka timer wheel,
|
||||
* hrtimers provide finer resolution and accuracy depending on system
|
||||
* configuration and capabilities.
|
||||
*
|
||||
* Started by: Thomas Gleixner and Ingo Molnar
|
||||
*
|
||||
* Credits:
|
||||
* based on kernel/timer.c
|
||||
* Based on the original timer wheel code
|
||||
*
|
||||
* Help, testing, suggestions, bugfixes, improvements were
|
||||
* provided by:
|
||||
*
|
||||
* George Anzinger, Andrew Morton, Steven Rostedt, Roman Zippel
|
||||
* et. al.
|
||||
*
|
||||
* For licencing details see kernel-base/COPYING
|
||||
*/
|
||||
|
||||
#include <linux/cpu.h>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/itimer.c
|
||||
*
|
||||
* Copyright (C) 1992 Darren Senn
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,25 +1,9 @@
|
|||
/***********************************************************************
|
||||
* linux/kernel/time/jiffies.c
|
||||
*
|
||||
* This file contains the jiffies based clocksource.
|
||||
*
|
||||
* Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
************************************************************************/
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* This file contains the jiffies based clocksource.
|
||||
*
|
||||
* Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
|
||||
*/
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/math64.h>
|
||||
|
||||
#include "ntp_internal.h"
|
||||
#include "timekeeping_internal.h"
|
||||
|
|
|
@ -1,21 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* posix-clock.c - support for dynamic clock devices
|
||||
* Support for dynamic clock devices
|
||||
*
|
||||
* Copyright (C) 2010 OMICRON electronics GmbH
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include <linux/export.h>
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Dummy stubs used when CONFIG_POSIX_TIMERS=n
|
||||
*
|
||||
* Created by: Nicolas Pitre, July 2016
|
||||
* Copyright: (C) 2016 Linaro Limited
|
||||
*
|
||||
* 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 <linux/linkage.h>
|
||||
|
|
|
@ -1,34 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* linux/kernel/posix-timers.c
|
||||
*
|
||||
*
|
||||
* 2002-10-15 Posix Clocks & timers
|
||||
* by George Anzinger george@mvista.com
|
||||
*
|
||||
* Copyright (C) 2002 2003 by MontaVista Software.
|
||||
*
|
||||
* 2004-06-01 Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
|
||||
* Copyright (C) 2004 Boris Hu
|
||||
*
|
||||
* 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.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* MontaVista Software | 1237 East Arques Avenue | Sunnyvale | CA 94085 | USA
|
||||
*/
|
||||
|
||||
/* These are all the functions necessary to implement
|
||||
* POSIX clocks & timers
|
||||
* These are all the functions necessary to implement POSIX clocks & timers
|
||||
*/
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* sched_clock.c: Generic sched_clock() support, to extend low level
|
||||
* hardware time counters to full 64-bit ns values.
|
||||
*
|
||||
* 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.
|
||||
* Generic sched_clock() support, to extend low level hardware time
|
||||
* counters to full 64-bit ns values.
|
||||
*/
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/init.h>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* udelay() test kernel module
|
||||
*
|
||||
|
@ -7,15 +8,6 @@
|
|||
* Specifying usecs of 0 or negative values will run multiples tests.
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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 <linux/debugfs.h>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/tick-broadcast-hrtimer.c
|
||||
* This file emulates a local clock event device
|
||||
* via a pseudo clock device.
|
||||
* Emulate a local clock event device via a pseudo clock device.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/err.h>
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/tick-broadcast.c
|
||||
*
|
||||
* This file contains functions which emulate a local clock-event
|
||||
* device via a broadcast event source.
|
||||
*
|
||||
* Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
|
||||
* Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
|
||||
*
|
||||
* This code is licenced under the GPL version 2. For details see
|
||||
* kernel-base/COPYING.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/err.h>
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/tick-common.c
|
||||
*
|
||||
* This file contains the base functions to manage periodic tick
|
||||
* related events.
|
||||
*
|
||||
* Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
|
||||
* Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
|
||||
*
|
||||
* This code is licenced under the GPL version 2. For details see
|
||||
* kernel-base/COPYING.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/err.h>
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/tick-oneshot.c
|
||||
*
|
||||
* This file contains functions which manage high resolution tick
|
||||
* related events.
|
||||
*
|
||||
* Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
|
||||
* Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
|
||||
*
|
||||
* This code is licenced under the GPL version 2. For details see
|
||||
* kernel-base/COPYING.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/err.h>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/tick-sched.c
|
||||
*
|
||||
* Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
|
||||
* Copyright(C) 2006-2007 Timesys Corp., Thomas Gleixner
|
||||
|
@ -8,8 +7,6 @@
|
|||
* No idle tick implementation for low and high resolution timers
|
||||
*
|
||||
* Started by: Thomas Gleixner and Ingo Molnar
|
||||
*
|
||||
* Distribute under GPLv2.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/err.h>
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*
|
||||
* This file contains the interface functions for the various
|
||||
* time related system calls: time, stime, gettimeofday, settimeofday,
|
||||
* adjtime
|
||||
*/
|
||||
/*
|
||||
* Modification history kernel/time.c
|
||||
* This file contains the interface functions for the various time related
|
||||
* system calls: time, stime, gettimeofday, settimeofday, adjtime
|
||||
*
|
||||
* Modification history:
|
||||
*
|
||||
* 1993-09-02 Philip Gladstone
|
||||
* Created file with time related functions from sched/core.c and adjtimex()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
scale=0
|
||||
|
||||
define gcd(a,b) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: LGPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
* This file is part of the GNU C Library.
|
||||
|
|
|
@ -1,20 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* linux/kernel/time/timecounter.c
|
||||
*
|
||||
* based on code that migrated away from
|
||||
* linux/kernel/time/clocksource.c
|
||||
*
|
||||
* 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.
|
||||
* Based on clocksource code. See commit 74d23cc704d1
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/timecounter.h>
|
||||
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/time/timekeeping.c
|
||||
*
|
||||
* Kernel timekeeping code and accessor functions
|
||||
*
|
||||
* This code was moved from linux/kernel/timer.c.
|
||||
* Please see that file for copyright and history logs.
|
||||
*
|
||||
* Kernel timekeeping code and accessor functions. Based on code from
|
||||
* timer.c, moved in commit 8524070b7982.
|
||||
*/
|
||||
|
||||
#include <linux/timekeeper_internal.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -50,7 +45,9 @@ enum timekeeping_adv_mode {
|
|||
static struct {
|
||||
seqcount_t seq;
|
||||
struct timekeeper timekeeper;
|
||||
} tk_core ____cacheline_aligned;
|
||||
} tk_core ____cacheline_aligned = {
|
||||
.seq = SEQCNT_ZERO(tk_core.seq),
|
||||
};
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(timekeeper_lock);
|
||||
static struct timekeeper shadow_timekeeper;
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* debugfs file to track time spent in suspend
|
||||
*
|
||||
* Copyright (c) 2011, Google, Inc.
|
||||
*
|
||||
* 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 <linux/debugfs.h>
|
||||
|
@ -28,7 +19,7 @@
|
|||
|
||||
static unsigned int sleep_time_bin[NUM_BINS] = {0};
|
||||
|
||||
static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
|
||||
static int tk_debug_sleep_time_show(struct seq_file *s, void *data)
|
||||
{
|
||||
unsigned int bin;
|
||||
seq_puts(s, " time (secs) count\n");
|
||||
|
@ -42,18 +33,7 @@ static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tk_debug_sleep_time_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, tk_debug_show_sleep_time, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations tk_debug_sleep_time_fops = {
|
||||
.open = tk_debug_sleep_time_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(tk_debug_sleep_time);
|
||||
|
||||
static int __init tk_debug_sleep_time_init(void)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* linux/kernel/timer.c
|
||||
*
|
||||
* Kernel internal timers
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* kernel/time/timer_list.c
|
||||
*
|
||||
* List pending timers
|
||||
*
|
||||
* Copyright(C) 2006, Red Hat, Inc., Ingo Molnar
|
||||
*
|
||||
* 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 <linux/proc_fs.h>
|
||||
|
|
Loading…
Reference in New Issue