diff --git a/core/device.c b/core/device.c
index 0118d485f..f48a80159 100644
--- a/core/device.c
+++ b/core/device.c
@@ -593,11 +593,18 @@ u32 dt_property_get_cell(const struct dt_property *prop, u32 index)
 	return fdt32_to_cpu(((const u32 *)prop->prop)[index]);
 }
 
+u64 dt_property_get_u64(const struct dt_property *prop, u32 index)
+{
+	assert(prop->len >= (index+1)*sizeof(u64));
+	/* Always aligned, so this works. */
+	return fdt64_to_cpu(((const fdt64_t *)prop->prop)[index]);
+}
+
 void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val)
 {
 	assert(prop->len >= (index+1)*sizeof(u32));
 	/* Always aligned, so this works. */
-	((u32 *)prop->prop)[index] = cpu_to_fdt32(val);
+	((fdt32_t *)prop->prop)[index] = cpu_to_fdt32(val);
 }
 
 /* First child of this node. */
diff --git a/core/pci.c b/core/pci.c
index e497fd50c..f23ba1873 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -1524,16 +1524,8 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
 	char name[MAX_NAME];
 	char compat[MAX_NAME];
 	uint32_t rev_class;
-	__be32 reg[5];
 	uint8_t intpin;
 	bool is_pcie;
-	const __be32 ranges_direct[] = {
-				/* 64-bit direct mapping. We know the bridges
-				 * don't cover the entire address space so
-				 * use 0xf00... as a good compromise. */
-				cpu_to_be32(0x02000000), 0x0, 0x0,
-				cpu_to_be32(0x02000000), 0x0, 0x0,
-				cpu_to_be32(0xf0000000), 0x0};
 
 	pci_cfg_read32(phb, pd->bdfn, PCI_CFG_REV_ID, &rev_class);
 	pci_cfg_read8(phb, pd->bdfn, PCI_CFG_INT_PIN, &intpin);
@@ -1609,9 +1601,7 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
 	 * entry in the "reg" property. That's enough for Linux and we might
 	 * even want to make this legit in future ePAPR
 	 */
-	reg[0] = cpu_to_be32(pd->bdfn << 8);
-	reg[1] = reg[2] = reg[3] = reg[4] = 0;
-	dt_add_property(np, "reg", reg, sizeof(reg));
+	dt_add_property_cells(np, "reg", pd->bdfn << 8, 0, 0, 0, 0);
 
 	/* Print summary info about the device */
 	pci_print_summary_line(phb, pd, np, rev_class, cname);
@@ -1646,7 +1636,13 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
 	 * (ie. an empty ranges property).
 	 * Instead add a ranges property that explicitly translates 1:1.
 	 */
