of: Move dynamic node fixups out of powerpc and into common code
PowerPC does an odd thing with dynamic nodes. It uses a notifier to catch new node additions and set some of the values like name and type. This makes no sense since that same code can be put directly into of_attach_node(). Besides, all dynamic node users need this, not just powerpc. Fix this problem by moving the logic out of arch/powerpc and into drivers/of/dynamic.c. It is also important to remove this notifier because we want to move the firing of notifiers from before the tree is modified to after so that the receiver gets a consistent view of the tree, but that is incompatible with notifiers that modify the node. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Nathan Fontenot <nfont@austin.ibm.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
6162dbe49a
commit
a25095d451
@ -821,76 +821,6 @@ int cpu_to_chip_id(int cpu)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cpu_to_chip_id);
|
EXPORT_SYMBOL(cpu_to_chip_id);
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
|
||||||
/*
|
|
||||||
* Fix up the uninitialized fields in a new device node:
|
|
||||||
* name, type and pci-specific fields
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int of_finish_dynamic_node(struct device_node *node)
|
|
||||||
{
|
|
||||||
struct device_node *parent = of_get_parent(node);
|
|
||||||
int err = 0;
|
|
||||||
const phandle *ibm_phandle;
|
|
||||||
|
|
||||||
node->name = of_get_property(node, "name", NULL);
|
|
||||||
node->type = of_get_property(node, "device_type", NULL);
|
|
||||||
|
|
||||||
if (!node->name)
|
|
||||||
node->name = "<NULL>";
|
|
||||||
if (!node->type)
|
|
||||||
node->type = "<NULL>";
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't support that function on PowerMac, at least
|
|
||||||
* not yet
|
|
||||||
*/
|
|
||||||
if (machine_is(powermac))
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
/* fix up new node's phandle field */
|
|
||||||
if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL)))
|
|
||||||
node->phandle = *ibm_phandle;
|
|
||||||
|
|
||||||
out:
|
|
||||||
of_node_put(parent);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int prom_reconfig_notifier(struct notifier_block *nb,
|
|
||||||
unsigned long action, void *node)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
switch (action) {
|
|
||||||
case OF_RECONFIG_ATTACH_NODE:
|
|
||||||
err = of_finish_dynamic_node(node);
|
|
||||||
if (err < 0)
|
|
||||||
printk(KERN_ERR "finish_node returned %d\n", err);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return notifier_from_errno(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct notifier_block prom_reconfig_nb = {
|
|
||||||
.notifier_call = prom_reconfig_notifier,
|
|
||||||
.priority = 10, /* This one needs to run first */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init prom_reconfig_setup(void)
|
|
||||||
{
|
|
||||||
return of_reconfig_notifier_register(&prom_reconfig_nb);
|
|
||||||
}
|
|
||||||
__initcall(prom_reconfig_setup);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
|
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
|
||||||
{
|
{
|
||||||
return (int)phys_id == get_hard_smp_processor_id(cpu);
|
return (int)phys_id == get_hard_smp_processor_id(cpu);
|
||||||
|
@ -266,8 +266,8 @@ EXPORT_SYMBOL(of_find_all_nodes);
|
|||||||
* Find a property with a given name for a given node
|
* Find a property with a given name for a given node
|
||||||
* and return the value.
|
* and return the value.
|
||||||
*/
|
*/
|
||||||
static const void *__of_get_property(const struct device_node *np,
|
const void *__of_get_property(const struct device_node *np,
|
||||||
const char *name, int *lenp)
|
const char *name, int *lenp)
|
||||||
{
|
{
|
||||||
struct property *pp = __of_find_property(np, name, lenp);
|
struct property *pp = __of_find_property(np, name, lenp);
|
||||||
|
|
||||||
|
@ -98,6 +98,19 @@ int of_property_notify(int action, struct device_node *np,
|
|||||||
|
|
||||||
void __of_attach_node(struct device_node *np)
|
void __of_attach_node(struct device_node *np)
|
||||||
{
|
{
|
||||||
|
const __be32 *phandle;
|
||||||
|
int sz;
|
||||||
|
|
||||||
|
np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
|
||||||
|
np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
|
||||||
|
|
||||||
|
phandle = __of_get_property(np, "phandle", &sz);
|
||||||
|
if (!phandle)
|
||||||
|
phandle = __of_get_property(np, "linux,phandle", &sz);
|
||||||
|
if (IS_ENABLED(PPC_PSERIES) && !phandle)
|
||||||
|
phandle = __of_get_property(np, "ibm,phandle", &sz);
|
||||||
|
np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
|
||||||
|
|
||||||
np->child = NULL;
|
np->child = NULL;
|
||||||
np->sibling = np->parent->child;
|
np->sibling = np->parent->child;
|
||||||
np->allnext = np->parent->allnext;
|
np->allnext = np->parent->allnext;
|
||||||
|
@ -63,6 +63,8 @@ static inline int of_property_notify(int action, struct device_node *np,
|
|||||||
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
|
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
|
||||||
struct device_node *__of_node_alloc(const char *full_name, gfp_t allocflags);
|
struct device_node *__of_node_alloc(const char *full_name, gfp_t allocflags);
|
||||||
|
|
||||||
|
extern const void *__of_get_property(const struct device_node *np,
|
||||||
|
const char *name, int *lenp);
|
||||||
extern int __of_add_property(struct device_node *np, struct property *prop);
|
extern int __of_add_property(struct device_node *np, struct property *prop);
|
||||||
extern int __of_add_property_sysfs(struct device_node *np,
|
extern int __of_add_property_sysfs(struct device_node *np,
|
||||||
struct property *prop);
|
struct property *prop);
|
||||||
|
Loading…
Reference in New Issue
Block a user