aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-07-16 12:48:23 -0600
committerMark Brown <broonie@kernel.org>2015-02-19 22:42:40 +0900
commit9b989b5586997cff26c1a1644a6d4dcdbe78ecf5 (patch)
tree4269de81d9ce709368d9b59df259dc2ecd869a59
parent915ec64e24a02a4562c855376ce7b4abb8bf558d (diff)
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: Grant Likely <grant.likely@linaro.org> Cc: Nathan Fontenot <nfont@austin.ibm.com> (cherry picked from commit 259092a35c7e11f1d4616b0f5b3ba7b851fe4fa6) Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c2
-rw-r--r--drivers/crypto/nx/nx-842.c30
-rw-r--r--drivers/of/base.c21
-rw-r--r--drivers/of/dynamic.c18
-rw-r--r--drivers/of/of_private.h4
-rw-r--r--include/linux/of.h1
6 files changed, 29 insertions, 47 deletions
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 9590dbb756f2..daae52670a0a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -212,7 +212,7 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
if (!memblock_size)
return -EINVAL;
- p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL);
+ p = (u32 *) pr->old_prop->value;
if (!p)
return -EINVAL;
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
index 1e5481d88a26..a86359765fda 100644
--- a/drivers/crypto/nx/nx-842.c
+++ b/drivers/crypto/nx/nx-842.c
@@ -936,28 +936,14 @@ static int nx842_OF_upd(struct property *new_prop)
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
- * has no impact.
- */
- goto out;
- }
- }
+ /*
+ * If this is a property update, there are only certain properties that
+ * 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;
/* Perform property updates */
ret = nx842_OF_upd_status(new_devdata, status);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ae220dfebadd..8059f149d171 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1599,10 +1599,6 @@ int of_add_property(struct device_node *np, struct property *prop)
unsigned long flags;
int rc;
- rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
- if (rc)
- return rc;
-
mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1614,6 +1610,9 @@ int of_add_property(struct device_node *np, struct property *prop)
mutex_unlock(&of_mutex);
+ if (!rc)
+ of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
+
return rc;
}
@@ -1656,10 +1655,6 @@ int of_remove_property(struct device_node *np, struct property *prop)
unsigned long flags;
int rc;
- rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
- if (rc)
- return rc;
-
mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1671,6 +1666,9 @@ int of_remove_property(struct device_node *np, struct property *prop)
mutex_unlock(&of_mutex);
+ if (!rc)
+ of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
+
return rc;
}
@@ -1730,10 +1728,6 @@ int of_update_property(struct device_node *np, struct property *newprop)
if (!newprop->name)
return -EINVAL;
- rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
- if (rc)
- return rc;
-
mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1745,6 +1739,9 @@ int of_update_property(struct device_node *np, struct property *newprop)
mutex_unlock(&of_mutex);
+ if (!rc)
+ of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
+
return rc;
}
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 2f50de87ae08..f298dc55368f 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -83,7 +83,7 @@ int of_reconfig_notify(unsigned long action, void *p)
}
int of_property_notify(int action, struct device_node *np,
- struct property *prop)
+ struct property *prop, struct property *oldprop)
{
struct of_prop_reconfig pr;
@@ -93,6 +93,7 @@ int of_property_notify(int action, struct device_node *np,
pr.dn = np;
pr.prop = prop;
+ pr.old_prop = oldprop;
return of_reconfig_notify(action, &pr);
}
@@ -125,11 +126,6 @@ void __of_attach_node(struct device_node *np)
int of_attach_node(struct device_node *np)
{
unsigned long flags;
- int rc;
-
- rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
- if (rc)
- return rc;
mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -138,6 +134,9 @@ int of_attach_node(struct device_node *np)
__of_attach_node_sysfs(np);
mutex_unlock(&of_mutex);
+
+ of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
+
return 0;
}
@@ -188,10 +187,6 @@ int of_detach_node(struct device_node *np)
unsigned long flags;
int rc = 0;
- rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
- if (rc)
- return rc;
-
mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
__of_detach_node(np);
@@ -199,6 +194,9 @@ int of_detach_node(struct device_node *np)
__of_detach_node_sysfs(np);
mutex_unlock(&of_mutex);
+
+ of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
+
return rc;
}
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 8129c0e58d70..f69ccb1fa308 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -43,11 +43,11 @@ static inline struct device_node *kobj_to_device_node(struct kobject *kobj)
#if defined(CONFIG_OF_DYNAMIC)
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);
#else /* CONFIG_OF_DYNAMIC */
static inline int of_property_notify(int action, struct device_node *np,
- struct property *prop)
+ struct property *prop, struct property *old_prop)
{
return 0;
}
diff --git a/include/linux/of.h b/include/linux/of.h
index c9cabc4ffbc9..689e26274cf0 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -313,6 +313,7 @@ extern int of_update_property(struct device_node *np, struct property *newprop);
struct of_prop_reconfig {
struct device_node *dn;
struct property *prop;
+ struct property *old_prop;
};
extern int of_reconfig_notifier_register(struct notifier_block *);