[PATCH v3 32/62] arm/acpi: Parse GTDT to initialize timer

shannon.zhao at linaro.org shannon.zhao at linaro.org
Tue Nov 17 01:40:31 PST 2015


From: Parth Dixit <parth.dixit at linaro.org>

Parse GTDT (Generic Timer Descriptor Table) to initialize timer. Using
the information presented by GTDT to initialize the arch timer (not
memory-mapped).

Signed-off-by: Naresh Bhat <naresh.bhat at linaro.org>
Signed-off-by: Parth Dixit <parth.dixit at linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
---
 xen/arch/arm/time.c | 73 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 62 insertions(+), 11 deletions(-)

diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index 5ded30c..adbfc2a 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -29,6 +29,7 @@
 #include <xen/time.h>
 #include <xen/sched.h>
 #include <xen/event.h>
+#include <xen/acpi.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/gic.h>
@@ -65,8 +66,45 @@ unsigned int timer_get_irq(enum timer_ppi ppi)
 
 static __initdata struct dt_device_node *timer;
 
+#ifdef CONFIG_ACPI
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+    unsigned int irq_type;
+    struct acpi_table_gtdt *gtdt;
+
+    gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+    /* Initialize all the generic timer IRQ variable from GTDT table */
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el1_flags);
+    irq_set_type(gtdt->non_secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_NONSECURE_PPI] = gtdt->non_secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->secure_el1_flags);
+    irq_set_type(gtdt->secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_SECURE_PPI] = gtdt->secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->virtual_timer_flags);
+    irq_set_type(gtdt->virtual_timer_interrupt, irq_type);
+    timer_irq[TIMER_VIRT_PPI] = gtdt->virtual_timer_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el2_flags);
+    irq_set_type(gtdt->non_secure_el2_interrupt, irq_type);
+    timer_irq[TIMER_HYP_PPI] = gtdt->non_secure_el2_interrupt;
+
+    return 0;
+}
+
+void __init acpi_preinit_xen_time(void)
+{
+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#else
+static inline void acpi_preinit_xen_time(void) { }
+#endif
+
 /* Set up the timer on the boot CPU (early init function) */
-void __init preinit_xen_time(void)
+static void __init dt_preinit_xen_time(void)
 {
     static const struct dt_device_match timer_ids[] __initconst =
     {
@@ -74,7 +112,6 @@ void __init preinit_xen_time(void)
         { /* sentinel */ },
     };
     int res;
-    u32 rate;
 
     timer = dt_find_matching_node(NULL, timer_ids);
     if ( !timer )
@@ -86,8 +123,19 @@ void __init preinit_xen_time(void)
     if ( res )
         panic("Timer: Cannot initialize platform timer");
 
-    res = dt_property_read_u32(timer, "clock-frequency", &rate);
-    if ( res )
+}
+
+void __init preinit_xen_time(void)
+{
+    u32 rate;
+
+    /* Initialize all the generic timers presented in GTDT */
+    if ( acpi_disabled )
+        dt_preinit_xen_time();
+    else
+        acpi_preinit_xen_time();
+
+    if( acpi_disabled && dt_property_read_u32(timer, "clock-frequency", &rate) )
     {
         cpu_khz = rate / 1000;
         timer_dt_clock_frequency = rate;
@@ -104,14 +152,17 @@ int __init init_xen_time(void)
     int res;
     unsigned int i;
 
-    /* Retrieve all IRQs for the timer */
-    for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+    if( acpi_disabled )
     {
-        res = platform_get_irq(timer, i);
-
-        if ( res < 0 )
-            panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
-        timer_irq[i] = res;
+        /* Retrieve all IRQs for the timer */
+        for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+        {
+            res = platform_get_irq(timer, i);
+
+            if ( res < 0 )
+                panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
+            timer_irq[i] = res;
+        }
     }
 
     /* Check that this CPU supports the Generic Timer interface */
-- 
2.1.0




More information about the linux-arm-kernel mailing list