-	dt_add_property(np, "ranges", ranges_direct, sizeof(ranges_direct));
+	dt_add_property_cells(np, "ranges",
+				/* 64-bit direct mapping. We know the bridges
+				 * don't cover the entire address space so
+				 * use 0xf00... as a good compromise. */
+				0x02000000, 0x0, 0x0,
+				0x02000000, 0x0, 0x0,
+				0xf0000000, 0x0);
 }
 
 void __noinline pci_add_device_nodes(struct phb *phb,
diff --git a/hdata/iohub.c b/hdata/iohub.c
index 6647e6aac..35f4a74c9 100644
--- a/hdata/iohub.c
+++ b/hdata/iohub.c
@@ -95,7 +95,6 @@ static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
 				   unsigned int spci_xscom)
 {
 	struct dt_node *pbcq;
-	uint32_t reg[6];
 	unsigned int hdif_vers;
 
 	/* Get HDIF version */
@@ -109,13 +108,10 @@ static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
 	/* "reg" property contains in order the PE, PCI and SPCI XSCOM
 	 * addresses
 	 */
-	reg[0] = cpu_to_be32(pe_xscom);
-	reg[1] = cpu_to_be32(0x20);
-	reg[2] = cpu_to_be32(pci_xscom);
-	reg[3] = cpu_to_be32(0x05);
-	reg[4] = cpu_to_be32(spci_xscom);
-	reg[5] = cpu_to_be32(0x15);
-	dt_add_property(pbcq, "reg", reg, sizeof(reg));
+	dt_add_property_cells(pbcq, "reg",
+				pe_xscom, 0x20,
+				pci_xscom, 0x05,
+				spci_xscom, 0x15);
 
 	/* A couple more things ... */
 	dt_add_property_strings(pbcq, "compatible", "ibm,power8-pbcq");
@@ -202,7 +198,6 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub,
 				   int phb_base)
 {
 	struct dt_node *pbcq;
-	uint32_t reg[4];
 	uint8_t active_phb_mask = hub->fab_br0_pdt;
 	uint32_t pe_xscom  = 0x4010c00 + (pec_index * 0x0000400);
 	uint32_t pci_xscom = 0xd010800 + (pec_index * 0x1000000);
@@ -214,11 +209,9 @@ static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub,
 		return NULL;
 
 	/* "reg" property contains (in order) the PE and PCI XSCOM addresses */
-	reg[0] = cpu_to_be32(pe_xscom);
-	reg[1] = cpu_to_be32(0x100);
-	reg[2] = cpu_to_be32(pci_xscom);
-	reg[3] = cpu_to_be32(0x200);
-	dt_add_property(pbcq, "reg", reg, sizeof(reg));
+	dt_add_property_cells(pbcq, "reg",
+				pe_xscom, 0x100,
+				pci_xscom, 0x200);
 
 	/* The hubs themselves go under the stacks */
 	dt_add_property_strings(pbcq, "compatible", "ibm,power9-pbcq");
diff --git a/hdata/memory.c b/hdata/memory.c
index 9e5e99b9c..7839dea3f 100644
--- a/hdata/memory.c
+++ b/hdata/memory.c
@@ -77,24 +77,21 @@ static void append_chip_id(struct dt_node *mem, u32 id)
 {
 	struct dt_property *prop;
 	size_t len, i;
-	be32 *p;
 
 	prop = __dt_find_property(mem, "ibm,chip-id");
 	if (!prop)
 		return;
 	len = prop->len >> 2;
-	p = (be32*)prop->prop;
 
 	/* Check if it exists already */
 	for (i = 0; i < len; i++) {
-		if (be32_to_cpu(p[i]) == id)
+		if (dt_property_get_cell(prop, i) == id)
 			return;
 	}
 
 	/* Add it to the list */
 	dt_resize_property(&prop, (len + 1) << 2);
-	p = (be32 *)prop->prop;
-	p[len] = cpu_to_be32(id);
+	dt_property_set_cell(prop, len, id);
 }
 
 static void update_status(struct dt_node *mem, uint32_t status)
diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index 1112fb74b..7592ee07b 100644
--- a/hw/fsp/fsp.c
+++ b/hw/fsp/fsp.c
@@ -1912,7 +1912,7 @@ static void fsp_init_links(struct dt_node *fsp_node)
 		u64 reg;
 		u32 link;
 
-		link = be32_to_cpu(((const __be32 *)linksprop->prop)[i]);
+		link = dt_property_get_cell(linksprop, i);
 		fiop = &fsp->iopath[i];
 		fiop->psi = psi_find_link(link);
 		if (fiop->psi == NULL) {
diff --git a/hw/phb4.c b/hw/phb4.c
index 9f7bcd4ca..ed7f4e5c4 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -5544,11 +5544,11 @@ static bool phb4_calculate_windows(struct phb4 *p)
 				   "ibm,mmio-windows", -1);
 	assert(prop->len >= (2 * sizeof(uint64_t)));
 
-	p->mm0_base = be64_to_cpu(((__be64 *)prop->prop)[0]);
-	p->mm0_size = be64_to_cpu(((__be64 *)prop->prop)[1]);
+	p->mm0_base = dt_property_get_u64(prop, 0);
+	p->mm0_size = dt_property_get_u64(prop, 1);
 	if (prop->len > 16) {
-		p->mm1_base = be64_to_cpu(((__be64 *)prop->prop)[2]);
-		p->mm1_size = be64_to_cpu(((__be64 *)prop->prop)[3]);
+		p->mm1_base = dt_property_get_u64(prop, 2);
+		p->mm1_size = dt_property_get_u64(prop, 3);
 	}
 
 	/* Sort them so that 0 is big and 1 is small */
@@ -5660,11 +5660,11 @@ static void phb4_create(struct dt_node *np)
 
 	/* Get the various XSCOM register bases from the device-tree */
 	prop = dt_require_property(np, "ibm,xscom-bases", 5 * sizeof(uint32_t));
-	p->pe_xscom = be32_to_cpu(((__be32 *)prop->prop)[0]);
-	p->pe_stk_xscom = be32_to_cpu(((__be32 *)prop->prop)[1]);
-	p->pci_xscom = be32_to_cpu(((__be32 *)prop->prop)[2]);
-	p->pci_stk_xscom = be32_to_cpu(((__be32 *)prop->prop)[3]);
-	p->etu_xscom = be32_to_cpu(((__be32 *)prop->prop)[4]);
+	p->pe_xscom = dt_property_get_cell(prop, 0);
+	p->pe_stk_xscom = dt_property_get_cell(prop, 1);
+	p->pci_xscom = dt_property_get_cell(prop, 2);
+	p->pci_stk_xscom = dt_property_get_cell(prop, 3);
+	p->etu_xscom = dt_property_get_cell(prop, 4);
 
 	/*
 	 * We skip the initial PERST assertion requested by the generic code
@@ -5825,7 +5825,6 @@ static void phb4_probe_stack(struct dt_node *stk_node, uint32_t pec_index,
 	uint64_t val, phb_bar = 0, irq_bar = 0, bar_en;
 	uint64_t mmio0_bar = 0, mmio0_bmask, mmio0_sz;
 	uint64_t mmio1_bar = 0, mmio1_bmask, mmio1_sz;
-	uint64_t reg[4];
 	void *foo;
 	__be64 mmio_win[4];
 	unsigned int mmio_win_sz;
@@ -5923,18 +5922,15 @@ static void phb4_probe_stack(struct dt_node *stk_node, uint32_t pec_index,
 	prlog_once(PR_DEBUG, "Version reg: 0x%016llx\n", in_be64(foo));
 
 	/* Create PHB node */
-	reg[0] = cpu_to_be64(phb_bar);
-	reg[1] = cpu_to_be64(0x1000);
-	reg[2] = cpu_to_be64(irq_bar);
-	reg[3] = cpu_to_be64(0x10000000);
-
 	np = dt_new_addr(dt_root, "pciex", phb_bar);
 	if (!np)
 		return;
 
 	dt_add_property_strings(np, "compatible", "ibm,power9-pciex", "ibm,ioda3-phb");
 	dt_add_property_strings(np, "device_type", "pciex");
-	dt_add_property(np, "reg", reg, sizeof(reg));
+	dt_add_property_u64s(np, "reg",
+				phb_bar, 0x1000,
+				irq_bar, 0x10000000);
 
 	/* Everything else is handled later by skiboot, we just
 	 * stick a few hints here
diff --git a/include/device.h b/include/device.h
index 25325ec07..4f7a0983f 100644
--- a/include/device.h
+++ b/include/device.h
@@ -130,6 +130,7 @@ void dt_resize_property(struct dt_property **prop, size_t len);
 
 void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val);
 u32 dt_property_get_cell(const struct dt_property *prop, u32 index);
+u64 dt_property_get_u64(const struct dt_property *prop, u32 index);
 
 /* First child of this node. */
 struct dt_node *dt_first(const struct dt_node *root);
