Commit 259092a3 authored by Grant Likely's avatar Grant Likely

of: Reorder device tree changes and notifiers

Currently, devicetree reconfig notifiers get emitted before the change
is applied to the tree, but that behaviour is problematic if the
receiver wants the determine the new state of the tree. The current
users don't care, but the changeset code to follow will be making
multiple changes at once. Reorder notifiers to get emitted after the
change has been applied to the tree so that callbacks see the new tree
state.

At the same time, fixup the existing callbacks to expect the new order.
There are a few callbacks that compare the old and new values of a
changed property. Put both property pointers into the of_prop_reconfig
structure.

The current notifiers also allow the notifier callback to fail and
cancel the change to the tree, but that feature isn't actually used.
It really isn't valid to ignore a tree modification provided by firmware
anyway, so remove the ability to cancel a change to the tree.
Signed-off-by: default avatarGrant Likely <grant.likely@linaro.org>
Cc: Nathan Fontenot <nfont@austin.ibm.com>
parent a25095d4
...@@ -194,7 +194,7 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) ...@@ -194,7 +194,7 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
if (!memblock_size) if (!memblock_size)
return -EINVAL; return -EINVAL;
p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL); p = (u32 *) pr->old_prop->value;
if (!p) if (!p)
return -EINVAL; return -EINVAL;
......
...@@ -936,28 +936,14 @@ static int nx842_OF_upd(struct property *new_prop) ...@@ -936,28 +936,14 @@ static int nx842_OF_upd(struct property *new_prop)
goto error_out; goto error_out;
} }
/* Set ptr to new property if provided */
if (new_prop) {
/* Single property */
if (!strncmp(new_prop->name, "status", new_prop->length)) {
status = new_prop;
} else if (!strncmp(new_prop->name, "ibm,max-sg-len",
new_prop->length)) {
maxsglen = new_prop;
} else if (!strncmp(new_prop->name, "ibm,max-sync-cop",
new_prop->length)) {
maxsyncop = new_prop;
} else {
/* /*
* Skip the update, the property being updated * If this is a property update, there are only certain properties that
* has no impact. * we care about. Bail if it isn't in the below list
*/ */
if (new_prop && (strncmp(new_prop->name, "status", new_prop->length) ||
strncmp(new_prop->name, "ibm,max-sg-len", new_prop->length) ||
strncmp(new_prop->name, "ibm,max-sync-cop", new_prop->length)))
goto out; goto out;
}
}
/* Perform property updates */ /* Perform property updates */
ret = nx842_OF_upd_status(new_devdata, status); ret = nx842_OF_upd_status(new_devdata, status);
......
...@@ -1674,10 +1674,6 @@ int of_add_property(struct device_node *np, struct property *prop) ...@@ -1674,10 +1674,6 @@ int of_add_property(struct device_node *np, struct property *prop)
unsigned long flags; unsigned long flags;
int rc; int rc;
rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
if (rc)
return rc;
mutex_lock(&of_mutex); mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
...@@ -1689,6 +1685,9 @@ int of_add_property(struct device_node *np, struct property *prop) ...@@ -1689,6 +1685,9 @@ int of_add_property(struct device_node *np, struct property *prop)
mutex_unlock(&of_mutex); mutex_unlock(&of_mutex);
if (!rc)
of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
return rc; return rc;
} }
...@@ -1731,10 +1730,6 @@ int of_remove_property(struct device_node *np, struct property *prop) ...@@ -1731,10 +1730,6 @@ int of_remove_property(struct device_node *np, struct property *prop)
unsigned long flags; unsigned long flags;
int rc; int rc;
rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
if (rc)
return rc;
mutex_lock(&of_mutex); mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
...@@ -1746,6 +1741,9 @@ int of_remove_property(struct device_node *np, struct property *prop) ...@@ -1746,6 +1741,9 @@ int of_remove_property(struct device_node *np, struct property *prop)
mutex_unlock(&of_mutex); mutex_unlock(&of_mutex);
if (!rc)
of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
return rc; return rc;
} }
...@@ -1805,10 +1803,6 @@ int of_update_property(struct device_node *np, struct property *newprop) ...@@ -1805,10 +1803,6 @@ int of_update_property(struct device_node *np, struct property *newprop)
if (!newprop->name) if (!newprop->name)
return -EINVAL; return -EINVAL;
rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
if (rc)
return rc;
mutex_lock(&of_mutex); mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
...@@ -1820,6 +1814,9 @@ int of_update_property(struct device_node *np, struct property *newprop) ...@@ -1820,6 +1814,9 @@ int of_update_property(struct device_node *np, struct property *newprop)
mutex_unlock(&of_mutex); mutex_unlock(&of_mutex);
if (!rc)
of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
return rc; return rc;
} }
......
...@@ -83,7 +83,7 @@ int of_reconfig_notify(unsigned long action, void *p) ...@@ -83,7 +83,7 @@ int of_reconfig_notify(unsigned long action, void *p)
} }
int of_property_notify(int action, struct device_node *np, int of_property_notify(int action, struct device_node *np,
struct property *prop) struct property *prop, struct property *oldprop)
{ {
struct of_prop_reconfig pr; struct of_prop_reconfig pr;
...@@ -93,6 +93,7 @@ int of_property_notify(int action, struct device_node *np, ...@@ -93,6 +93,7 @@ int of_property_notify(int action, struct device_node *np,
pr.dn = np; pr.dn = np;
pr.prop = prop; pr.prop = prop;
pr.old_prop = oldprop;
return of_reconfig_notify(action, &pr); return of_reconfig_notify(action, &pr);
} }
...@@ -125,11 +126,6 @@ void __of_attach_node(struct device_node *np) ...@@ -125,11 +126,6 @@ void __of_attach_node(struct device_node *np)
int of_attach_node(struct device_node *np) int of_attach_node(struct device_node *np)
{ {
unsigned long flags; unsigned long flags;
int rc;
rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
if (rc)
return rc;
mutex_lock(&of_mutex); mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
...@@ -138,6 +134,9 @@ int of_attach_node(struct device_node *np) ...@@ -138,6 +134,9 @@ int of_attach_node(struct device_node *np)
__of_attach_node_sysfs(np); __of_attach_node_sysfs(np);
mutex_unlock(&of_mutex); mutex_unlock(&of_mutex);
of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
return 0; return 0;
} }
...@@ -188,10 +187,6 @@ int of_detach_node(struct device_node *np) ...@@ -188,10 +187,6 @@ int of_detach_node(struct device_node *np)
unsigned long flags; unsigned long flags;
int rc = 0; int rc = 0;
rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
if (rc)
return rc;
mutex_lock(&of_mutex); mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
__of_detach_node(np); __of_detach_node(np);
...@@ -199,6 +194,9 @@ int of_detach_node(struct device_node *np) ...@@ -199,6 +194,9 @@ int of_detach_node(struct device_node *np)
__of_detach_node_sysfs(np); __of_detach_node_sysfs(np);
mutex_unlock(&of_mutex); mutex_unlock(&of_mutex);
of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
return rc; return rc;
} }
......
...@@ -43,11 +43,11 @@ static inline struct device_node *kobj_to_device_node(struct kobject *kobj) ...@@ -43,11 +43,11 @@ static inline struct device_node *kobj_to_device_node(struct kobject *kobj)
#if defined(CONFIG_OF_DYNAMIC) #if defined(CONFIG_OF_DYNAMIC)
extern int of_property_notify(int action, struct device_node *np, extern int of_property_notify(int action, struct device_node *np,
struct property *prop); struct property *prop, struct property *old_prop);
extern void of_node_release(struct kobject *kobj); extern void of_node_release(struct kobject *kobj);
#else /* CONFIG_OF_DYNAMIC */ #else /* CONFIG_OF_DYNAMIC */
static inline int of_property_notify(int action, struct device_node *np, static inline int of_property_notify(int action, struct device_node *np,
struct property *prop) struct property *prop, struct property *old_prop)
{ {
return 0; return 0;
} }
......
...@@ -321,6 +321,7 @@ extern int of_update_property(struct device_node *np, struct property *newprop); ...@@ -321,6 +321,7 @@ extern int of_update_property(struct device_node *np, struct property *newprop);
struct of_prop_reconfig { struct of_prop_reconfig {
struct device_node *dn; struct device_node *dn;
struct property *prop; struct property *prop;
struct property *old_prop;
}; };
extern int of_reconfig_notifier_register(struct notifier_block *); extern int of_reconfig_notifier_register(struct notifier_block *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment