diff options
author | Fu Wei <fu.wei@linaro.org> | 2017-01-18 08:25:30 -0500 |
---|---|---|
committer | Mark Rutland <mark.rutland@arm.com> | 2017-04-10 09:29:54 -0400 |
commit | 4502b6bb720d7a519c4cea76cf68a2425b481a45 (patch) | |
tree | 6e184182d79ce4882691b30e5c638bde1f100082 /drivers/clocksource/arm_arch_timer.c | |
parent | 097cd143dd871bfceacf4ed252b177cf515a1888 (diff) |
clocksource: arm_arch_timer: rework PPI selection
Currently, the arch timer driver uses ARCH_TIMER_PHYS_SECURE_PPI to mean
the driver will use the secure PPI *and* potentially also use the
non-secure PPI. This is somewhat confusing.
For arm64 it never makes sense to use the secure PPI, but we do anyway,
inheriting this behaviour from 32-bit arm. For ACPI, we may not even
have a valid secure PPI, so we need to be able to only request the
non-secure PPI.
To that end, this patch reworks the timer driver so that we can request
the non-secure PPI alone. The PPI selection is split out into a new
function, arch_timer_select_ppi(), and verification of the selected PPI
is shifted out to callers (as DT may select the PPI by other means and
must handle this anyway).
We now consistently use arch_timer_has_nonsecure_ppi() to determine
whether we must manage a non-secure PPI *in addition* to a secure PPI.
When we only have a non-secure PPI, this returns false.
Signed-off-by: Fu Wei <fu.wei@linaro.org>
Tested-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
[Mark: reword commit message]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 15059c958be7..94de018c65d0 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -992,7 +992,7 @@ static int __init arch_timer_register(void) | |||
992 | case ARCH_TIMER_PHYS_NONSECURE_PPI: | 992 | case ARCH_TIMER_PHYS_NONSECURE_PPI: |
993 | err = request_percpu_irq(ppi, arch_timer_handler_phys, | 993 | err = request_percpu_irq(ppi, arch_timer_handler_phys, |
994 | "arch_timer", arch_timer_evt); | 994 | "arch_timer", arch_timer_evt); |
995 | if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) { | 995 | if (!err && arch_timer_has_nonsecure_ppi()) { |
996 | ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]; | 996 | ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]; |
997 | err = request_percpu_irq(ppi, arch_timer_handler_phys, | 997 | err = request_percpu_irq(ppi, arch_timer_handler_phys, |
998 | "arch_timer", arch_timer_evt); | 998 | "arch_timer", arch_timer_evt); |
@@ -1114,39 +1114,41 @@ static int __init arch_timer_common_init(void) | |||
1114 | return arch_timer_arch_init(); | 1114 | return arch_timer_arch_init(); |
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | static int __init arch_timer_init(void) | 1117 | /** |
1118 | * arch_timer_select_ppi() - Select suitable PPI for the current system. | ||
1119 | * | ||
1120 | * If HYP mode is available, we know that the physical timer | ||
1121 | * has been configured to be accessible from PL1. Use it, so | ||
1122 | * that a guest can use the virtual timer instead. | ||
1123 | * | ||
1124 | * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE | ||
1125 | * accesses to CNTP_*_EL1 registers are silently redirected to | ||
1126 | * their CNTHP_*_EL2 counterparts, and use a different PPI | ||
1127 | * number. | ||
1128 | * | ||
1129 | * If no interrupt provided for virtual timer, we'll have to | ||
1130 | * stick to the physical timer. It'd better be accessible... | ||
1131 | * For arm64 we never use the secure interrupt. | ||
1132 | * | ||
1133 | * Return: a suitable PPI type for the current system. | ||
1134 | */ | ||
1135 | static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void) | ||
1118 | { | 1136 | { |
1119 | int ret; | 1137 | if (is_kernel_in_hyp_mode()) |
1120 | /* | 1138 | return ARCH_TIMER_HYP_PPI; |
1121 | * If HYP mode is available, we know that the physical timer | ||
1122 | * has been configured to be accessible from PL1. Use it, so | ||
1123 | * that a guest can use the virtual timer instead. | ||
1124 | * | ||
1125 | * If no interrupt provided for virtual timer, we'll have to | ||
1126 | * stick to the physical timer. It'd better be accessible... | ||
1127 | * | ||
1128 | * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE | ||
1129 | * accesses to CNTP_*_EL1 registers are silently redirected to | ||
1130 | * their CNTHP_*_EL2 counterparts, and use a different PPI | ||
1131 | * number. | ||
1132 | */ | ||
1133 | if (is_hyp_mode_available() || !arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) { | ||
1134 | bool has_ppi; | ||
1135 | 1139 | ||
1136 | if (is_kernel_in_hyp_mode()) { | 1140 | if (!is_hyp_mode_available() && arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) |
1137 | arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI; | 1141 | return ARCH_TIMER_VIRT_PPI; |
1138 | has_ppi = !!arch_timer_ppi[ARCH_TIMER_HYP_PPI]; | ||
1139 | } else { | ||
1140 | arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI; | ||
1141 | has_ppi = (!!arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] || | ||
1142 | !!arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]); | ||
1143 | } | ||
1144 | 1142 | ||
1145 | if (!has_ppi) { | 1143 | if (IS_ENABLED(CONFIG_ARM64)) |
1146 | pr_warn("No interrupt available, giving up\n"); | 1144 | return ARCH_TIMER_PHYS_NONSECURE_PPI; |
1147 | return -EINVAL; | 1145 | |
1148 | } | 1146 | return ARCH_TIMER_PHYS_SECURE_PPI; |
1149 | } | 1147 | } |
1148 | |||
1149 | static int __init arch_timer_init(void) | ||
1150 | { | ||
1151 | int ret; | ||
1150 | 1152 | ||
1151 | ret = arch_timer_register(); | 1153 | ret = arch_timer_register(); |
1152 | if (ret) | 1154 | if (ret) |
@@ -1188,6 +1190,13 @@ static int __init arch_timer_of_init(struct device_node *np) | |||
1188 | if (IS_ENABLED(CONFIG_ARM) && | 1190 | if (IS_ENABLED(CONFIG_ARM) && |
1189 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) | 1191 | of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) |
1190 | arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI; | 1192 | arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI; |
1193 | else | ||
1194 | arch_timer_uses_ppi = arch_timer_select_ppi(); | ||
1195 | |||
1196 | if (!arch_timer_ppi[arch_timer_uses_ppi]) { | ||
1197 | pr_err("No interrupt available, giving up\n"); | ||
1198 | return -EINVAL; | ||
1199 | } | ||
1191 | 1200 | ||
1192 | /* On some systems, the counter stops ticking when in suspend. */ | 1201 | /* On some systems, the counter stops ticking when in suspend. */ |
1193 | arch_counter_suspend_stop = of_property_read_bool(np, | 1202 | arch_counter_suspend_stop = of_property_read_bool(np, |
@@ -1333,6 +1342,12 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) | |||
1333 | /* Get the frequency from CNTFRQ */ | 1342 | /* Get the frequency from CNTFRQ */ |
1334 | arch_timer_detect_rate(NULL, NULL); | 1343 | arch_timer_detect_rate(NULL, NULL); |
1335 | 1344 | ||
1345 | arch_timer_uses_ppi = arch_timer_select_ppi(); | ||
1346 | if (!arch_timer_ppi[arch_timer_uses_ppi]) { | ||
1347 | pr_err("No interrupt available, giving up\n"); | ||
1348 | return -EINVAL; | ||
1349 | } | ||
1350 | |||
1336 | /* Always-on capability */ | 1351 | /* Always-on capability */ |
1337 | arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON); | 1352 | arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON); |
1338 | 1353 | ||