aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-12-05 02:32:16 -0500
committerOlof Johansson <olof@lixom.net>2014-12-05 02:32:16 -0500
commit6b34df9e30c8b596f9d0173ca17714076474458e (patch)
treea47b26e4ebb4d0aea10b3abbb620efa2a004ba8c
parente58e501a9b3e0db722263b02d6c06f1656a5dee7 (diff)
parent65b5732d241b8b39e07653794eefffd0d8028cbb (diff)
Merge branch 'clocksource/physical-timers' into next/drivers
* clocksource/physical-timers: clocksource: arch_timer: Allow the device tree to specify uninitialized timer registers clocksource: arch_timer: Fix code to use physical timers when requested
-rw-r--r--Documentation/devicetree/bindings/arm/arch_timer.txt8
-rw-r--r--arch/arm/include/asm/arch_timer.h9
-rw-r--r--arch/arm64/include/asm/arch_timer.h9
-rw-r--r--drivers/clocksource/arm_arch_timer.c13
4 files changed, 38 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
index 37b2cafa4e52..256b4d8bab7b 100644
--- a/Documentation/devicetree/bindings/arm/arch_timer.txt
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -22,6 +22,14 @@ to deliver its interrupts via SPIs.
22- always-on : a boolean property. If present, the timer is powered through an 22- always-on : a boolean property. If present, the timer is powered through an
23 always-on power domain, therefore it never loses context. 23 always-on power domain, therefore it never loses context.
24 24
25** Optional properties:
26
27- arm,cpu-registers-not-fw-configured : Firmware does not initialize
28 any of the generic timer CPU registers, which contain their
29 architecturally-defined reset values. Only supported for 32-bit
30 systems which follow the ARMv7 architected reset values.
31
32
25Example: 33Example:
26 34
27 timer { 35 timer {
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 92793ba69c40..d4ebf5679f1f 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -78,6 +78,15 @@ static inline u32 arch_timer_get_cntfrq(void)
78 return val; 78 return val;
79} 79}
80 80
81static inline u64 arch_counter_get_cntpct(void)
82{
83 u64 cval;
84
85 isb();
86 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
87 return cval;
88}
89
81static inline u64 arch_counter_get_cntvct(void) 90static inline u64 arch_counter_get_cntvct(void)
82{ 91{
83 u64 cval; 92 u64 cval;
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index f19097134b02..b1fa4e614718 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -104,6 +104,15 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
104 asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); 104 asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
105} 105}
106 106
107static inline u64 arch_counter_get_cntpct(void)
108{
109 /*
110 * AArch64 kernel and user space mandate the use of CNTVCT.
111 */
112 BUG();
113 return 0;
114}
115
107static inline u64 arch_counter_get_cntvct(void) 116static inline u64 arch_counter_get_cntvct(void)
108{ 117{
109 u64 cval; 118 u64 cval;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 43005d4d3348..6a79fc4f900c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -462,7 +462,10 @@ static void __init arch_counter_register(unsigned type)
462 462
463 /* Register the CP15 based counter if we have one */ 463 /* Register the CP15 based counter if we have one */
464 if (type & ARCH_CP15_TIMER) { 464 if (type & ARCH_CP15_TIMER) {
465 arch_timer_read_counter = arch_counter_get_cntvct; 465 if (arch_timer_use_virtual)
466 arch_timer_read_counter = arch_counter_get_cntvct;
467 else
468 arch_timer_read_counter = arch_counter_get_cntpct;
466 } else { 469 } else {
467 arch_timer_read_counter = arch_counter_get_cntvct_mem; 470 arch_timer_read_counter = arch_counter_get_cntvct_mem;
468 471
@@ -702,6 +705,14 @@ static void __init arch_timer_init(struct device_node *np)
702 arch_timer_detect_rate(NULL, np); 705 arch_timer_detect_rate(NULL, np);
703 706
704 /* 707 /*
708 * If we cannot rely on firmware initializing the timer registers then
709 * we should use the physical timers instead.
710 */
711 if (IS_ENABLED(CONFIG_ARM) &&
712 of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
713 arch_timer_use_virtual = false;
714
715 /*
705 * If HYP mode is available, we know that the physical timer 716 * If HYP mode is available, we know that the physical timer
706 * has been configured to be accessible from PL1. Use it, so 717 * has been configured to be accessible from PL1. Use it, so
707 * that a guest can use the virtual timer instead. 718 * that a guest can use the virtual timer instead.