summaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@kernel.org>2026-06-13 16:24:29 +0200
committerThomas Gleixner <tglx@kernel.org>2026-06-13 16:24:29 +0200
commitc66494c79ede1af529dbf67f9ed6fdbf42e05ef3 (patch)
treeef203fa15e12e9530bf76f576b4cfd8c1c5d6dba /drivers/acpi
parent3eb4923e68511741f3eb3fab55ed1e8ded9e4da8 (diff)
parenta9ac745bc320cbdc2ed3c851eb78f91f22ff975b (diff)
Merge tag 'timers-v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/daniel.lezcano/linux into timers/clocksource
Pull clocksource/driver updates from Daniel Lezcano: - Remove the sifive,fine-ctr-bits property bindings because it is a redundant information (Nick Hu) - Remove the TCIU8 interrupt bindings on Renesas because it should not be described as the documentation marked reserved and fix the conditional reset line for the RZ/{T2H,N2H} (Cosmin Tanislav) - Add the StarFive JHB100 clint DT bindings compatible string (Ley Foon Tan) - Extend schema condition for interrupts to cover D1 compatible variant an add the D1 hstimer support (Michal Piekos) - Update the ARM architected timer support to handle the ACPI GTDT v3 format and the EL2 virtual timer, enabling Linux to use the most appropriate timer when running with VHE, while also fixing several Device Trees to accurately reflect the underlying hardware (Marc Zyngier) - Cleanup and add the clocksource and the clockevent in the TI DM timer (Markus Schneider-Pargmann) - Add the multiple watchdogs support in the tegra186 and tegra234. Dedicate one as a kernel watchdog (Kartik Rajput) - Add the NXP clocksource selection for the scheduler in the Kconfig (Enric Balletbo i Serra) Link: https://lore.kernel.org/all/1e55e8d6-8024-4f17-8620-ab3385465d76@oss.qualcomm.com
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/arm64/gtdt.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index ffc867bac2d6..00158c8aa6d9 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -34,14 +34,33 @@ struct acpi_gtdt_descriptor {
void *platform_timer;
};
+struct gtdt_v3 {
+ struct acpi_table_gtdt gtdt_v2;
+ struct acpi_gtdt_el2 el2_vtimer;
+};
+
static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
+static __init struct acpi_gtdt_el2 *gtdt_to_el2_vtimer(struct acpi_table_gtdt *gtdt)
+{
+ if (gtdt->header.revision < 3)
+ return NULL;
+
+ return &container_of(gtdt, struct gtdt_v3, gtdt_v2)->el2_vtimer;
+}
+
static __init bool platform_timer_valid(void *platform_timer)
{
struct acpi_gtdt_header *gh = platform_timer;
+ void *platform_timer_begin;
+
+ if (acpi_gtdt_desc.gtdt->header.revision >= 3)
+ platform_timer_begin = container_of(acpi_gtdt_desc.gtdt, struct gtdt_v3, gtdt_v2) + 1;
+ else
+ platform_timer_begin = acpi_gtdt_desc.gtdt + 1;
- return (platform_timer >= (void *)(acpi_gtdt_desc.gtdt + 1) &&
- platform_timer < acpi_gtdt_desc.gtdt_end &&
+ return (platform_timer >= platform_timer_begin &&
+ platform_timer + sizeof(*gh) <= acpi_gtdt_desc.gtdt_end &&
gh->length != 0 &&
platform_timer + gh->length <= acpi_gtdt_desc.gtdt_end);
}
@@ -101,6 +120,7 @@ static int __init map_gt_gsi(u32 interrupt, u32 flags)
int __init acpi_gtdt_map_ppi(int type)
{
struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;
+ struct acpi_gtdt_el2 *el2_vtimer = gtdt_to_el2_vtimer(gtdt);
switch (type) {
case ARCH_TIMER_PHYS_NONSECURE_PPI:
@@ -113,6 +133,12 @@ int __init acpi_gtdt_map_ppi(int type)
case ARCH_TIMER_HYP_PPI:
return map_gt_gsi(gtdt->non_secure_el2_interrupt,
gtdt->non_secure_el2_flags);
+ case ARCH_TIMER_HYP_VIRT_PPI:
+ if (el2_vtimer && el2_vtimer->virtual_el2_timer_gsiv)
+ return map_gt_gsi(el2_vtimer->virtual_el2_timer_gsiv,
+ el2_vtimer->virtual_el2_timer_flags);
+
+ return 0;
default:
pr_err("Failed to map timer interrupt: invalid type.\n");
}
@@ -130,6 +156,7 @@ int __init acpi_gtdt_map_ppi(int type)
bool __init acpi_gtdt_c3stop(int type)
{
struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;
+ struct acpi_gtdt_el2 *el2_vtimer = gtdt_to_el2_vtimer(gtdt);
switch (type) {
case ARCH_TIMER_PHYS_NONSECURE_PPI:
@@ -141,6 +168,10 @@ bool __init acpi_gtdt_c3stop(int type)
case ARCH_TIMER_HYP_PPI:
return !(gtdt->non_secure_el2_flags & ACPI_GTDT_ALWAYS_ON);
+ case ARCH_TIMER_HYP_VIRT_PPI:
+ return el2_vtimer && el2_vtimer->virtual_el2_timer_gsiv &&
+ !(el2_vtimer->virtual_el2_timer_flags & ACPI_GTDT_ALWAYS_ON);
+
default:
pr_err("Failed to get c3stop info: invalid type.\n");
}
@@ -166,6 +197,13 @@ int __init acpi_gtdt_init(struct acpi_table_header *table,
u32 cnt = 0;
gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+ if ((gtdt->header.revision >= 3 && gtdt->header.length < sizeof(struct gtdt_v3)) ||
+ (gtdt->header.revision == 2 && gtdt->header.length < sizeof(*gtdt))) {
+ pr_err(FW_BUG "GTDT with invalid size %d\n", gtdt->header.length);
+ return -EINVAL;
+ }
+
acpi_gtdt_desc.gtdt = gtdt;
acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
acpi_gtdt_desc.platform_timer = NULL;