const struct kernel_info *kinfo)
{
int res, i;
- int reg_size = dt_n_addr_cells(parent) + dt_n_size_cells(parent);
+ int reg_size = dt_child_n_addr_cells(parent) + dt_child_n_size_cells(parent);
int nr_cells = reg_size*kinfo->mem.nr_banks;
__be32 reg[nr_cells];
__be32 *cells;
DPRINT(" Bank %d: %#"PRIx64"->%#"PRIx64"\n",
i, start, start + size);
- dt_set_range(&cells, parent, start, size);
+ dt_child_set_range(&cells, parent, start, size);
}
res = fdt_property(fdt, "reg", reg, sizeof(reg));
__be32 *cells;
int res;
/* Convenience alias */
- int addrcells = dt_n_addr_cells(parent);
- int sizecells = dt_n_size_cells(parent);
+ int addrcells = dt_child_n_addr_cells(parent);
+ int sizecells = dt_child_n_size_cells(parent);
void *fdt = kinfo->fdt;
DPRINT("Create hypervisor node\n");
/* reg 0 is grant table space */
cells = ®[0];
- dt_set_range(&cells, parent, kinfo->gnttab_start, kinfo->gnttab_size);
+ dt_child_set_range(&cells, parent, kinfo->gnttab_start, kinfo->gnttab_size);
res = fdt_property(fdt, "reg", reg,
dt_cells_to_size(addrcells + sizecells));
if ( res )
dt_set_cell(cellp, dt_n_size_cells(np), size);
}
+void dt_child_set_range(__be32 **cellp, const struct dt_device_node *parent,
+ u64 address, u64 size)
+{
+ dt_set_cell(cellp, dt_child_n_addr_cells(parent), address);
+ dt_set_cell(cellp, dt_child_n_size_cells(parent), size);
+}
+
static void __init *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
unsigned long align)
{
return NULL;
}
-int dt_n_addr_cells(const struct dt_device_node *np)
+static int __dt_n_addr_cells(const struct dt_device_node *np, bool_t parent)
{
const __be32 *ip;
do {
- if ( np->parent )
+ if ( np->parent && !parent )
np = np->parent;
+ parent = false;
+
ip = dt_get_property(np, "#address-cells", NULL);
if ( ip )
return be32_to_cpup(ip);
return DT_ROOT_NODE_ADDR_CELLS_DEFAULT;
}
-int dt_n_size_cells(const struct dt_device_node *np)
+int __dt_n_size_cells(const struct dt_device_node *np, bool_t parent)
{
const __be32 *ip;
do {
- if ( np->parent )
+ if ( np->parent && !parent )
np = np->parent;
+ parent = false;
+
ip = dt_get_property(np, "#size-cells", NULL);
if ( ip )
return be32_to_cpup(ip);
return DT_ROOT_NODE_SIZE_CELLS_DEFAULT;
}
+int dt_n_addr_cells(const struct dt_device_node *np)
+{
+ return __dt_n_addr_cells(np, false);
+}
+
+int dt_n_size_cells(const struct dt_device_node *np)
+{
+ return __dt_n_size_cells(np, false);
+}
+
+int dt_child_n_addr_cells(const struct dt_device_node *parent)
+{
+ return __dt_n_addr_cells(parent, true);
+}
+
+int dt_child_n_size_cells(const struct dt_device_node *parent)
+{
+ return __dt_n_size_cells(parent, true);
+}
+
/*
* These are defined in Linux where much of this code comes from, but
* are currently unused outside this file in the context of Xen.
*/
int dt_n_addr_cells(const struct dt_device_node *np);
+/**
+ * dt_child_n_size_cells - Helper to retrieve the number of cell for the size
+ * @parent: parent of the child to get the value
+ *
+ * This function retrieves for a given device-tree node the number of
+ * cell for the size field of there child
+ */
+int dt_child_n_size_cells(const struct dt_device_node *parent);
+
+/**
+ * dt_child_n_addr_cells - Helper to retrieve the number of cell for the
+ * address
+ * @parent: parent of the child to get the value
+ *
+ * This function retrieves for a given device-tree node the number of
+ * cell for the address field of there child
+ */
+int dt_child_n_addr_cells(const struct dt_device_node *parent);
+
/**
* dt_device_is_available - Check if a device is available for use
*
void dt_set_range(__be32 **cellp, const struct dt_device_node *np,
u64 address, u64 size);
+/**
+ * dt_child_set_range - Write range into a series of cells
+ *
+ * @cellp: Pointer to cells
+ * @parent: Parent node which contains the encode for the address and the size
+ * @address: Start of range
+ * @size: Size of the range
+ *
+ * Write a range into a series of cells and update cellp to point to the
+ * cell just after.
+ */
+void dt_child_set_range(__be32 **cellp, const struct dt_device_node *parent,
+ u64 address, u64 size);
+
/**
* dt_get_range - Read a range (address/size) from a series of cells
*