Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e81b3295 authored by Nathan Fontenot's avatar Nathan Fontenot Committed by Benjamin Herrenschmidt
Browse files

powerpc+of: Add /proc device tree updating to of node add/remove



When adding or removing a device tree node we should also update
the device tree in /proc/device-tree. This action is already done in the
generic OF code for adding/removing properties of a node. This patch adds
this functionality for nodes.

Signed-off-by: default avatarNathan Fontenot <nfont@linux.vnet.ibm.com>
Acked-by: default avatarRob Herring <rob.herring@calxeda.com>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 83dac594
Loading
Loading
Loading
Loading
+0 −24
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/cpu.h>
#include <linux/slab.h>
@@ -255,9 +254,6 @@ static struct device_node *derive_parent(const char *path)

int dlpar_attach_node(struct device_node *dn)
{
#ifdef CONFIG_PROC_DEVICETREE
	struct proc_dir_entry *ent;
#endif
	int rc;

	of_node_set_flag(dn, OF_DYNAMIC);
@@ -274,32 +270,12 @@ int dlpar_attach_node(struct device_node *dn)
	}

	of_attach_node(dn);

#ifdef CONFIG_PROC_DEVICETREE
	ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
	if (ent)
		proc_device_tree_add_node(dn, ent);
#endif

	of_node_put(dn->parent);
	return 0;
}

int dlpar_detach_node(struct device_node *dn)
{
#ifdef CONFIG_PROC_DEVICETREE
	struct device_node *parent = dn->parent;
	struct property *prop = dn->properties;

	while (prop) {
		remove_proc_entry(prop->name, dn->pde);
		prop = prop->next;
	}

	if (dn->pde)
		remove_proc_entry(dn->pde->name, parent->pde);
#endif

	pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, dn);
	of_detach_node(dn);
	of_node_put(dn); /* Must decrement the refcount */
+0 −47
Original line number Diff line number Diff line
@@ -23,48 +23,6 @@
#include <asm/pSeries_reconfig.h>
#include <asm/mmu.h>



/*
 * Routines for "runtime" addition and removal of device tree nodes.
 */
#ifdef CONFIG_PROC_DEVICETREE
/*
 * Add a node to /proc/device-tree.
 */
static void add_node_proc_entries(struct device_node *np)
{
	struct proc_dir_entry *ent;

	ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
	if (ent)
		proc_device_tree_add_node(np, ent);
}

static void remove_node_proc_entries(struct device_node *np)
{
	struct property *pp = np->properties;
	struct device_node *parent = np->parent;

	while (pp) {
		remove_proc_entry(pp->name, np->pde);
		pp = pp->next;
	}
	if (np->pde)
		remove_proc_entry(np->pde->name, parent->pde);
}
#else /* !CONFIG_PROC_DEVICETREE */
static void add_node_proc_entries(struct device_node *np)
{
	return;
}

static void remove_node_proc_entries(struct device_node *np)
{
	return;
}
#endif /* CONFIG_PROC_DEVICETREE */

/**
 *	derive_parent - basically like dirname(1)
 *	@path:  the full_name of a node to be added to the tree
@@ -149,9 +107,6 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
	}

	of_attach_node(np);

	add_node_proc_entries(np);

	of_node_put(np->parent);

	return 0;
@@ -179,8 +134,6 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
		return -EBUSY;
	}

	remove_node_proc_entries(np);

	pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, np);
	of_detach_node(np);

+51 −4
Original line number Diff line number Diff line
@@ -1160,6 +1160,22 @@ int prom_update_property(struct device_node *np,
 * device tree nodes.
 */

#ifdef CONFIG_PROC_DEVICETREE
static void of_add_proc_dt_entry(struct device_node *dn)
{
	struct proc_dir_entry *ent;

	ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
	if (ent)
		proc_device_tree_add_node(dn, ent);
}
#else
static void of_add_proc_dt_entry(struct device_node *dn)
{
	return;
}
#endif

/**
 * of_attach_node - Plug a device node into the tree and global list.
 */
@@ -1173,8 +1189,31 @@ void of_attach_node(struct device_node *np)
	np->parent->child = np;
	allnodes = np;
	write_unlock_irqrestore(&devtree_lock, flags);

	of_add_proc_dt_entry(np);
}

#ifdef CONFIG_PROC_DEVICETREE
static void of_remove_proc_dt_entry(struct device_node *dn)
{
	struct device_node *parent = dn->parent;
	struct property *prop = dn->properties;

	while (prop) {
		remove_proc_entry(prop->name, dn->pde);
		prop = prop->next;
	}

	if (dn->pde)
		remove_proc_entry(dn->pde->name, parent->pde);
}
#else
static void of_remove_proc_dt_entry(struct device_node *dn)
{
	return;
}
#endif

/**
 * of_detach_node - "Unplug" a node from the device tree.
 *
@@ -1188,9 +1227,17 @@ void of_detach_node(struct device_node *np)

	write_lock_irqsave(&devtree_lock, flags);

	if (of_node_check_flag(np, OF_DETACHED)) {
		/* someone already detached it */
		write_unlock_irqrestore(&devtree_lock, flags);
		return;
	}

	parent = np->parent;
	if (!parent)
		goto out_unlock;
	if (!parent) {
		write_unlock_irqrestore(&devtree_lock, flags);
		return;
	}

	if (allnodes == np)
		allnodes = np->allnext;
@@ -1215,9 +1262,9 @@ void of_detach_node(struct device_node *np)
	}

	of_node_set_flag(np, OF_DETACHED);

out_unlock:
	write_unlock_irqrestore(&devtree_lock, flags);

	of_remove_proc_dt_entry(np);
}
#endif /* defined(CONFIG_OF_DYNAMIC) */