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 | |
| 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')
| -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 | ||
