diff options
author | Grant Likely <grant.likely@linaro.org> | 2014-11-24 12:58:01 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@linaro.org> | 2014-11-24 17:25:03 -0500 |
commit | f5242e5a883bf1c1aba6bfd87b85e7dda0e62191 (patch) | |
tree | ff348e70ad50d96de50212f9a6e6b6088bb7feef /drivers/of | |
parent | 00aa37206e1a54dae61a0dba96bf2ee0938b99d7 (diff) |
of/reconfig: Always use the same structure for notifiers
The OF_RECONFIG notifier callback uses a different structure depending
on whether it is a node change or a property change. This is silly, and
not very safe. Rework the code to use the same data structure regardless
of the type of notifier.
Signed-off-by: Grant Likely <grant.likely@linaro.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Cc: <linuxppc-dev@lists.ozlabs.org>
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/dynamic.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index cc106529dca8..3351ef408125 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c | |||
@@ -87,18 +87,17 @@ const char *action_names[] = { | |||
87 | }; | 87 | }; |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | int of_reconfig_notify(unsigned long action, void *p) | 90 | int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) |
91 | { | 91 | { |
92 | int rc; | 92 | int rc; |
93 | #ifdef DEBUG | 93 | #ifdef DEBUG |
94 | struct device_node *dn = p; | 94 | struct of_reconfig_data *pr = p; |
95 | struct of_prop_reconfig *pr = p; | ||
96 | 95 | ||
97 | switch (action) { | 96 | switch (action) { |
98 | case OF_RECONFIG_ATTACH_NODE: | 97 | case OF_RECONFIG_ATTACH_NODE: |
99 | case OF_RECONFIG_DETACH_NODE: | 98 | case OF_RECONFIG_DETACH_NODE: |
100 | pr_debug("of/notify %-15s %s\n", action_names[action], | 99 | pr_debug("of/notify %-15s %s\n", action_names[action], |
101 | dn->full_name); | 100 | pr->dn->full_name); |
102 | break; | 101 | break; |
103 | case OF_RECONFIG_ADD_PROPERTY: | 102 | case OF_RECONFIG_ADD_PROPERTY: |
104 | case OF_RECONFIG_REMOVE_PROPERTY: | 103 | case OF_RECONFIG_REMOVE_PROPERTY: |
@@ -122,31 +121,22 @@ int of_reconfig_notify(unsigned long action, void *p) | |||
122 | * Returns 0 on device going from enabled to disabled, 1 on device | 121 | * Returns 0 on device going from enabled to disabled, 1 on device |
123 | * going from disabled to enabled and -1 on no change. | 122 | * going from disabled to enabled and -1 on no change. |
124 | */ | 123 | */ |
125 | int of_reconfig_get_state_change(unsigned long action, void *arg) | 124 | int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) |
126 | { | 125 | { |
127 | struct device_node *dn; | 126 | struct property *prop, *old_prop = NULL; |
128 | struct property *prop, *old_prop; | ||
129 | struct of_prop_reconfig *pr; | ||
130 | int is_status, status_state, old_status_state, prev_state, new_state; | 127 | int is_status, status_state, old_status_state, prev_state, new_state; |
131 | 128 | ||
132 | /* figure out if a device should be created or destroyed */ | 129 | /* figure out if a device should be created or destroyed */ |
133 | dn = NULL; | ||
134 | prop = old_prop = NULL; | ||
135 | switch (action) { | 130 | switch (action) { |
136 | case OF_RECONFIG_ATTACH_NODE: | 131 | case OF_RECONFIG_ATTACH_NODE: |
137 | case OF_RECONFIG_DETACH_NODE: | 132 | case OF_RECONFIG_DETACH_NODE: |
138 | dn = arg; | 133 | prop = of_find_property(pr->dn, "status", NULL); |
139 | prop = of_find_property(dn, "status", NULL); | ||
140 | break; | 134 | break; |
141 | case OF_RECONFIG_ADD_PROPERTY: | 135 | case OF_RECONFIG_ADD_PROPERTY: |
142 | case OF_RECONFIG_REMOVE_PROPERTY: | 136 | case OF_RECONFIG_REMOVE_PROPERTY: |
143 | pr = arg; | ||
144 | dn = pr->dn; | ||
145 | prop = pr->prop; | 137 | prop = pr->prop; |
146 | break; | 138 | break; |
147 | case OF_RECONFIG_UPDATE_PROPERTY: | 139 | case OF_RECONFIG_UPDATE_PROPERTY: |
148 | pr = arg; | ||
149 | dn = pr->dn; | ||
150 | prop = pr->prop; | 140 | prop = pr->prop; |
151 | old_prop = pr->old_prop; | 141 | old_prop = pr->old_prop; |
152 | break; | 142 | break; |
@@ -212,7 +202,7 @@ EXPORT_SYMBOL_GPL(of_reconfig_get_state_change); | |||
212 | int of_property_notify(int action, struct device_node *np, | 202 | int of_property_notify(int action, struct device_node *np, |
213 | struct property *prop, struct property *oldprop) | 203 | struct property *prop, struct property *oldprop) |
214 | { | 204 | { |
215 | struct of_prop_reconfig pr; | 205 | struct of_reconfig_data pr; |
216 | 206 | ||
217 | /* only call notifiers if the node is attached */ | 207 | /* only call notifiers if the node is attached */ |
218 | if (!of_node_is_attached(np)) | 208 | if (!of_node_is_attached(np)) |
@@ -250,8 +240,12 @@ void __of_attach_node(struct device_node *np) | |||
250 | */ | 240 | */ |
251 | int of_attach_node(struct device_node *np) | 241 | int of_attach_node(struct device_node *np) |
252 | { | 242 | { |
243 | struct of_reconfig_data rd; | ||
253 | unsigned long flags; | 244 | unsigned long flags; |
254 | 245 | ||
246 | memset(&rd, 0, sizeof(rd)); | ||
247 | rd.dn = np; | ||
248 | |||
255 | mutex_lock(&of_mutex); | 249 | mutex_lock(&of_mutex); |
256 | raw_spin_lock_irqsave(&devtree_lock, flags); | 250 | raw_spin_lock_irqsave(&devtree_lock, flags); |
257 | __of_attach_node(np); | 251 | __of_attach_node(np); |
@@ -260,7 +254,7 @@ int of_attach_node(struct device_node *np) | |||
260 | __of_attach_node_sysfs(np); | 254 | __of_attach_node_sysfs(np); |
261 | mutex_unlock(&of_mutex); | 255 | mutex_unlock(&of_mutex); |
262 | 256 | ||
263 | of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); | 257 | of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd); |
264 | 258 | ||
265 | return 0; | 259 | return 0; |
266 | } | 260 | } |
@@ -298,9 +292,13 @@ void __of_detach_node(struct device_node *np) | |||
298 | */ | 292 | */ |
299 | int of_detach_node(struct device_node *np) | 293 | int of_detach_node(struct device_node *np) |
300 | { | 294 | { |
295 | struct of_reconfig_data rd; | ||
301 | unsigned long flags; | 296 | unsigned long flags; |
302 | int rc = 0; | 297 | int rc = 0; |
303 | 298 | ||
299 | memset(&rd, 0, sizeof(rd)); | ||
300 | rd.dn = np; | ||
301 | |||
304 | mutex_lock(&of_mutex); | 302 | mutex_lock(&of_mutex); |
305 | raw_spin_lock_irqsave(&devtree_lock, flags); | 303 | raw_spin_lock_irqsave(&devtree_lock, flags); |
306 | __of_detach_node(np); | 304 | __of_detach_node(np); |
@@ -309,7 +307,7 @@ int of_detach_node(struct device_node *np) | |||
309 | __of_detach_node_sysfs(np); | 307 | __of_detach_node_sysfs(np); |
310 | mutex_unlock(&of_mutex); | 308 | mutex_unlock(&of_mutex); |
311 | 309 | ||
312 | of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); | 310 | of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd); |
313 | 311 | ||
314 | return rc; | 312 | return rc; |
315 | } | 313 | } |
@@ -505,6 +503,7 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce, | |||
505 | 503 | ||
506 | static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) | 504 | static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) |
507 | { | 505 | { |
506 | struct of_reconfig_data rd; | ||
508 | struct of_changeset_entry ce_inverted; | 507 | struct of_changeset_entry ce_inverted; |
509 | int ret; | 508 | int ret; |
510 | 509 | ||
@@ -516,7 +515,9 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve | |||
516 | switch (ce->action) { | 515 | switch (ce->action) { |
517 | case OF_RECONFIG_ATTACH_NODE: | 516 | case OF_RECONFIG_ATTACH_NODE: |
518 | case OF_RECONFIG_DETACH_NODE: | 517 | case OF_RECONFIG_DETACH_NODE: |
519 | ret = of_reconfig_notify(ce->action, ce->np); | 518 | memset(&rd, 0, sizeof(rd)); |
519 | rd.dn = ce->np; | ||
520 | ret = of_reconfig_notify(ce->action, &rd); | ||
520 | break; | 521 | break; |
521 | case OF_RECONFIG_ADD_PROPERTY: | 522 | case OF_RECONFIG_ADD_PROPERTY: |
522 | case OF_RECONFIG_REMOVE_PROPERTY: | 523 | case OF_RECONFIG_REMOVE_PROPERTY: |