@@ -287,7 +287,12 @@ static struct property *dup_and_fixup_symbol_prop(
* @target may be either in the live devicetree or in a new subtree that
* is contained in the changeset.
*
- * Some special properties are not updated (no error returned).
+ * Some special properties are not added or updated (no error returned):
+ * "name", "phandle", "linux,phandle".
+ *
+ * Properties "#address-cells" and "#size-cells" are not updated if they
+ * are already in the live tree, but if present in the live tree, the values
+ * in the overlay must match the values in the live tree.
*
* Update of property in symbols node is not allowed.
*
@@ -300,6 +305,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
{
struct property *new_prop = NULL, *prop;
int ret = 0;
+ bool check_for_non_overlay_node = false;
if (!of_prop_cmp(overlay_prop->name, "name") ||
!of_prop_cmp(overlay_prop->name, "phandle") ||
@@ -322,13 +328,39 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
if (!new_prop)
return -ENOMEM;
- if (!prop)
+ if (!prop) {
+
+ check_for_non_overlay_node = true;
ret = of_changeset_add_property(&ovcs->cset, target->np,
new_prop);
- else
+
+ } else if (!of_prop_cmp(prop->name, "#address-cells")) {
+
+ if (prop->length != 4 || new_prop->length != 4 ||
+ *(u32 *)prop->value != *(u32 *)new_prop->value)
+ pr_err("ERROR: overlay and/or live tree #address-cells invalid in node %pOF\n",
+ target->np);
+
+ } else if (!of_prop_cmp(prop->name, "#size-cells")) {
+
+ if (prop->length != 4 || new_prop->length != 4 ||
+ *(u32 *)prop->value != *(u32 *)new_prop->value)
+ pr_err("ERROR: overlay and/or live tree #size-cells invalid in node %pOF\n",
+ target->np);
+
+ } else {
+
+ check_for_non_overlay_node = true;
ret = of_changeset_update_property(&ovcs->cset, target->np,
new_prop);
+ }
+
+ if (check_for_non_overlay_node &&
+ !of_node_check_flag(target->np, OF_OVERLAY))
+ pr_err("WARNING: %s(), memory leak will occur if overlay removed. Property: %pOF/%s\n",
+ __func__, target->np, new_prop->name);
+
if (ret) {
kfree(new_prop->name);
kfree(new_prop->value);