aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-07-16 14:48:23 -0400
committerGrant Likely <grant.likely@linaro.org>2014-07-23 19:08:13 -0400
commit259092a35c7e11f1d4616b0f5b3ba7b851fe4fa6 (patch)
tree932489d219e9c07b3a2f1ba37aabf7ed58242b7a
parenta25095d451ece23b1fef34474f3230100db7aa05 (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>
-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 7995135170a3..ac01e188faef 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -194,7 +194,7 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
194 if (!memblock_size) 194 if (!memblock_size)
195 return -EINVAL; 195 return -EINVAL;
196 196
197 p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL); 197 p = (u32 *) pr->old_prop->value;
198 if (!p) 198 if (!p)
199 return -EINVAL; 199 return -EINVAL;
200 200
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
index 502edf0a2933..c897c3a5ee17 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)
936 goto error_out; 936 goto error_out;
937 } 937 }
938 938
939 /* Set ptr to new property if provided */ 939 /*
940 if (new_prop) { 940 * If this is a property update, there are only certain properties that
941 /* Single property */ 941 * we care about. Bail if it isn't in the below list
942 if (!strncmp(new_prop->name, "status", new_prop->length)) { 942 */
943 status = new_prop; 943 if (new_prop && (strncmp(new_prop->name, "status", new_prop->length) ||
944 944 strncmp(new_prop->name, "ibm,max-sg-len", new_prop->length) ||
945 } else if (!strncmp(new_prop->name, "ibm,max-sg-len", 945 strncmp(new_prop->name, "ibm,max-sync-cop", new_prop->length)))
946 new_prop->length)) { 946 goto out;
947 maxsglen = new_prop;
948
949 } else if (!strncmp(new_prop->name, "ibm,max-sync-cop",
950 new_prop->length)) {
951 maxsyncop = new_prop;
952
953 } else {
954 /*
955 * Skip the update, the property being updated
956 * has no impact.
957 */
958 goto out;
959 }
960 }
961 947
962 /* Perform property updates */ 948 /* Perform property updates */
963 ret = nx842_OF_upd_status(new_devdata, status); 949 ret = nx842_OF_upd_status(new_devdata, status);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ededf8e33145..a7ad1013edfa 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1674,10 +1674,6 @@ int of_add_property(struct device_node *np, struct property *prop)
1674 unsigned long flags; 1674 unsigned long flags;
1675 int rc; 1675 int rc;
1676 1676
1677 rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
1678 if (rc)
1679 return rc;
1680
1681 mutex_lock(&of_mutex); 1677 mutex_lock(&of_mutex);
1682 1678
1683 raw_spin_lock_irqsave(&devtree_lock, flags); 1679 raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1689,6 +1685,9 @@ int of_add_property(struct device_node *np, struct property *prop)
1689 1685
1690 mutex_unlock(&of_mutex); 1686 mutex_unlock(&of_mutex);
1691 1687
1688 if (!rc)
1689 of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
1690
1692 return rc; 1691 return rc;
1693} 1692}
1694 1693
@@ -1731,10 +1730,6 @@ int of_remove_property(struct device_node *np, struct property *prop)
1731 unsigned long flags; 1730 unsigned long flags;
1732 int rc; 1731 int rc;
1733 1732
1734 rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
1735 if (rc)
1736 return rc;
1737
1738 mutex_lock(&of_mutex); 1733 mutex_lock(&of_mutex);
1739 1734
1740 raw_spin_lock_irqsave(&devtree_lock, flags); 1735 raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1746,6 +1741,9 @@ int of_remove_property(struct device_node *np, struct property *prop)
1746 1741
1747 mutex_unlock(&of_mutex); 1742 mutex_unlock(&of_mutex);
1748 1743
1744 if (!rc)
1745 of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
1746
1749 return rc; 1747 return rc;
1750} 1748}
1751 1749
@@ -1805,10 +1803,6 @@ int of_update_property(struct device_node *np, struct property *newprop)
1805 if (!newprop->name) 1803 if (!newprop->name)
1806 return -EINVAL; 1804 return -EINVAL;
1807 1805
1808 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
1809 if (rc)
1810 return rc;
1811
1812 mutex_lock(&of_mutex); 1806 mutex_lock(&of_mutex);
1813 1807
1814 raw_spin_lock_irqsave(&devtree_lock, flags); 1808 raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -1820,6 +1814,9 @@ int of_update_property(struct device_node *np, struct property *newprop)
1820 1814
1821 mutex_unlock(&of_mutex); 1815 mutex_unlock(&of_mutex);
1822 1816
1817 if (!rc)
1818 of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
1819
1823 return rc; 1820 return rc;
1824} 1821}
1825 1822
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 7c020b9a3317..7bd5501736a6 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -83,7 +83,7 @@ int of_reconfig_notify(unsigned long action, void *p)
83} 83}
84 84
85int of_property_notify(int action, struct device_node *np, 85int of_property_notify(int action, struct device_node *np,
86 struct property *prop) 86 struct property *prop, struct property *oldprop)
87{ 87{
88 struct of_prop_reconfig pr; 88 struct of_prop_reconfig pr;
89 89
@@ -93,6 +93,7 @@ int of_property_notify(int action, struct device_node *np,
93 93
94 pr.dn = np; 94 pr.dn = np;
95 pr.prop = prop; 95 pr.prop = prop;
96 pr.old_prop = oldprop;
96 return of_reconfig_notify(action, &pr); 97 return of_reconfig_notify(action, &pr);
97} 98}
98 99
@@ -125,11 +126,6 @@ void __of_attach_node(struct device_node *np)
125int of_attach_node(struct device_node *np) 126int of_attach_node(struct device_node *np)
126{ 127{
127 unsigned long flags; 128 unsigned long flags;
128 int rc;
129
130 rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
131 if (rc)
132 return rc;
133 129
134 mutex_lock(&of_mutex); 130 mutex_lock(&of_mutex);
135 raw_spin_lock_irqsave(&devtree_lock, flags); 131 raw_spin_lock_irqsave(&devtree_lock, flags);
@@ -138,6 +134,9 @@ int of_attach_node(struct device_node *np)
138 134
139 __of_attach_node_sysfs(np); 135 __of_attach_node_sysfs(np);
140 mutex_unlock(&of_mutex); 136 mutex_unlock(&of_mutex);
137
138 of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
139
141 return 0; 140 return 0;
142} 141}
143 142
@@ -188,10 +187,6 @@ int of_detach_node(struct device_node *np)
188 unsigned long flags; 187 unsigned long flags;
189 int rc = 0; 188 int rc = 0;
190 189
191 rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
192 if (rc)
193 return rc;
194
195 mutex_lock(&of_mutex); 190 mutex_lock(&of_mutex);
196 raw_spin_lock_irqsave(&devtree_lock, flags); 191 raw_spin_lock_irqsave(&devtree_lock, flags);
197 __of_detach_node(np); 192 __of_detach_node(np);
@@ -199,6 +194,9 @@ int of_detach_node(struct device_node *np)
199 194
200 __of_detach_node_sysfs(np); 195 __of_detach_node_sysfs(np);
201 mutex_unlock(&of_mutex); 196 mutex_unlock(&of_mutex);
197
198 of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
199
202 return rc; 200 return rc;
203} 201}
204 202
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)
43 43
44#if defined(CONFIG_OF_DYNAMIC) 44#if defined(CONFIG_OF_DYNAMIC)
45extern int of_property_notify(int action, struct device_node *np, 45extern int of_property_notify(int action, struct device_node *np,
46 struct property *prop); 46 struct property *prop, struct property *old_prop);
47extern void of_node_release(struct kobject *kobj); 47extern void of_node_release(struct kobject *kobj);
48#else /* CONFIG_OF_DYNAMIC */ 48#else /* CONFIG_OF_DYNAMIC */
49static inline int of_property_notify(int action, struct device_node *np, 49static inline int of_property_notify(int action, struct device_node *np,
50 struct property *prop) 50 struct property *prop, struct property *old_prop)
51{ 51{
52 return 0; 52 return 0;
53} 53}
diff --git a/include/linux/of.h b/include/linux/of.h
index 705fa12fca7f..400f18cb4fff 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -321,6 +321,7 @@ extern int of_update_property(struct device_node *np, struct property *newprop);
321struct of_prop_reconfig { 321struct of_prop_reconfig {
322 struct device_node *dn; 322 struct device_node *dn;
323 struct property *prop; 323 struct property *prop;
324 struct property *old_prop;
324}; 325};
325 326
326extern int of_reconfig_notifier_register(struct notifier_block *); 327extern int of_reconfig_notifier_register(struct notifier_block *);