[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC PATCH v4 07/11] arch/arm: create device tree nodes for hwdom cpufreq cpu driver



This patch copies all cpu@xxxxxx@N nodes (from input
device tree) with properties to /hypervisor/pcpus
node (device tree for hwdom). Thus we can give all
information about all physical CPUs in the pcpus node.
Driver in hwdom should parse /hypervisor/pcpus path
instead of the /cpus path in the device tree.

Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@xxxxxxxxxxxxxxx>
---
 xen/arch/arm/domain_build.c | 78 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 70 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 2db0236..87e05c7 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -326,8 +326,64 @@ static int make_memory_node(const struct domain *d,
     return res;
 }
 
-static int make_hypervisor_node(struct domain *d,
-                                void *fdt, const struct dt_device_node *parent)
+#ifdef HAS_HWDOM_CPUFREQ
+static int fdt_copy_phys_cpus_nodes(struct domain *d, struct kernel_info 
*kinfo)
+{
+    int res;
+    const struct dt_device_node *cpus = dt_find_node_by_path("/cpus");
+    const struct dt_device_node *npcpu;
+    char *node_name;
+
+    if ( !cpus )
+    {
+        dprintk(XENLOG_ERR, "Missing /cpus node in the device tree?\n");
+        return -ENOENT;
+    }
+
+    /*
+     * create pcpus node and copy to it
+     * original cpu@xxxxxx@N nodes with its properties.
+     * This is needed for the cpufreq cpu driver in Dom0
+     */
+    DPRINT("Create pcpus node\n");
+
+    res = fdt_begin_node(kinfo->fdt, "pcpus");
+    if ( res )
+        return res;
+
+    dt_for_each_child_node( cpus, npcpu )
+    {
+        if ( dt_device_type_is_equal(npcpu, "cpu") )
+        {
+            node_name = strrchr(dt_node_full_name(npcpu), '/');
+            ASSERT(node_name);
+
+            node_name++;
+            ASSERT(*node_name);
+
+            DPRINT("Copy %s node to the pcpus\n", node_name);
+
+            res = fdt_begin_node(kinfo->fdt, node_name);
+            if ( res )
+                return res;
+
+            res = write_properties(d, kinfo, npcpu);
+            if ( res )
+                return res;
+
+            res = fdt_end_node(kinfo->fdt);
+            if ( res )
+                return res;
+        }
+    }
+
+    res = fdt_end_node(kinfo->fdt);
+    return res;
+}
+#endif /* HAS_HWDOM_CPUFREQ */
+
+static int make_hypervisor_node(struct domain *d, struct kernel_info *kinfo,
+                                const struct dt_device_node *parent)
 {
     const char compat[] =
         "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
@@ -351,12 +407,12 @@ static int make_hypervisor_node(struct domain *d,
         panic("Cannot cope with this size");
 
     /* See linux Documentation/devicetree/bindings/arm/xen.txt */
-    res = fdt_begin_node(fdt, "hypervisor");
+    res = fdt_begin_node(kinfo->fdt, "hypervisor");
     if ( res )
         return res;
 
     /* Cannot use fdt_property_string due to embedded nulls */
-    res = fdt_property(fdt, "compatible", compat, sizeof(compat));
+    res = fdt_property(kinfo->fdt, "compatible", compat, sizeof(compat));
     if ( res )
         return res;
 
@@ -366,7 +422,7 @@ static int make_hypervisor_node(struct domain *d,
     /* reg 0 is grant table space */
     cells = &reg[0];
     dt_set_range(&cells, parent, gnttab_start, gnttab_size);
-    res = fdt_property(fdt, "reg", reg,
+    res = fdt_property(kinfo->fdt, "reg", reg,
                        dt_cells_to_size(addrcells + sizecells));
     if ( res )
         return res;
@@ -382,11 +438,17 @@ static int make_hypervisor_node(struct domain *d,
     set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
                    DT_IRQ_TYPE_LEVEL_LOW);
 
-    res = fdt_property_interrupts(fdt, &intr, 1);
+    res = fdt_property_interrupts(kinfo->fdt, &intr, 1);
     if ( res )
         return res;
 
-    res = fdt_end_node(fdt);
+    #ifdef HAS_HWDOM_CPUFREQ
+    res = fdt_copy_phys_cpus_nodes(d, kinfo);
+    if ( res )
+        return res;
+    #endif
+
+    res = fdt_end_node(kinfo->fdt);
 
     return res;
 }
@@ -863,7 +925,7 @@ static int handle_node(struct domain *d, struct kernel_info 
*kinfo,
 
     if ( node == dt_host )
     {
-        res = make_hypervisor_node(d, kinfo->fdt, node);
+        res = make_hypervisor_node(d, kinfo, node);
         if ( res )
             return res;
 
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.