[media] of: move graph helpers from drivers/media/v4l2-core to drivers/of
This patch moves the parsing helpers used to parse connected graphs in the device tree, like the video interface bindings documented in Documentation/devicetree/bindings/media/video-interfaces.txt, from drivers/media/v4l2-core/v4l2-of.c into drivers/of/base.c. This allows to reuse the same parser code from outside the V4L2 framework, most importantly from display drivers. The functions v4l2_of_get_next_endpoint, v4l2_of_get_remote_port, and v4l2_of_get_remote_port_parent are moved. They are renamed to of_graph_get_next_endpoint, of_graph_get_remote_port, and of_graph_get_remote_port_parent, respectively. Since there are not that many current users yet, switch all of them to the new functions right away. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Mauro Carvalho Chehab <m.chehab@samsung.com> Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
This commit is contained in:
		
					parent
					
						
							
								0414855fdc
							
						
					
				
			
			
				commit
				
					
						fd9fdb78a9
					
				
			
		
					 12 changed files with 182 additions and 153 deletions
				
			
		|  | @ -26,12 +26,12 @@ | ||||||
| #include <linux/videodev2.h> | #include <linux/videodev2.h> | ||||||
| #include <linux/uaccess.h> | #include <linux/uaccess.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| 
 | 
 | ||||||
| #include <media/adv7343.h> | #include <media/adv7343.h> | ||||||
| #include <media/v4l2-async.h> | #include <media/v4l2-async.h> | ||||||
| #include <media/v4l2-device.h> | #include <media/v4l2-device.h> | ||||||
| #include <media/v4l2-ctrls.h> | #include <media/v4l2-ctrls.h> | ||||||
| #include <media/v4l2-of.h> |  | ||||||
| 
 | 
 | ||||||
| #include "adv7343_regs.h" | #include "adv7343_regs.h" | ||||||
| 
 | 
 | ||||||
|  | @ -410,7 +410,7 @@ adv7343_get_pdata(struct i2c_client *client) | ||||||
| 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||||||
| 		return client->dev.platform_data; | 		return client->dev.platform_data; | ||||||
| 
 | 
 | ||||||
| 	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 	np = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||||||
| 	if (!np) | 	if (!np) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
| #include <linux/of_gpio.h> | #include <linux/of_gpio.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/pm.h> | #include <linux/pm.h> | ||||||
| #include <linux/regulator/consumer.h> | #include <linux/regulator/consumer.h> | ||||||
| #include <linux/slab.h> | #include <linux/slab.h> | ||||||
|  | @ -29,7 +30,6 @@ | ||||||
| #include <media/mt9p031.h> | #include <media/mt9p031.h> | ||||||
| #include <media/v4l2-ctrls.h> | #include <media/v4l2-ctrls.h> | ||||||
| #include <media/v4l2-device.h> | #include <media/v4l2-device.h> | ||||||
| #include <media/v4l2-of.h> |  | ||||||
| #include <media/v4l2-subdev.h> | #include <media/v4l2-subdev.h> | ||||||
| 
 | 
 | ||||||
| #include "aptina-pll.h" | #include "aptina-pll.h" | ||||||
|  | @ -943,7 +943,7 @@ mt9p031_get_pdata(struct i2c_client *client) | ||||||
| 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||||||
| 		return client->dev.platform_data; | 		return client->dev.platform_data; | ||||||
| 
 | 
 | ||||||
| 	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 	np = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||||||
| 	if (!np) | 	if (!np) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include <linux/media.h> | #include <linux/media.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/of_gpio.h> | #include <linux/of_gpio.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/regulator/consumer.h> | #include <linux/regulator/consumer.h> | ||||||
| #include <linux/slab.h> | #include <linux/slab.h> | ||||||
| 
 | 
 | ||||||
