Commit a67ca893 authored by Thomas Gleixner's avatar Thomas Gleixner

Merge tag 'timers-v5.5-rc6' of https://git.linaro.org/people/daniel.lezcano/linux into timers/core

Pull clocksource/events driver updates from Daniel Lezcano

  - Add suspend/resume for Hyper-V clocksource (Dexuan Cui)

  - Fix Kconfig indentation (Krzysztof Kozlowski)

  - Add SoC specific bindings for RZ/G2N (r8a774b1) (Biju Das)

  - Add Microchip PIT64B support (Claudiu Beznea)

  - Convert the cadence ttc driver to a platform driver to initialize
    later (Rajan Vaja)

  - Fix a memory leak when the initialization fails on bcm2835 (Colin
    Ian King)

  - Use the combo devm_platform_ioremap_resource() function for em-sti,
    ti-dm and switch to platform_get_irq (Yangtao Li)

  - Fix Exynos naming in the driver (Krzysztof Kozlowski)

  - Fix an uninitialized pointer access in ti-dm timer (Tony Lindgren)

  - Fix a sparse warning in microchip-pit64b (Claudiu Beznea)

  - Code reorg without functional changes for Hyper-V clocksource
    (Andrea Parri)

  - Decrease the Hyper-V clocksource rating in order to let the stable
    TSC to be selected instead (Andrea Parri)
