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

Commit aa10537f authored by Rob Herring's avatar Rob Herring
Browse files

Merge tag 'dt-for-robh' of git://git.secretlab.ca/git/linux into for-next

Pull DT changes from Grant Likely:

DT queued up for v3.16

Mostly bug fixes, but also some rework to improve path handling and device naming
parents eafd370d 08cf78ed
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -51,10 +51,6 @@ static inline void dcr_write_mmio(dcr_host_mmio_t host,
	out_be32(host.token + ((host.base + dcr_n) * host.stride), value);
}

extern u64 of_translate_dcr_address(struct device_node *dev,
				    unsigned int dcr_n,
				    unsigned int *stride);

#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_DCR_MMIO_H */

+3 −3
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(dcr_resource_len);

#ifdef CONFIG_PPC_DCR_MMIO

u64 of_translate_dcr_address(struct device_node *dev,
static u64 of_translate_dcr_address(struct device_node *dev,
				    unsigned int dcr_n,
				    unsigned int *out_stride)
{
+5 −2
Original line number Diff line number Diff line
@@ -131,9 +131,12 @@ EXPORT_SYMBOL_GPL(platform_get_resource_byname);
 */
int platform_get_irq_byname(struct platform_device *dev, const char *name)
{
	struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ,
							  name);
	struct resource *r;

	if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
		return of_irq_get_byname(dev->dev.of_node, name);

	r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
	return r ? r->start : -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq_byname);
+93 −22
Original line number Diff line number Diff line
@@ -695,6 +695,22 @@ struct device_node *of_get_next_parent(struct device_node *node)
}
EXPORT_SYMBOL(of_get_next_parent);

static struct device_node *__of_get_next_child(const struct device_node *node,
						struct device_node *prev)
{
	struct device_node *next;

	next = prev ? prev->sibling : node->child;
	for (; next; next = next->sibling)
		if (of_node_get(next))
			break;
	of_node_put(prev);
	return next;
}
#define __for_each_child_of_node(parent, child) \
	for (child = __of_get_next_child(parent, NULL); child != NULL; \
	     child = __of_get_next_child(parent, child))

/**
 *	of_get_next_child - Iterate a node childs
 *	@node:	parent node
@@ -710,11 +726,7 @@ struct device_node *of_get_next_child(const struct device_node *node,
	unsigned long flags;

	raw_spin_lock_irqsave(&devtree_lock, flags);
	next = prev ? prev->sibling : node->child;
	for (; next; next = next->sibling)
		if (of_node_get(next))
			break;
	of_node_put(prev);
	next = __of_get_next_child(node, prev);
	raw_spin_unlock_irqrestore(&devtree_lock, flags);
	return next;
}
@@ -771,24 +783,79 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_child_by_name);

static struct device_node *__of_find_node_by_path(struct device_node *parent,
						const char *path)
{
	struct device_node *child;
	int len = strchrnul(path, '/') - path;

	if (!len)
		return NULL;

	__for_each_child_of_node(parent, child) {
		const char *name = strrchr(child->full_name, '/');
		if (WARN(!name, "malformed device_node %s\n", child->full_name))
			continue;
		name++;
		if (strncmp(path, name, len) == 0 && (strlen(name) == len))
			return child;
	}
	return NULL;
}

/**
 *	of_find_node_by_path - Find a node matching a full OF path
 *	@path:	The full path to match
 *	@path: Either the full path to match, or if the path does not
 *	       start with '/', the name of a property of the /aliases
 *	       node (an alias).  In the case of an alias, the node
 *	       matching the alias' value will be returned.
 *
 *	Valid paths:
 *		/foo/bar	Full path
 *		foo		Valid alias
 *		foo/bar		Valid alias + relative path
 *
 *	Returns a node pointer with refcount incremented, use
 *	of_node_put() on it when done.
 */
struct device_node *of_find_node_by_path(const char *path)
{
	struct device_node *np = of_allnodes;
	struct device_node *np = NULL;
	struct property *pp;
	unsigned long flags;

	raw_spin_lock_irqsave(&devtree_lock, flags);
	for (; np; np = np->allnext) {
		if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
		    && of_node_get(np))
	if (strcmp(path, "/") == 0)
		return of_node_get(of_allnodes);

	/* The path could begin with an alias */
	if (*path != '/') {
		char *p = strchrnul(path, '/');
		int len = p - path;

		/* of_aliases must not be NULL */
		if (!of_aliases)
			return NULL;

		for_each_property_of_node(of_aliases, pp) {
			if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
				np = of_find_node_by_path(pp->value);
				break;
			}
		}
		if (!np)
			return NULL;
		path = p;
	}

	/* Step down the tree matching path components */
	raw_spin_lock_irqsave(&devtree_lock, flags);
	if (!np)
		np = of_node_get(of_allnodes);
	while (np && *path == '/') {
		path++; /* Increment past '/' delimiter */
		np = __of_find_node_by_path(np, path);
		path = strchrnul(path, '/');
	}
	raw_spin_unlock_irqrestore(&devtree_lock, flags);
	return np;
}
@@ -1800,7 +1867,7 @@ int of_update_property(struct device_node *np, struct property *newprop)
{
	struct property **next, *oldprop;
	unsigned long flags;
	int rc, found = 0;
	int rc;

	rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
	if (rc)
@@ -1809,29 +1876,33 @@ int of_update_property(struct device_node *np, struct property *newprop)
	if (!newprop->name)
		return -EINVAL;

	oldprop = of_find_property(np, newprop->name, NULL);
	if (!oldprop)
		return of_add_property(np, newprop);

	raw_spin_lock_irqsave(&devtree_lock, flags);
	next = &np->properties;
	while (*next) {
	oldprop = __of_find_property(np, newprop->name, NULL);
	if (!oldprop) {
		/* add the new node */
		rc = __of_add_property(np, newprop);
	} else while (*next) {
		/* replace the node */
		if (*next == oldprop) {
			/* found the node */
			newprop->next = oldprop->next;
			*next = newprop;
			oldprop->next = np->deadprops;
			np->deadprops = oldprop;
			found = 1;
			break;
		}
		next = &(*next)->next;
	}
	raw_spin_unlock_irqrestore(&devtree_lock, flags);
	if (!found)
		return -ENODEV;
	if (rc)
		return rc;

	/* At early boot, bail out and defer setup to of_init() */
	if (!of_kset)
		return 0;

	/* Update the sysfs attribute */
	if (oldprop)
		sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
	__of_add_property_sysfs(np, newprop);

+2 −2
Original line number Diff line number Diff line
@@ -324,7 +324,7 @@ static void __unflatten_device_tree(void *blob,

	/* First pass, scan for size */
	start = 0;
	size = (unsigned long)unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
	size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0);
	size = ALIGN(size, 4);

	pr_debug("  size is %lx, allocating...\n", size);
@@ -748,7 +748,7 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
		 * The longtrail doesn't have a device_type on the
		 * /memory node, so look for the node called /memory@0.
		 */
		if (depth != 1 || strcmp(uname, "memory@0") != 0)
		if (!IS_ENABLED(CONFIG_PPC32) || depth != 1 || strcmp(uname, "memory@0") != 0)
			return 0;
	} else if (strcmp(type, "memory") != 0)
		return 0;
Loading