|  | @ -1855,7 +1856,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev) | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	node_ep = v4l2_of_get_next_endpoint(node, NULL); | 	node_ep = of_graph_get_next_endpoint(node, NULL); | ||||||
| 	if (!node_ep) { | 	if (!node_ep) { | ||||||
| 		dev_err(dev, "no endpoint defined at node %s\n", | 		dev_err(dev, "no endpoint defined at node %s\n", | ||||||
| 			node->full_name); | 			node->full_name); | ||||||
|  |  | ||||||
|  | @ -36,6 +36,7 @@ | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/v4l2-mediabus.h> | #include <linux/v4l2-mediabus.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| 
 | 
 | ||||||
| #include <media/v4l2-async.h> | #include <media/v4l2-async.h> | ||||||
| #include <media/v4l2-device.h> | #include <media/v4l2-device.h> | ||||||
|  | @ -1068,7 +1069,7 @@ tvp514x_get_pdata(struct i2c_client *client) | ||||||
| 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||||||
| 		return client->dev.platform_data; | 		return client->dev.platform_data; | ||||||
| 
 | 
 | ||||||
| 	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||||||
| 	if (!endpoint) | 	if (!endpoint) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ | ||||||
| #include <linux/videodev2.h> | #include <linux/videodev2.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/v4l2-dv-timings.h> | #include <linux/v4l2-dv-timings.h> | ||||||
| #include <media/tvp7002.h> | #include <media/tvp7002.h> | ||||||
| #include <media/v4l2-async.h> | #include <media/v4l2-async.h> | ||||||
|  | @ -957,7 +958,7 @@ tvp7002_get_pdata(struct i2c_client *client) | ||||||
| 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||||||
| 		return client->dev.platform_data; | 		return client->dev.platform_data; | ||||||
| 
 | 
 | ||||||
| 	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||||||
| 	if (!endpoint) | 	if (!endpoint) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -24,13 +24,13 @@ | ||||||
| #include <linux/i2c.h> | #include <linux/i2c.h> | ||||||
| #include <linux/of_irq.h> | #include <linux/of_irq.h> | ||||||
| #include <linux/of_address.h> | #include <linux/of_address.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/of_platform.h> | #include <linux/of_platform.h> | ||||||
| #include <linux/platform_device.h> | #include <linux/platform_device.h> | ||||||
| #include <linux/pm_runtime.h> | #include <linux/pm_runtime.h> | ||||||
| #include <linux/slab.h> | #include <linux/slab.h> | ||||||
| #include <linux/types.h> | #include <linux/types.h> | ||||||
| #include <linux/videodev2.h> | #include <linux/videodev2.h> | ||||||
| #include <media/v4l2-of.h> |  | ||||||
| #include <media/videobuf2-dma-contig.h> | #include <media/videobuf2-dma-contig.h> | ||||||
| 
 | 
 | ||||||
| #include "media-dev.h" | #include "media-dev.h" | ||||||
|  | @ -167,10 +167,10 @@ static int fimc_is_parse_sensor_config(struct fimc_is_sensor *sensor, | ||||||
| 	u32 tmp = 0; | 	u32 tmp = 0; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	np = v4l2_of_get_next_endpoint(np, NULL); | 	np = of_graph_get_next_endpoint(np, NULL); | ||||||
| 	if (!np) | 	if (!np) | ||||||
| 		return -ENXIO; | 		return -ENXIO; | ||||||
| 	np = v4l2_of_get_remote_port(np); | 	np = of_graph_get_remote_port(np); | ||||||
| 	if (!np) | 	if (!np) | ||||||
| 		return -ENXIO; | 		return -ENXIO; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
| #include <linux/of_platform.h> | #include <linux/of_platform.h> | ||||||
| #include <linux/of_device.h> | #include <linux/of_device.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/platform_device.h> | #include <linux/platform_device.h> | ||||||
| #include <linux/pm_runtime.h> | #include <linux/pm_runtime.h> | ||||||
| #include <linux/types.h> | #include <linux/types.h> | ||||||
|  | @ -473,7 +474,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, | ||||||
| 
 | 
 | ||||||
| 	pd->mux_id = (endpoint.port - 1) & 0x1; | 	pd->mux_id = (endpoint.port - 1) & 0x1; | ||||||
| 
 | 
 | ||||||
| 	rem = v4l2_of_get_remote_port_parent(ep); | 	rem = of_graph_get_remote_port_parent(ep); | ||||||
| 	of_node_put(ep); | 	of_node_put(ep); | ||||||
| 	if (rem == NULL) { | 	if (rem == NULL) { | ||||||
| 		v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", | 		v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| #include <linux/memory.h> | #include <linux/memory.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/phy/phy.h> | #include <linux/phy/phy.h> | ||||||
| #include <linux/platform_data/mipi-csis.h> | #include <linux/platform_data/mipi-csis.h> | ||||||
| #include <linux/platform_device.h> | #include <linux/platform_device.h> | ||||||
|  | @ -762,7 +763,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, | ||||||
| 				 &state->max_num_lanes)) | 				 &state->max_num_lanes)) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	node = v4l2_of_get_next_endpoint(node, NULL); | 	node = of_graph_get_next_endpoint(node, NULL); | ||||||
| 	if (!node) { | 	if (!node) { | ||||||
| 		dev_err(&pdev->dev, "No port node at %s\n", | 		dev_err(&pdev->dev, "No port node at %s\n", | ||||||
| 				pdev->dev.of_node->full_name); | 				pdev->dev.of_node->full_name); | ||||||
|  |  | ||||||
|  | @ -152,120 +152,3 @@ int v4l2_of_parse_endpoint(const struct device_node *node, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(v4l2_of_parse_endpoint); | EXPORT_SYMBOL(v4l2_of_parse_endpoint); | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * v4l2_of_get_next_endpoint() - get next endpoint node |  | ||||||
|  * @parent: pointer to the parent device node |  | ||||||
|  * @prev: previous endpoint node, or NULL to get first |  | ||||||
|  * |  | ||||||
|  * Return: An 'endpoint' node pointer with refcount incremented. Refcount |  | ||||||
|  * of the passed @prev node is not decremented, the caller have to use |  | ||||||
|  * of_node_put() on it when done. |  | ||||||
|  */ |  | ||||||
| struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent, |  | ||||||
| 					struct device_node *prev) |  | ||||||
| { |  | ||||||
| 	struct device_node *endpoint; |  | ||||||
| 	struct device_node *port = NULL; |  | ||||||
| 
 |  | ||||||
| 	if (!parent) |  | ||||||
| 		return NULL; |  | ||||||
| 
 |  | ||||||
| 	if (!prev) { |  | ||||||
| 		struct device_node *node; |  | ||||||
| 		/*
 |  | ||||||
| 		 * It's the first call, we have to find a port subnode |  | ||||||
| 		 * within this node or within an optional 'ports' node. |  | ||||||
| 		 */ |  | ||||||
| 		node = of_get_child_by_name(parent, "ports"); |  | ||||||
| 		if (node) |  | ||||||
| 			parent = node; |  | ||||||
| 
 |  | ||||||
| 		port = of_get_child_by_name(parent, "port"); |  | ||||||
| 
 |  | ||||||
| 		if (port) { |  | ||||||
| 			/* Found a port, get an endpoint. */ |  | ||||||
| 			endpoint = of_get_next_child(port, NULL); |  | ||||||
| 			of_node_put(port); |  | ||||||
| 		} else { |  | ||||||
| 			endpoint = NULL; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (!endpoint) |  | ||||||
| 			pr_err("%s(): no endpoint nodes specified for %s\n", |  | ||||||
| 			       __func__, parent->full_name); |  | ||||||
| 		of_node_put(node); |  | ||||||
| 	} else { |  | ||||||
| 		port = of_get_parent(prev); |  | ||||||
| 		if (!port) |  | ||||||
| 			/* Hm, has someone given us the root node ?... */ |  | ||||||
| 			return NULL; |  | ||||||
| 
 |  | ||||||
| 		/* Avoid dropping prev node refcount to 0. */ |  | ||||||
| 		of_node_get(prev); |  | ||||||
| 		endpoint = of_get_next_child(port, prev); |  | ||||||
| 		if (endpoint) { |  | ||||||
| 			of_node_put(port); |  | ||||||
| 			return endpoint; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		/* No more endpoints under this port, try the next one. */ |  | ||||||
| 		do { |  | ||||||
| 			port = of_get_next_child(parent, port); |  | ||||||
| 			if (!port) |  | ||||||
| 				return NULL; |  | ||||||
| 		} while (of_node_cmp(port->name, "port")); |  | ||||||
| 
 |  | ||||||
| 		/* Pick up the first endpoint in this port. */ |  | ||||||
| 		endpoint = of_get_next_child(port, NULL); |  | ||||||
| 		of_node_put(port); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return endpoint; |  | ||||||
| } |  | ||||||
| EXPORT_SYMBOL(v4l2_of_get_next_endpoint); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * v4l2_of_get_remote_port_parent() - get remote port's parent node |  | ||||||
|  * @node: pointer to a local endpoint device_node |  | ||||||
|  * |  | ||||||
|  * Return: Remote device node associated with remote endpoint node linked |  | ||||||
|  *	   to @node. Use of_node_put() on it when done. |  | ||||||
|  */ |  | ||||||
| struct device_node *v4l2_of_get_remote_port_parent( |  | ||||||
| 			       const struct device_node *node) |  | ||||||
| { |  | ||||||
| 	struct device_node *np; |  | ||||||
| 	unsigned int depth; |  | ||||||
| 
 |  | ||||||
| 	/* Get remote endpoint node. */ |  | ||||||
| 	np = of_parse_phandle(node, "remote-endpoint", 0); |  | ||||||
| 
 |  | ||||||
| 	/* Walk 3 levels up only if there is 'ports' node. */ |  | ||||||
| 	for (depth = 3; depth && np; depth--) { |  | ||||||
| 		np = of_get_next_parent(np); |  | ||||||
| 		if (depth == 2 && of_node_cmp(np->name, "ports")) |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 	return np; |  | ||||||
| } |  | ||||||
| EXPORT_SYMBOL(v4l2_of_get_remote_port_parent); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * v4l2_of_get_remote_port() - get remote port node |  | ||||||
|  * @node: pointer to a local endpoint device_node |  | ||||||
|  * |  | ||||||
|  * Return: Remote port node associated with remote endpoint node linked |  | ||||||
|  *	   to @node. Use of_node_put() on it when done. |  | ||||||
|  */ |  | ||||||
| struct device_node *v4l2_of_get_remote_port(const struct device_node *node) |  | ||||||
| { |  | ||||||
| 	struct device_node *np; |  | ||||||
| 
 |  | ||||||
| 	/* Get remote endpoint node. */ |  | ||||||
| 	np = of_parse_phandle(node, "remote-endpoint", 0); |  | ||||||
| 	if (!np) |  | ||||||
| 		return NULL; |  | ||||||
| 	return of_get_next_parent(np); |  | ||||||
| } |  | ||||||
| EXPORT_SYMBOL(v4l2_of_get_remote_port); |  | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include <linux/cpu.h> | #include <linux/cpu.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| #include <linux/spinlock.h> | #include <linux/spinlock.h> | ||||||
| #include <linux/slab.h> | #include <linux/slab.h> | ||||||
| #include <linux/proc_fs.h> | #include <linux/proc_fs.h> | ||||||
|  | @ -1982,3 +1983,120 @@ struct device_node *of_find_next_cache_node(const struct device_node *np) | ||||||
| 
 | 
 | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * of_graph_get_next_endpoint() - get next endpoint node | ||||||
|  |  * @parent: pointer to the parent device node | ||||||
|  |  * @prev: previous endpoint node, or NULL to get first | ||||||
|  |  * | ||||||
|  |  * Return: An 'endpoint' node pointer with refcount incremented. Refcount | ||||||
|  |  * of the passed @prev node is not decremented, the caller have to use | ||||||
|  |  * of_node_put() on it when done. | ||||||
|  |  */ | ||||||
|  | struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | ||||||
|  | 					struct device_node *prev) | ||||||
|  | { | ||||||
|  | 	struct device_node *endpoint; | ||||||
|  | 	struct device_node *port = NULL; | ||||||
|  | 
 | ||||||
|  | 	if (!parent) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	if (!prev) { | ||||||
|  | 		struct device_node *node; | ||||||
|  | 		/*
 | ||||||
|  | 		 * It's the first call, we have to find a port subnode | ||||||
|  | 		 * within this node or within an optional 'ports' node. | ||||||
|  | 		 */ | ||||||
|  | 		node = of_get_child_by_name(parent, "ports"); | ||||||
|  | 		if (node) | ||||||
|  | 			parent = node; | ||||||
|  | 
 | ||||||
|  | 		port = of_get_child_by_name(parent, "port"); | ||||||
|  | 
 | ||||||
|  | 		if (port) { | ||||||
|  | 			/* Found a port, get an endpoint. */ | ||||||
|  | 			endpoint = of_get_next_child(port, NULL); | ||||||
|  | 			of_node_put(port); | ||||||
|  | 		} else { | ||||||
|  | 			endpoint = NULL; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!endpoint) | ||||||
|  | 			pr_err("%s(): no endpoint nodes specified for %s\n", | ||||||
|  | 			       __func__, parent->full_name); | ||||||
|  | 		of_node_put(node); | ||||||
|  | 	} else { | ||||||
|  | 		port = of_get_parent(prev); | ||||||
|  | 		if (!port) | ||||||
|  | 			/* Hm, has someone given us the root node ?... */ | ||||||
|  | 			return NULL; | ||||||
|  | 
 | ||||||
|  | 		/* Avoid dropping prev node refcount to 0. */ | ||||||
|  | 		of_node_get(prev); | ||||||
|  | 		endpoint = of_get_next_child(port, prev); | ||||||
|  | 		if (endpoint) { | ||||||
|  | 			of_node_put(port); | ||||||
|  | 			return endpoint; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* No more endpoints under this port, try the next one. */ | ||||||
|  | 		do { | ||||||
|  | 			port = of_get_next_child(parent, port); | ||||||
|  | 			if (!port) | ||||||
|  | 				return NULL; | ||||||
|  | 		} while (of_node_cmp(port->name, "port")); | ||||||
|  | 
 | ||||||
|  | 		/* Pick up the first endpoint in this port. */ | ||||||
|  | 		endpoint = of_get_next_child(port, NULL); | ||||||
|  | 		of_node_put(port); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return endpoint; | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(of_graph_get_next_endpoint); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * of_graph_get_remote_port_parent() - get remote port's parent node | ||||||
|  |  * @node: pointer to a local endpoint device_node | ||||||
|  |  * | ||||||
|  |  * Return: Remote device node associated with remote endpoint node linked | ||||||
|  |  *	   to @node. Use of_node_put() on it when done. | ||||||
|  |  */ | ||||||
|  | struct device_node *of_graph_get_remote_port_parent( | ||||||
|  | 			       const struct device_node *node) | ||||||
|  | { | ||||||
|  | 	struct device_node *np; | ||||||
|  | 	unsigned int depth; | ||||||
|  | 
 | ||||||
|  | 	/* Get remote endpoint node. */ | ||||||
|  | 	np = of_parse_phandle(node, "remote-endpoint", 0); | ||||||
|  | 
 | ||||||
|  | 	/* Walk 3 levels up only if there is 'ports' node. */ | ||||||
|  | 	for (depth = 3; depth && np; depth--) { | ||||||
|  | 		np = of_get_next_parent(np); | ||||||
|  | 		if (depth == 2 && of_node_cmp(np->name, "ports")) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	return np; | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(of_graph_get_remote_port_parent); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * of_graph_get_remote_port() - get remote port node | ||||||
|  |  * @node: pointer to a local endpoint device_node | ||||||
|  |  * | ||||||
|  |  * Return: Remote port node associated with remote endpoint node linked | ||||||
|  |  *	   to @node. Use of_node_put() on it when done. | ||||||
|  |  */ | ||||||
|  | struct device_node *of_graph_get_remote_port(const struct device_node *node) | ||||||
|  | { | ||||||
|  | 	struct device_node *np; | ||||||
|  | 
 | ||||||
|  | 	/* Get remote endpoint node. */ | ||||||
|  | 	np = of_parse_phandle(node, "remote-endpoint", 0); | ||||||
|  | 	if (!np) | ||||||
|  | 		return NULL; | ||||||
|  | 	return of_get_next_parent(np); | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(of_graph_get_remote_port); | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								include/linux/of_graph.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								include/linux/of_graph.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | /*
 | ||||||
|  |  * OF graph binding parsing helpers | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd. | ||||||
|  |  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2012 Renesas Electronics Corp. | ||||||
|  |  * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or modify | ||||||
|  |  * it under the terms of version 2 of the GNU General Public License as | ||||||
|  |  * published by the Free Software Foundation. | ||||||
|  |  */ | ||||||
|  | #ifndef __LINUX_OF_GRAPH_H | ||||||
|  | #define __LINUX_OF_GRAPH_H | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_OF | ||||||
|  | struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | ||||||
|  | 					struct device_node *previous); | ||||||
|  | struct device_node *of_graph_get_remote_port_parent( | ||||||
|  | 					const struct device_node *node); | ||||||
|  | struct device_node *of_graph_get_remote_port(const struct device_node *node); | ||||||
|  | #else | ||||||
|  | 
 | ||||||
|  | static inline struct device_node *of_graph_get_next_endpoint( | ||||||
|  | 					const struct device_node *parent, | ||||||
|  | 					struct device_node *previous) | ||||||
|  | { | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline struct device_node *of_graph_get_remote_port_parent( | ||||||
|  | 					const struct device_node *node) | ||||||
|  | { | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline struct device_node *of_graph_get_remote_port( | ||||||
|  | 					const struct device_node *node) | ||||||
|  | { | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* CONFIG_OF */ | ||||||
|  | 
 | ||||||
|  | #endif /* __LINUX_OF_GRAPH_H */ | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| #include <linux/list.h> | #include <linux/list.h> | ||||||
| #include <linux/types.h> | #include <linux/types.h> | ||||||
| #include <linux/errno.h> | #include <linux/errno.h> | ||||||
|  | #include <linux/of_graph.h> | ||||||
| 
 | 
 | ||||||
| #include <media/v4l2-mediabus.h> | #include <media/v4l2-mediabus.h> | ||||||
| 
 | 
 | ||||||
|  | @ -72,11 +73,6 @@ struct v4l2_of_endpoint { | ||||||
| #ifdef CONFIG_OF | #ifdef CONFIG_OF | ||||||
| int v4l2_of_parse_endpoint(const struct device_node *node, | int v4l2_of_parse_endpoint(const struct device_node *node, | ||||||
| 			   struct v4l2_of_endpoint *endpoint); | 			   struct v4l2_of_endpoint *endpoint); | ||||||
| struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent, |  | ||||||
| 					struct device_node *previous); |  | ||||||
| struct device_node *v4l2_of_get_remote_port_parent( |  | ||||||
| 					const struct device_node *node); |  | ||||||
| struct device_node *v4l2_of_get_remote_port(const struct device_node *node); |  | ||||||
| #else /* CONFIG_OF */ | #else /* CONFIG_OF */ | ||||||
| 
 | 
 | ||||||
| static inline int v4l2_of_parse_endpoint(const struct device_node *node, | static inline int v4l2_of_parse_endpoint(const struct device_node *node, | ||||||
|  | @ -85,25 +81,6 @@ static inline int v4l2_of_parse_endpoint(const struct device_node *node, | ||||||
| 	return -ENOSYS; | 	return -ENOSYS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline struct device_node *v4l2_of_get_next_endpoint( |  | ||||||
| 					const struct device_node *parent, |  | ||||||
| 					struct device_node *previous) |  | ||||||
| { |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline struct device_node *v4l2_of_get_remote_port_parent( |  | ||||||
| 					const struct device_node *node) |  | ||||||
| { |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline struct device_node *v4l2_of_get_remote_port( |  | ||||||
| 					const struct device_node *node) |  | ||||||
| { |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #endif /* CONFIG_OF */ | #endif /* CONFIG_OF */ | ||||||
| 
 | 
 | ||||||
| #endif /* _V4L2_OF_H */ | #endif /* _V4L2_OF_H */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Philipp Zabel
				Philipp Zabel