parents 49a101d7 9e0333ae
...@@ -10,6 +10,12 @@ PIT Timer required properties: ...@@ -10,6 +10,12 @@ PIT Timer required properties:
- interrupts: Should contain interrupt for the PIT which is the IRQ line - interrupts: Should contain interrupt for the PIT which is the IRQ line
shared across all System Controller members. shared across all System Controller members.
PIT64B Timer required properties:
- compatible: Should be "microchip,sam9x60-pit64b"
- reg: Should contain registers location and length
- interrupts: Should contain interrupt for PIT64B timer
- clocks: Should contain the available clock sources for PIT64B timer.
System Timer (ST) required properties: System Timer (ST) required properties:
- compatible: Should be "atmel,at91rm9200-st", "syscon", "simple-mfd" - compatible: Should be "atmel,at91rm9200-st", "syscon", "simple-mfd"
- reg: Should contain registers location and length - reg: Should contain registers location and length
......
...@@ -29,6 +29,8 @@ Required Properties: ...@@ -29,6 +29,8 @@ Required Properties:
- "renesas,r8a77470-cmt1" for the 48-bit CMT1 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-cmt0" for the 32-bit CMT0 device included in r8a774a1.
- "renesas,r8a774a1-cmt1" for the 48-bit CMT devices included in r8a774a1. - "renesas,r8a774a1-cmt1" for the 48-bit CMT devices included in r8a774a1.
- "renesas,r8a774b1-cmt0" for the 32-bit CMT0 device included in r8a774b1.
- "renesas,r8a774b1-cmt1" for the 48-bit CMT devices included in r8a774b1.
- "renesas,r8a774c0-cmt0" for the 32-bit CMT0 device included in r8a774c0. - "renesas,r8a774c0-cmt0" for the 32-bit CMT0 device included in r8a774c0.
- "renesas,r8a774c0-cmt1" for the 48-bit CMT devices included in r8a774c0. - "renesas,r8a774c0-cmt1" for the 48-bit CMT devices included in r8a774c0.
- "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790. - "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
......
...@@ -88,7 +88,7 @@ config ROCKCHIP_TIMER ...@@ -88,7 +88,7 @@ config ROCKCHIP_TIMER
select TIMER_OF select TIMER_OF
select CLKSRC_MMIO select CLKSRC_MMIO
help help
Enables the support for the rockchip timer driver. Enables the support for the Rockchip timer driver.
config ARMADA_370_XP_TIMER config ARMADA_370_XP_TIMER
bool "Armada 370 and XP timer driver" if COMPILE_TEST bool "Armada 370 and XP timer driver" if COMPILE_TEST
...@@ -162,13 +162,13 @@ config NPCM7XX_TIMER ...@@ -162,13 +162,13 @@ config NPCM7XX_TIMER
select CLKSRC_MMIO select CLKSRC_MMIO
help help
Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture, Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture,
While TIMER0 serves as clockevent and TIMER1 serves as clocksource. where TIMER0 serves as clockevent and TIMER1 serves as clocksource.
config CADENCE_TTC_TIMER config CADENCE_TTC_TIMER
bool "Cadence TTC timer driver" if COMPILE_TEST bool "Cadence TTC timer driver" if COMPILE_TEST
depends on COMMON_CLK depends on COMMON_CLK
help help
Enables support for the cadence ttc driver. Enables support for the Cadence TTC driver.
config ASM9260_TIMER config ASM9260_TIMER
bool "ASM9260 timer driver" if COMPILE_TEST bool "ASM9260 timer driver" if COMPILE_TEST
...@@ -190,10 +190,10 @@ config CLKSRC_DBX500_PRCMU ...@@ -190,10 +190,10 @@ config CLKSRC_DBX500_PRCMU
bool "Clocksource PRCMU Timer" if COMPILE_TEST bool "Clocksource PRCMU Timer" if COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
help help
Use the always on PRCMU Timer as clocksource Use the always on PRCMU Timer as clocksource.
config CLPS711X_TIMER config CLPS711X_TIMER
bool "Cirrus logic timer driver" if COMPILE_TEST bool "Cirrus Logic timer driver" if COMPILE_TEST
select CLKSRC_MMIO select CLKSRC_MMIO
help help
Enables support for the Cirrus Logic PS711 timer. Enables support for the Cirrus Logic PS711 timer.
...@@ -205,11 +205,11 @@ config ATLAS7_TIMER ...@@ -205,11 +205,11 @@ config ATLAS7_TIMER
Enables support for the Atlas7 timer. Enables support for the Atlas7 timer.
config MXS_TIMER config MXS_TIMER
bool "Mxs timer driver" if COMPILE_TEST bool "MXS timer driver" if COMPILE_TEST
select CLKSRC_MMIO select CLKSRC_MMIO
select STMP_DEVICE select STMP_DEVICE
help help
Enables support for the Mxs timer. Enables support for the MXS timer.
config PRIMA2_TIMER config PRIMA2_TIMER
bool "Prima2 timer driver" if COMPILE_TEST bool "Prima2 timer driver" if COMPILE_TEST
...@@ -238,10 +238,10 @@ config KEYSTONE_TIMER ...@@ -238,10 +238,10 @@ config KEYSTONE_TIMER
Enables support for the Keystone timer. Enables support for the Keystone timer.
config INTEGRATOR_AP_TIMER config INTEGRATOR_AP_TIMER
bool "Integrator-ap timer driver" if COMPILE_TEST bool "Integrator-AP timer driver" if COMPILE_TEST
select CLKSRC_MMIO select CLKSRC_MMIO
help help
Enables support for the Integrator-ap timer. Enables support for the Integrator-AP timer.
config CLKSRC_EFM32 config CLKSRC_EFM32
bool "Clocksource for Energy Micro's EFM32 SoCs" if !ARCH_EFM32 bool "Clocksource for Energy Micro's EFM32 SoCs" if !ARCH_EFM32
...@@ -283,8 +283,8 @@ config CLKSRC_NPS ...@@ -283,8 +283,8 @@ config CLKSRC_NPS
select TIMER_OF if OF select TIMER_OF if OF
help help
NPS400 clocksource support. NPS400 clocksource support.
Got 64 bit counter with update rate up to 1000MHz. It has a 64-bit counter with update rate up to 1000MHz.
This counter is accessed via couple of 32 bit memory mapped registers. This counter is accessed via couple of 32-bit memory-mapped registers.
config CLKSRC_STM32 config CLKSRC_STM32
bool "Clocksource for STM32 SoCs" if !ARCH_STM32 bool "Clocksource for STM32 SoCs" if !ARCH_STM32
...@@ -305,14 +305,14 @@ config ARC_TIMERS ...@@ -305,14 +305,14 @@ config ARC_TIMERS
help help
These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores
(ARC700 as well as ARC HS38). (ARC700 as well as ARC HS38).
TIMER0 serves as clockevent while TIMER1 provides clocksource TIMER0 serves as clockevent while TIMER1 provides clocksource.
config ARC_TIMERS_64BIT config ARC_TIMERS_64BIT
bool "Support for 64-bit counters in ARC HS38 cores" if COMPILE_TEST bool "Support for 64-bit counters in ARC HS38 cores" if COMPILE_TEST
depends on ARC_TIMERS depends on ARC_TIMERS
select TIMER_OF select TIMER_OF
help help
This enables 2 different 64-bit timers: RTC (for UP) and GFRC (for SMP) This enables 2 different 64-bit timers: RTC (for UP) and GFRC (for SMP).
RTC is implemented inside the core, while GFRC sits outside the core in RTC is implemented inside the core, while GFRC sits outside the core in
ARConnect IP block. Driver automatically picks one of them for clocksource ARConnect IP block. Driver automatically picks one of them for clocksource
as appropriate. as appropriate.
...@@ -390,7 +390,7 @@ config ARM_GLOBAL_TIMER ...@@ -390,7 +390,7 @@ config ARM_GLOBAL_TIMER
select TIMER_OF if OF select TIMER_OF if OF
depends on ARM depends on ARM
help help
This options enables support for the ARM global timer unit This option enables support for the ARM global timer unit.
config ARM_TIMER_SP804 config ARM_TIMER_SP804
bool "Support for Dual Timer SP804 module" if COMPILE_TEST bool "Support for Dual Timer SP804 module" if COMPILE_TEST
...@@ -403,14 +403,14 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK ...@@ -403,14 +403,14 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
depends on ARM_GLOBAL_TIMER depends on ARM_GLOBAL_TIMER
default y default y
help help
Use ARM global timer clock source as sched_clock Use ARM global timer clock source as sched_clock.
config ARMV7M_SYSTICK config ARMV7M_SYSTICK
bool "Support for the ARMv7M system time" if COMPILE_TEST bool "Support for the ARMv7M system time" if COMPILE_TEST
select TIMER_OF if OF select TIMER_OF if OF
select CLKSRC_MMIO select CLKSRC_MMIO
help help
This options enables support for the ARMv7M system timer unit This option enables support for the ARMv7M system timer unit.
config ATMEL_PIT config ATMEL_PIT
bool "Atmel PIT support" if COMPILE_TEST bool "Atmel PIT support" if COMPILE_TEST
...@@ -460,7 +460,7 @@ config VF_PIT_TIMER ...@@ -460,7 +460,7 @@ config VF_PIT_TIMER
bool bool
select CLKSRC_MMIO select CLKSRC_MMIO
help help
Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. Support for Periodic Interrupt Timer on Freescale Vybrid Family SoCs.
config OXNAS_RPS_TIMER config OXNAS_RPS_TIMER
bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST bool "Oxford Semiconductor OXNAS RPS Timers driver" if COMPILE_TEST
...@@ -470,7 +470,7 @@ config OXNAS_RPS_TIMER ...@@ -470,7 +470,7 @@ config OXNAS_RPS_TIMER
This enables support for the Oxford Semiconductor OXNAS RPS timers. This enables support for the Oxford Semiconductor OXNAS RPS timers.
config SYS_SUPPORTS_SH_CMT config SYS_SUPPORTS_SH_CMT
bool bool
config MTK_TIMER config MTK_TIMER
bool "Mediatek timer driver" if COMPILE_TEST bool "Mediatek timer driver" if COMPILE_TEST
...@@ -490,13 +490,13 @@ config SPRD_TIMER ...@@ -490,13 +490,13 @@ config SPRD_TIMER
Enables support for the Spreadtrum timer driver. Enables support for the Spreadtrum timer driver.
config SYS_SUPPORTS_SH_MTU2 config SYS_SUPPORTS_SH_MTU2
bool bool
config SYS_SUPPORTS_SH_TMU config SYS_SUPPORTS_SH_TMU
bool bool
config SYS_SUPPORTS_EM_STI config SYS_SUPPORTS_EM_STI
bool bool
config CLKSRC_JCORE_PIT config CLKSRC_JCORE_PIT
bool "J-Core PIT timer driver" if COMPILE_TEST bool "J-Core PIT timer driver" if COMPILE_TEST
...@@ -523,7 +523,7 @@ config SH_TIMER_MTU2 ...@@ -523,7 +523,7 @@ config SH_TIMER_MTU2
help help
This enables build of a clockevent driver for the Multi-Function This enables build of a clockevent driver for the Multi-Function
Timer Pulse Unit 2 (MTU2) hardware available on SoCs from Renesas. Timer Pulse Unit 2 (MTU2) hardware available on SoCs from Renesas.
This hardware comes with 16 bit-timer registers. This hardware comes with 16-bit timer registers.
config RENESAS_OSTM config RENESAS_OSTM
bool "Renesas OSTM timer driver" if COMPILE_TEST bool "Renesas OSTM timer driver" if COMPILE_TEST
...@@ -580,7 +580,7 @@ config CLKSRC_TANGO_XTAL ...@@ -580,7 +580,7 @@ config CLKSRC_TANGO_XTAL
select TIMER_OF select TIMER_OF
select CLKSRC_MMIO select CLKSRC_MMIO
help help
This enables the clocksource for Tango SoC This enables the clocksource for Tango SoC.
config CLKSRC_PXA config CLKSRC_PXA
bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST
...@@ -591,24 +591,24 @@ config CLKSRC_PXA ...@@ -591,24 +591,24 @@ config CLKSRC_PXA
platforms. platforms.
config H8300_TMR8 config H8300_TMR8
bool "Clockevent timer for the H8300 platform" if COMPILE_TEST bool "Clockevent timer for the H8300 platform" if COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
help help
This enables the 8 bits timer for the H8300 platform. This enables the 8 bits timer for the H8300 platform.
config H8300_TMR16 config H8300_TMR16
bool "Clockevent timer for the H83069 platform" if COMPILE_TEST bool "Clockevent timer for the H83069 platform" if COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
help help
This enables the 16 bits timer for the H8300 platform with the This enables the 16 bits timer for the H8300 platform with the
H83069 cpu. H83069 CPU.
config H8300_TPU config H8300_TPU
bool "Clocksource for the H8300 platform" if COMPILE_TEST bool "Clocksource for the H8300 platform" if COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
help help
This enables the clocksource for the H8300 platform with the This enables the clocksource for the H8300 platform with the
H8S2678 cpu. H8S2678 CPU.
config CLKSRC_IMX_GPT config CLKSRC_IMX_GPT
bool "Clocksource using i.MX GPT" if COMPILE_TEST bool "Clocksource using i.MX GPT" if COMPILE_TEST
...@@ -666,8 +666,8 @@ config CSKY_MP_TIMER ...@@ -666,8 +666,8 @@ config CSKY_MP_TIMER
help help
Say yes here to enable C-SKY SMP timer driver used for C-SKY SMP Say yes here to enable C-SKY SMP timer driver used for C-SKY SMP
system. system.
csky,mptimer is not only used in SMP system, it also could be used csky,mptimer is not only used in SMP system, it also could be used in
single core system. It's not a mmio reg and it use mtcr/mfcr instruction. single core system. It's not a mmio reg and it uses mtcr/mfcr instruction.
config GX6605S_TIMER config GX6605S_TIMER
bool "Gx6605s SOC system timer driver" if COMPILE_TEST bool "Gx6605s SOC system timer driver" if COMPILE_TEST
...@@ -697,4 +697,14 @@ config INGENIC_TIMER ...@@ -697,4 +697,14 @@ config INGENIC_TIMER
help help
Support for the timer/counter unit of the Ingenic JZ SoCs. Support for the timer/counter unit of the Ingenic JZ SoCs.
config MICROCHIP_PIT64B
bool "Microchip PIT64B support"
depends on OF || COMPILE_TEST
select CLKSRC_MMIO
help
This option enables Microchip PIT64B timer for Atmel
based system. It supports the oneshot, the periodic
modes and high resolution. It is used as a clocksource
and a clockevent.
endmenu endmenu
...@@ -88,3 +88,4 @@ obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o ...@@ -88,3 +88,4 @@ obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o
...@@ -121,7 +121,7 @@ static int __init bcm2835_timer_init(struct device_node *node) ...@@ -121,7 +121,7 @@ static int __init bcm2835_timer_init(struct device_node *node)
ret = setup_irq(irq, &timer->act); ret = setup_irq(irq, &timer->act);
if (ret) { if (ret) {
pr_err("Can't set up timer IRQ\n"); pr_err("Can't set up timer IRQ\n");
goto err_iounmap; goto err_timer_free;
} }
clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
...@@ -130,6 +130,9 @@ static int __init bcm2835_timer_init(struct device_node *node) ...@@ -130,6 +130,9 @@ static int __init bcm2835_timer_init(struct device_node *node)
return 0; return 0;
err_timer_free:
kfree(timer);
err_iounmap: err_iounmap:
iounmap(base); iounmap(base);
return ret; return ret;
......
...@@ -279,9 +279,7 @@ static void em_sti_register_clockevent(struct em_sti_priv *p) ...@@ -279,9 +279,7 @@ static void em_sti_register_clockevent(struct em_sti_priv *p)
static int em_sti_probe(struct platform_device *pdev) static int em_sti_probe(struct platform_device *pdev)
{ {
struct em_sti_priv *p; struct em_sti_priv *p;
struct resource *res; int irq, ret;
int irq;
int ret;
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
if (p == NULL) if (p == NULL)
...@@ -295,8 +293,7 @@ static int em_sti_probe(struct platform_device *pdev) ...@@ -295,8 +293,7 @@ static int em_sti_probe(struct platform_device *pdev)
return irq; return irq;
/* map memory, let base point to the STI instance */ /* map memory, let base point to the STI instance */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); p->base = devm_platform_ioremap_resource(pdev, 0);
p->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(p->base)) if (IS_ERR(p->base))
return PTR_ERR(p->base); return PTR_ERR(p->base);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (c) 2011 Samsung Electronics Co., Ltd. * Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com * http://www.samsung.com
* *
* EXYNOS4 MCT(Multi-Core Timer) support * Exynos4 MCT(Multi-Core Timer) support
*/ */
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
...@@ -66,7 +66,7 @@ static int hv_ce_set_next_event(unsigned long delta, ...@@ -66,7 +66,7 @@ static int hv_ce_set_next_event(unsigned long delta,
{ {
u64 current_tick; u64 current_tick;
current_tick = hyperv_cs->read(NULL); current_tick = hv_read_reference_counter();
current_tick += delta; current_tick += delta;
hv_init_timer(0, current_tick); hv_init_timer(0, current_tick);
return 0; return 0;
...@@ -302,22 +302,33 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup); ...@@ -302,22 +302,33 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
* the other that uses the TSC reference page feature as defined in the * the other that uses the TSC reference page feature as defined in the
* TLFS. The MSR version is for compatibility with old versions of * TLFS. The MSR version is for compatibility with old versions of
* Hyper-V and 32-bit x86. The TSC reference page version is preferred. * Hyper-V and 32-bit x86. The TSC reference page version is preferred.
*
* The Hyper-V clocksource ratings of 250 are chosen to be below the
* TSC clocksource rating of 300. In configurations where Hyper-V offers
* an InvariantTSC, the TSC is not marked "unstable", so the TSC clocksource
* is available and preferred. With the higher rating, it will be the
* default. On older hardware and Hyper-V versions, the TSC is marked
* "unstable", so no TSC clocksource is created and the selected Hyper-V
* clocksource will be the default.
*/ */
struct clocksource *hyperv_cs; u64 (*hv_read_reference_counter)(void);
EXPORT_SYMBOL_GPL(hyperv_cs); EXPORT_SYMBOL_GPL(hv_read_reference_counter);
static struct ms_hyperv_tsc_page tsc_pg __aligned(PAGE_SIZE); static union {
struct ms_hyperv_tsc_page page;
u8 reserved[PAGE_SIZE];
} tsc_pg __aligned(PAGE_SIZE);
struct ms_hyperv_tsc_page *hv_get_tsc_page(void) struct ms_hyperv_tsc_page *hv_get_tsc_page(void)
{ {
return &tsc_pg; return &tsc_pg.page;
} }
EXPORT_SYMBOL_GPL(hv_get_tsc_page); EXPORT_SYMBOL_GPL(hv_get_tsc_page);
static u64 notrace read_hv_clock_tsc(struct clocksource *arg) static u64 notrace read_hv_clock_tsc(void)
{ {
u64 current_tick = hv_read_tsc_page(&tsc_pg); u64 current_tick = hv_read_tsc_page(hv_get_tsc_page());
if (current_tick == U64_MAX) if (current_tick == U64_MAX)
hv_get_time_ref_count(current_tick); hv_get_time_ref_count(current_tick);
...@@ -325,20 +336,50 @@ static u64 notrace read_hv_clock_tsc(struct clocksource *arg) ...@@ -325,20 +336,50 @@ static u64 notrace read_hv_clock_tsc(struct clocksource *arg)
return current_tick; return current_tick;
} }
static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg)
{
return read_hv_clock_tsc();
}
static u64 read_hv_sched_clock_tsc(void) static u64 read_hv_sched_clock_tsc(void)
{ {
return read_hv_clock_tsc(NULL) - hv_sched_clock_offset; return read_hv_clock_tsc() - hv_sched_clock_offset;
}
static void suspend_hv_clock_tsc(struct clocksource *arg)
{
u64 tsc_msr;
/* Disable the TSC page */
hv_get_reference_tsc(tsc_msr);
tsc_msr &= ~BIT_ULL(0);
hv_set_reference_tsc(tsc_msr);
}
static void resume_hv_clock_tsc(struct clocksource *arg)
{
phys_addr_t phys_addr = virt_to_phys(&tsc_pg);
u64 tsc_msr;
/* Re-enable the TSC page */
hv_get_reference_tsc(tsc_msr);
tsc_msr &= GENMASK_ULL(11, 0);
tsc_msr |= BIT_ULL(0) | (u64)phys_addr;
hv_set_reference_tsc(tsc_msr);
} }
static struct clocksource hyperv_cs_tsc = { static struct clocksource hyperv_cs_tsc = {
.name = "hyperv_clocksource_tsc_page", .name = "hyperv_clocksource_tsc_page",
.rating = 400, .rating = 250,
.read = read_hv_clock_tsc, .read = read_hv_clock_tsc_cs,
.mask = CLOCKSOURCE_MASK(64), .mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS, .flags = CLOCK_SOURCE_IS_CONTINUOUS,
.suspend= suspend_hv_clock_tsc,
.resume = resume_hv_clock_tsc,
}; };
static u64 notrace read_hv_clock_msr(struct clocksource *arg) static u64 notrace read_hv_clock_msr(void)
{ {
u64 current_tick; u64 current_tick;
/* /*
...@@ -350,15 +391,20 @@ static u64 notrace read_hv_clock_msr(struct clocksource *arg) ...@@ -350,15 +391,20 @@ static u64 notrace read_hv_clock_msr(struct clocksource *arg)
return current_tick; return current_tick;
} }
static u64 notrace read_hv_clock_msr_cs(struct clocksource *arg)
{
return read_hv_clock_msr();
}
static u64 read_hv_sched_clock_msr(void) static u64 read_hv_sched_clock_msr(void)
{ {
return read_hv_clock_msr(NULL) - hv_sched_clock_offset; return read_hv_clock_msr() - hv_sched_clock_offset;
} }
static struct clocksource hyperv_cs_msr = { static struct clocksource hyperv_cs_msr = {
.name = "hyperv_clocksource_msr", .name = "hyperv_clocksource_msr",
.rating = 400, .rating = 250,
.read = read_hv_clock_msr, .read = read_hv_clock_msr_cs,
.mask = CLOCKSOURCE_MASK(64), .mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS, .flags = CLOCK_SOURCE_IS_CONTINUOUS,
}; };
...@@ -371,8 +417,8 @@ static bool __init hv_init_tsc_clocksource(void) ...@@ -371,8 +417,8 @@ static bool __init hv_init_tsc_clocksource(void)
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE)) if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
return false; return false;
hyperv_cs = &hyperv_cs_tsc; hv_read_reference_counter = read_hv_clock_tsc;
phys_addr = virt_to_phys(&tsc_pg); phys_addr = virt_to_phys(hv_get_tsc_page());
/* /*
* The Hyper-V TLFS specifies to preserve the value of reserved * The Hyper-V TLFS specifies to preserve the value of reserved
...@@ -389,7 +435,7 @@ static bool __init hv_init_tsc_clocksource(void) ...@@ -389,7 +435,7 @@ static bool __init hv_init_tsc_clocksource(void)
hv_set_clocksource_vdso(hyperv_cs_tsc); hv_set_clocksource_vdso(hyperv_cs_tsc);
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100); clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
hv_sched_clock_offset = hyperv_cs->read(hyperv_cs); hv_sched_clock_offset = hv_read_reference_counter();
hv_setup_sched_clock(read_hv_sched_clock_tsc); hv_setup_sched_clock(read_hv_sched_clock_tsc);
return true; return true;
...@@ -411,10 +457,10 @@ void __init hv_init_clocksource(void) ...@@ -411,10 +457,10 @@ void __init hv_init_clocksource(void)
if (!(ms_hyperv.features & HV_MSR_TIME_REF_COUNT_AVAILABLE)) if (!(ms_hyperv.features & HV_MSR_TIME_REF_COUNT_AVAILABLE))
return; return;
hyperv_cs = &hyperv_cs_msr; hv_read_reference_counter = read_hv_clock_msr;
clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100); clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
hv_sched_clock_offset = hyperv_cs->read(hyperv_cs); hv_sched_clock_offset = hv_read_reference_counter();
hv_setup_sched_clock(read_hv_sched_clock_msr); hv_setup_sched_clock(read_hv_sched_clock_msr);
} }
EXPORT_SYMBOL_GPL(hv_init_clocksource); EXPORT_SYMBOL_GPL(hv_init_clocksource);
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
#include <linux/module.h>
#include <linux/of_platform.h>
/* /*
* This driver configures the 2 16/32-bit count-up timers as follows: * This driver configures the 2 16/32-bit count-up timers as follows:
...@@ -464,13 +466,7 @@ static int __init ttc_setup_clockevent(struct clk *clk, ...@@ -464,13 +466,7 @@ static int __init ttc_setup_clockevent(struct clk *clk,
return 0; return 0;
} }
/** static int __init ttc_timer_probe(struct platform_device *pdev)
* ttc_timer_init - Initialize the timer
*
* Initializes the timer hardware and register the clock source and clock event
* timers with Linux kernal timer framework
*/
static int __init ttc_timer_init(struct device_node *timer)
{ {
unsigned int irq; unsigned int irq;
void __iomem *timer_baseaddr; void __iomem *timer_baseaddr;
...@@ -478,6 +474,7 @@ static int __init ttc_timer_init(struct device_node *timer) ...@@ -478,6 +474,7 @@ static int __init ttc_timer_init(struct device_node *timer)
static int initialized; static int initialized;
int clksel, ret; int clksel, ret;
u32 timer_width = 16; u32 timer_width = 16;
struct device_node *timer = pdev->dev.of_node;
if (initialized) if (initialized)
return 0; return 0;
...@@ -532,4 +529,17 @@ static int __init ttc_timer_init(struct device_node *timer) ...@@ -532,4 +529,17 @@ static int __init ttc_timer_init(struct device_node *timer)
return 0; return 0;
} }
TIMER_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); static const struct of_device_id ttc_timer_of_match[] = {
{.compatible = "cdns,ttc"},
{},
};
MODULE_DEVICE_TABLE(of, ttc_timer_of_match);
static struct platform_driver ttc_timer_driver = {
.driver = {
.name = "cdns_ttc_timer",
.of_match_table = ttc_timer_of_match,
},
};
builtin_platform_driver_probe(ttc_timer_driver, ttc_timer_probe);
This diff is collapsed.
...@@ -780,7 +780,6 @@ static int omap_dm_timer_probe(struct platform_device *pdev) ...@@ -780,7 +780,6 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
{ {
unsigned long flags; unsigned long flags;
struct omap_dm_timer *timer; struct omap_dm_timer *timer;
struct resource *mem, *irq;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct dmtimer_platform_data *pdata; const struct dmtimer_platform_data *pdata;
int ret; int ret;
...@@ -796,24 +795,16 @@ static int omap_dm_timer_probe(struct platform_device *pdev) ...@@ -796,24 +795,16 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (unlikely(!irq)) {
dev_err(dev, "%s: no IRQ resource.\n", __func__);
return -ENODEV;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!mem)) {
dev_err(dev, "%s: no memory resource.\n", __func__);
return -ENODEV;
}
timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL); timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
if (!timer) if (!timer)
return -ENOMEM; return -ENOMEM;
timer->irq = platform_get_irq(pdev, 0);
if (timer->irq < 0)
return timer->irq;
timer->fclk = ERR_PTR(-ENODEV); timer->fclk = ERR_PTR(-ENODEV);
timer->io_base = devm_ioremap_resource(dev, mem); timer->io_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(timer->io_base)) if (IS_ERR(timer->io_base))
return PTR_ERR(timer->io_base); return PTR_ERR(timer->io_base);
...@@ -836,7 +827,6 @@ static int omap_dm_timer_probe(struct platform_device *pdev) ...@@ -836,7 +827,6 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
if (pdata) if (pdata)
timer->errata = pdata->timer_errata; timer->errata = pdata->timer_errata;
timer->irq = irq->start;
timer->pdev = pdev; timer->pdev = pdev;
pm_runtime_enable(dev); pm_runtime_enable(dev);
......
...@@ -211,7 +211,7 @@ static struct timespec64 hv_get_adj_host_time(void) ...@@ -211,7 +211,7 @@ static struct timespec64 hv_get_adj_host_time(void)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&host_ts.lock, flags); spin_lock_irqsave(&host_ts.lock, flags);
reftime = hyperv_cs->read(hyperv_cs); reftime = hv_read_reference_counter();
newtime = host_ts.host_time + (reftime - host_ts.ref_time); newtime = host_ts.host_time + (reftime - host_ts.ref_time);
ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100); ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100);
spin_unlock_irqrestore(&host_ts.lock, flags); spin_unlock_irqrestore(&host_ts.lock, flags);
...@@ -250,7 +250,7 @@ static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags) ...@@ -250,7 +250,7 @@ static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags)
*/ */
spin_lock_irqsave(&host_ts.lock, flags); spin_lock_irqsave(&host_ts.lock, flags);
cur_reftime = hyperv_cs->read(hyperv_cs); cur_reftime = hv_read_reference_counter();
host_ts.host_time = hosttime; host_ts.host_time = hosttime;
host_ts.ref_time = cur_reftime; host_ts.ref_time = cur_reftime;
...@@ -315,7 +315,7 @@ static void timesync_onchannelcallback(void *context) ...@@ -315,7 +315,7 @@ static void timesync_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr) + sizeof(struct vmbuspipe_hdr) +
sizeof(struct icmsg_hdr)]; sizeof(struct icmsg_hdr)];
adj_guesttime(timedatap->parenttime, adj_guesttime(timedatap->parenttime,
hyperv_cs->read(hyperv_cs), hv_read_reference_counter(),
timedatap->flags); timedatap->flags);
} }
} }
...@@ -524,7 +524,7 @@ static struct ptp_clock *hv_ptp_clock; ...@@ -524,7 +524,7 @@ static struct ptp_clock *hv_ptp_clock;
static int hv_timesync_init(struct hv_util_service *srv) static int hv_timesync_init(struct hv_util_service *srv)
{ {
/* TimeSync requires Hyper-V clocksource. */ /* TimeSync requires Hyper-V clocksource. */
if (!hyperv_cs) if (!hv_read_reference_counter)
return -ENODEV; return -ENODEV;
spin_lock_init(&host_ts.lock); spin_lock_init(&host_ts.lock);
......
...@@ -30,7 +30,7 @@ extern void hv_stimer_global_cleanup(void); ...@@ -30,7 +30,7 @@ extern void hv_stimer_global_cleanup(void);
extern void hv_stimer0_isr(void); extern void hv_stimer0_isr(void);
#ifdef CONFIG_HYPERV_TIMER #ifdef CONFIG_HYPERV_TIMER
extern struct clocksource *hyperv_cs; extern u64 (*hv_read_reference_counter)(void);
extern void hv_init_clocksource(void); extern void hv_init_clocksource(void);
extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void); extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment