Commit f5242e5a authored by Grant Likely's avatar Grant Likely

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: default avatarGrant 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>
parent 00aa3720
...@@ -1711,12 +1711,11 @@ static void stage_topology_update(int core_id) ...@@ -1711,12 +1711,11 @@ static void stage_topology_update(int core_id)
static int dt_update_callback(struct notifier_block *nb, static int dt_update_callback(struct notifier_block *nb,
unsigned long action, void *data) unsigned long action, void *data)
{ {
struct of_prop_reconfig *update; struct of_reconfig_data *update = data;
int rc = NOTIFY_DONE; int rc = NOTIFY_DONE;
switch (action) { switch (action) {
case OF_RECONFIG_UPDATE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY:
update = (struct of_prop_reconfig *)data;
if (!of_prop_cmp(update->dn->type, "cpu") && if (!of_prop_cmp(update->dn->type, "cpu") &&
!of_prop_cmp(update->prop->name, "ibm,associativity")) { !of_prop_cmp(update->prop->name, "ibm,associativity")) {
u32 core_id; u32 core_id;
......
...@@ -340,16 +340,17 @@ static void pseries_remove_processor(struct device_node *np) ...@@ -340,16 +340,17 @@ static void pseries_remove_processor(struct device_node *np)
} }
static int pseries_smp_notifier(struct notifier_block *nb, static int pseries_smp_notifier(struct notifier_block *nb,
unsigned long action, void *node) unsigned long action, void *data)
{ {
struct of_reconfig_data *rd = data;
int err = 0; int err = 0;
switch (action) { switch (action) {
case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_ATTACH_NODE:
err = pseries_add_processor(node); err = pseries_add_processor(rd->dn);
break; break;
case OF_RECONFIG_DETACH_NODE: case OF_RECONFIG_DETACH_NODE:
pseries_remove_processor(node); pseries_remove_processor(rd->dn);
break; break;
} }
return notifier_from_errno(err); return notifier_from_errno(err);
......
...@@ -183,7 +183,7 @@ static int pseries_add_mem_node(struct device_node *np) ...@@ -183,7 +183,7 @@ static int pseries_add_mem_node(struct device_node *np)
return (ret < 0) ? -EINVAL : 0; return (ret < 0) ? -EINVAL : 0;
} }
static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
{ {
struct of_drconf_cell *new_drmem, *old_drmem; struct of_drconf_cell *new_drmem, *old_drmem;
unsigned long memblock_size; unsigned long memblock_size;
...@@ -232,22 +232,21 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) ...@@ -232,22 +232,21 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
} }
static int pseries_memory_notifier(struct notifier_block *nb, static int pseries_memory_notifier(struct notifier_block *nb,
unsigned long action, void *node) unsigned long action, void *data)
{ {
struct of_prop_reconfig *pr; struct of_reconfig_data *rd = data;
int err = 0; int err = 0;
switch (action) { switch (action) {
case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_ATTACH_NODE:
err = pseries_add_mem_node(node); err = pseries_add_mem_node(rd->dn);
break; break;
case OF_RECONFIG_DETACH_NODE: case OF_RECONFIG_DETACH_NODE:
err = pseries_remove_mem_node(node); err = pseries_remove_mem_node(rd->dn);
break; break;
case OF_RECONFIG_UPDATE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY:
pr = (struct of_prop_reconfig *)node; if (!strcmp(rd->prop->name, "ibm,dynamic-memory"))
if (!strcmp(pr->prop->name, "ibm,dynamic-memory")) err = pseries_update_drconf_memory(rd);
err = pseries_update_drconf_memory(pr);
break; break;
} }
return notifier_from_errno(err); return notifier_from_errno(err);
......
...@@ -1251,10 +1251,11 @@ static struct notifier_block iommu_mem_nb = { ...@@ -1251,10 +1251,11 @@ static struct notifier_block iommu_mem_nb = {
.notifier_call = iommu_mem_notifier, .notifier_call = iommu_mem_notifier,
}; };
static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data)
{ {
int err = NOTIFY_OK; int err = NOTIFY_OK;
struct device_node *np = node; struct of_reconfig_data *rd = data;
struct device_node *np = rd->dn;
struct pci_dn *pci = PCI_DN(np); struct pci_dn *pci = PCI_DN(np);
struct direct_window *window; struct direct_window *window;
......
...@@ -251,9 +251,10 @@ static void __init pseries_discover_pic(void) ...@@ -251,9 +251,10 @@ static void __init pseries_discover_pic(void)
" interrupt-controller\n"); " interrupt-controller\n");
} }
static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data)
{ {
struct device_node *np = node; struct of_reconfig_data *rd = data;
struct device_node *np = rd->dn;
struct pci_dn *pci = NULL; struct pci_dn *pci = NULL;
int err = NOTIFY_OK; int err = NOTIFY_OK;
......
...@@ -1009,9 +1009,9 @@ static int nx842_OF_upd(struct property *new_prop) ...@@ -1009,9 +1009,9 @@ static int nx842_OF_upd(struct property *new_prop)
* notifier_to_errno() to decode this value * notifier_to_errno() to decode this value
*/ */
static int nx842_OF_notifier(struct notifier_block *np, unsigned long action, static int nx842_OF_notifier(struct notifier_block *np, unsigned long action,
void *update) void *data)
{ {
struct of_prop_reconfig *upd = update; struct of_reconfig_data *upd = data;
struct nx842_devdata *local_devdata; struct nx842_devdata *local_devdata;
struct device_node *node = NULL; struct device_node *node = NULL;
......
...@@ -87,18 +87,17 @@ const char *action_names[] = { ...@@ -87,18 +87,17 @@ const char *action_names[] = {
}; };
#endif #endif
int of_reconfig_notify(unsigned long action, void *p) int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
{ {
int rc; int rc;
#ifdef DEBUG #ifdef DEBUG
struct device_node *dn = p; struct of_reconfig_data *pr = p;
struct of_prop_reconfig *pr = p;
switch (action) { switch (action) {
case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_ATTACH_NODE:
case OF_RECONFIG_DETACH_NODE: case OF_RECONFIG_DETACH_NODE:
pr_debug("of/notify %-15s %s\n", action_names[action], pr_debug("of/notify %-15s %s\n", action_names[action],
dn->full_name); pr->dn->full_name);
break; break;
case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_ADD_PROPERTY:
case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY:
...@@ -122,31 +121,22 @@ int of_reconfig_notify(unsigned long action, void *p) ...@@ -122,31 +121,22 @@ int of_reconfig_notify(unsigned long action, void *p)
* Returns 0 on device going from enabled to disabled, 1 on device * Returns 0 on device going from enabled to disabled, 1 on device
* going from disabled to enabled and -1 on no change. * going from disabled to enabled and -1 on no change.
*/ */
int of_reconfig_get_state_change(unsigned long action, void *arg) int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
{ {
struct device_node *dn; struct property *prop, *old_prop = NULL;
struct property *prop, *old_prop;
struct of_prop_reconfig *pr;
int is_status, status_state, old_status_state, prev_state, new_state; int is_status, status_state, old_status_state, prev_state, new_state;
/* figure out if a device should be created or destroyed */ /* figure out if a device should be created or destroyed */
dn = NULL;
prop = old_prop = NULL;
switch (action) { switch (action) {
case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_ATTACH_NODE:
case OF_RECONFIG_DETACH_NODE: case OF_RECONFIG_DETACH_NODE:
dn = arg; prop = of_find_property(pr->dn, "status", NULL);
prop = of_find_property(dn, "status", NULL);
break; break;
case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_ADD_PROPERTY:
case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY:
pr = arg;
dn = pr->dn;
prop = pr->prop; prop = pr->prop;
break; break;
case OF_RECONFIG_UPDATE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY:
pr = arg;
dn = pr->dn;
prop = pr->prop; prop = pr->prop;
old_prop = pr->old_prop; old_prop = pr->old_prop;
break; break;
...@@ -212,7 +202,7 @@ EXPORT_SYMBOL_GPL(of_reconfig_get_state_change); ...@@ -212,7 +202,7 @@ EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
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 *oldprop) struct property *prop, struct property *oldprop)
{ {
struct of_prop_reconfig pr; struct of_reconfig_data pr;
/* only call notifiers if the node is attached */ /* only call notifiers if the node is attached */
if (!of_node_is_attached(np)) if (!of_node_is_attached(np))
...@@ -250,8 +240,12 @@ void __of_attach_node(struct device_node *np) ...@@ -250,8 +240,12 @@ void __of_attach_node(struct device_node *np)
*/ */
int of_attach_node(struct device_node *np) int of_attach_node(struct device_node *np)
{ {
struct of_reconfig_data rd;
unsigned long flags; unsigned long flags;
memset(&rd, 0, sizeof(rd));
rd.dn = np;
mutex_lock(&of_mutex); mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
__of_attach_node(np); __of_attach_node(np);
...@@ -260,7 +254,7 @@ int of_attach_node(struct device_node *np) ...@@ -260,7 +254,7 @@ 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); of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);
return 0; return 0;
} }
...@@ -298,9 +292,13 @@ void __of_detach_node(struct device_node *np) ...@@ -298,9 +292,13 @@ void __of_detach_node(struct device_node *np)
*/ */
int of_detach_node(struct device_node *np) int of_detach_node(struct device_node *np)
{ {
struct of_reconfig_data rd;
unsigned long flags; unsigned long flags;
int rc = 0; int rc = 0;
memset(&rd, 0, sizeof(rd));
rd.dn = np;
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);
...@@ -309,7 +307,7 @@ int of_detach_node(struct device_node *np) ...@@ -309,7 +307,7 @@ 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); of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
return rc; return rc;
} }
...@@ -505,6 +503,7 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce, ...@@ -505,6 +503,7 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert)
{ {
struct of_reconfig_data rd;
struct of_changeset_entry ce_inverted; struct of_changeset_entry ce_inverted;
int ret; int ret;
...@@ -516,7 +515,9 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve ...@@ -516,7 +515,9 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve
switch (ce->action) { switch (ce->action) {
case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_ATTACH_NODE:
case OF_RECONFIG_DETACH_NODE: case OF_RECONFIG_DETACH_NODE:
ret = of_reconfig_notify(ce->action, ce->np); memset(&rd, 0, sizeof(rd));
rd.dn = ce->np;
ret = of_reconfig_notify(ce->action, &rd);
break; break;
case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_ADD_PROPERTY:
case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY:
......
...@@ -73,6 +73,12 @@ struct of_phandle_args { ...@@ -73,6 +73,12 @@ struct of_phandle_args {
uint32_t args[MAX_PHANDLE_ARGS]; uint32_t args[MAX_PHANDLE_ARGS];
}; };
struct of_reconfig_data {
struct device_node *dn;
struct property *prop;
struct property *old_prop;
};
/* initialize a node */ /* initialize a node */
extern struct kobj_type of_node_ktype; extern struct kobj_type of_node_ktype;
static inline void of_node_init(struct device_node *node) static inline void of_node_init(struct device_node *node)
...@@ -318,12 +324,6 @@ extern int of_update_property(struct device_node *np, struct property *newprop); ...@@ -318,12 +324,6 @@ extern int of_update_property(struct device_node *np, struct property *newprop);
#define OF_RECONFIG_REMOVE_PROPERTY 0x0004 #define OF_RECONFIG_REMOVE_PROPERTY 0x0004
#define OF_RECONFIG_UPDATE_PROPERTY 0x0005 #define OF_RECONFIG_UPDATE_PROPERTY 0x0005
struct of_prop_reconfig {
struct device_node *dn;
struct property *prop;
struct property *old_prop;
};
extern int of_attach_node(struct device_node *); extern int of_attach_node(struct device_node *);
extern int of_detach_node(struct device_node *); extern int of_detach_node(struct device_node *);
...@@ -892,8 +892,9 @@ enum of_reconfig_change { ...@@ -892,8 +892,9 @@ enum of_reconfig_change {
#ifdef CONFIG_OF_DYNAMIC #ifdef CONFIG_OF_DYNAMIC
extern int of_reconfig_notifier_register(struct notifier_block *); extern int of_reconfig_notifier_register(struct notifier_block *);
extern int of_reconfig_notifier_unregister(struct notifier_block *); extern int of_reconfig_notifier_unregister(struct notifier_block *);
extern int of_reconfig_notify(unsigned long, void *); extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd);
extern int of_reconfig_get_state_change(unsigned long action, void *arg); extern int of_reconfig_get_state_change(unsigned long action,
struct of_reconfig_data *arg);
extern void of_changeset_init(struct of_changeset *ocs); extern void of_changeset_init(struct of_changeset *ocs);
extern void of_changeset_destroy(struct of_changeset *ocs); extern void of_changeset_destroy(struct of_changeset *ocs);
...@@ -941,11 +942,13 @@ static inline int of_reconfig_notifier_unregister(struct notifier_block *nb) ...@@ -941,11 +942,13 @@ static inline int of_reconfig_notifier_unregister(struct notifier_block *nb)
{ {
return -EINVAL; return -EINVAL;
} }
static inline int of_reconfig_notify(unsigned long action, void *arg) static inline int of_reconfig_notify(unsigned long action,
struct of_reconfig_data *arg)
{ {
return -EINVAL; return -EINVAL;
} }
static inline int of_reconfig_get_state_change(unsigned long action, void *arg) static inline int of_reconfig_get_state_change(unsigned long action,
struct of_reconfig_data *arg)
{ {
return -EINVAL; return -EINVAL;
} }
......
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