diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2014-02-10 16:01:48 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2014-03-06 11:41:22 -0500 |
commit | fd9fdb78a9bf85b94fb2190c82ff280c8f8375cc (patch) | |
tree | 49ad197ab19b401edbc4957b5ce2ed53af643b09 | |
parent | 0414855fdc4a40da05221fc6062cccbc0c30f169 (diff) |
[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>
-rw-r--r-- | drivers/media/i2c/adv7343.c | 4 | ||||
-rw-r--r-- | drivers/media/i2c/mt9p031.c | 4 | ||||
-rw-r--r-- | drivers/media/i2c/s5k5baf.c | 3 | ||||
-rw-r--r-- | drivers/media/i2c/tvp514x.c | 3 | ||||
-rw-r--r-- | drivers/media/i2c/tvp7002.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-is.c | 6 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/mipi-csis.c | 3 | ||||
-rw-r--r-- | drivers/media/v4l2-core/v4l2-of.c | 117 | ||||
-rw-r--r-- | drivers/of/base.c | 118 | ||||
-rw-r--r-- | include/linux/of_graph.h | 46 | ||||
-rw-r--r-- | include/media/v4l2-of.h | 25 |
12 files changed, 182 insertions, 153 deletions
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c index d4e15a617c3b..9d38f7b36cd1 100644 --- a/drivers/media/i2c/adv7343.c +++ b/drivers/media/i2c/adv7343.c | |||
@@ -26,12 +26,12 @@ | |||
26 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/of.h> | 28 | #include <linux/of.h> |
29 | #include <linux/of_graph.h> | ||
29 | 30 | ||
30 | #include <media/adv7343.h> | 31 | #include <media/adv7343.h> |
31 | #include <media/v4l2-async.h> | 32 | #include <media/v4l2-async.h> |
32 | #include <media/v4l2-device.h> | 33 | #include <media/v4l2-device.h> |
33 | #include <media/v4l2-ctrls.h> | 34 | #include <media/v4l2-ctrls.h> |
34 | #include <media/v4l2-of.h> | ||
35 | 35 | ||
36 | #include "adv7343_regs.h" | 36 | #include "adv7343_regs.h" |
37 | 37 | ||
@@ -410,7 +410,7 @@ adv7343_get_pdata(struct i2c_client *client) | |||
410 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 410 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) |
411 | return client->dev.platform_data; | 411 | return client->dev.platform_data; |
412 | 412 | ||
413 | np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 413 | np = of_graph_get_next_endpoint(client->dev.of_node, NULL); |
414 | if (!np) | 414 | if (!np) |
415 | return NULL; | 415 | return NULL; |
416 | 416 | ||
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index e5ddf47030fd..192c4aad05d6 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_gpio.h> | 23 | #include <linux/of_gpio.h> |
24 | #include <linux/of_graph.h> | ||
24 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
25 | #include <linux/regulator/consumer.h> | 26 | #include <linux/regulator/consumer.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
@@ -29,7 +30,6 @@ | |||
29 | #include <media/mt9p031.h> | 30 | #include <media/mt9p031.h> |
30 | #include <media/v4l2-ctrls.h> | 31 | #include <media/v4l2-ctrls.h> |
31 | #include <media/v4l2-device.h> | 32 | #include <media/v4l2-device.h> |
32 | #include <media/v4l2-of.h> | ||
33 | #include <media/v4l2-subdev.h> | 33 | #include <media/v4l2-subdev.h> |
34 | 34 | ||
35 | #include "aptina-pll.h" | 35 | #include "aptina-pll.h" |
@@ -943,7 +943,7 @@ mt9p031_get_pdata(struct i2c_client *client) | |||
943 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 943 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) |
944 | return client->dev.platform_data; | 944 | return client->dev.platform_data; |
945 | 945 | ||
946 | np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 946 | np = of_graph_get_next_endpoint(client->dev.of_node, NULL); |
947 | if (!np) | 947 | if (!np) |
948 | return NULL; | 948 | return NULL; |
949 | 949 | ||
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 77e10e0fd8d6..2d768ef67cc5 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/media.h> | 21 | #include <linux/media.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/of_gpio.h> | 23 | #include <linux/of_gpio.h> |
24 | #include <linux/of_graph.h> | ||
24 | #include <linux/regulator/consumer.h> | 25 | #include <linux/regulator/consumer.h> |
25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
26 | 27 | ||
@@ -1855,7 +1856,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev) | |||
1855 | if (ret < 0) | 1856 | if (ret < 0) |
1856 | return ret; | 1857 | return ret; |
1857 | 1858 | ||
1858 | node_ep = v4l2_of_get_next_endpoint(node, NULL); | 1859 | node_ep = of_graph_get_next_endpoint(node, NULL); |
1859 | if (!node_ep) { | 1860 | if (!node_ep) { |
1860 | dev_err(dev, "no endpoint defined at node %s\n", | 1861 | dev_err(dev, "no endpoint defined at node %s\n", |
1861 | node->full_name); | 1862 | node->full_name); |
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 83d85df4853a..ca001178c5bf 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/v4l2-mediabus.h> | 37 | #include <linux/v4l2-mediabus.h> |
38 | #include <linux/of.h> | 38 | #include <linux/of.h> |
39 | #include <linux/of_graph.h> | ||
39 | 40 | ||
40 | #include <media/v4l2-async.h> | 41 | #include <media/v4l2-async.h> |
41 | #include <media/v4l2-device.h> | 42 | #include <media/v4l2-device.h> |
@@ -1068,7 +1069,7 @@ tvp514x_get_pdata(struct i2c_client *client) | |||
1068 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 1069 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) |
1069 | return client->dev.platform_data; | 1070 | return client->dev.platform_data; |
1070 | 1071 | ||
1071 | endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 1072 | endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL); |
1072 | if (!endpoint) | 1073 | if (!endpoint) |
1073 | return NULL; | 1074 | return NULL; |
1074 | 1075 | ||
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 912e1cccdd1c..c4e1e2cb3094 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/of.h> | 32 | #include <linux/of.h> |
33 | #include <linux/of_graph.h> | ||
33 | #include <linux/v4l2-dv-timings.h> | 34 | #include <linux/v4l2-dv-timings.h> |
34 | #include <media/tvp7002.h> | 35 | #include <media/tvp7002.h> |
35 | #include <media/v4l2-async.h> | 36 | #include <media/v4l2-async.h> |
@@ -957,7 +958,7 @@ tvp7002_get_pdata(struct i2c_client *client) | |||
957 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | 958 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) |
958 | return client->dev.platform_data; | 959 | return client->dev.platform_data; |
959 | 960 | ||
960 | endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL); | 961 | endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL); |
961 | if (!endpoint) | 962 | if (!endpoint) |
962 | return NULL; | 963 | return NULL; |
963 | 964 | ||
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 13a4228952e3..9bdfa4599bc3 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c | |||
@@ -24,13 +24,13 @@ | |||
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
26 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
27 | #include <linux/of_graph.h> | ||
27 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
28 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
29 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
31 | #include <linux/types.h> | 32 | #include <linux/types.h> |
32 | #include <linux/videodev2.h> | 33 | #include <linux/videodev2.h> |
33 | #include <media/v4l2-of.h> | ||
34 | #include <media/videobuf2-dma-contig.h> | 34 | #include <media/videobuf2-dma-contig.h> |
35 | 35 | ||
36 | #include "media-dev.h" | 36 | #include "media-dev.h" |
@@ -167,10 +167,10 @@ static int fimc_is_parse_sensor_config(struct fimc_is_sensor *sensor, | |||
167 | u32 tmp = 0; | 167 | u32 tmp = 0; |
168 | int ret; | 168 | int ret; |
169 | 169 | ||
170 | np = v4l2_of_get_next_endpoint(np, NULL); | 170 | np = of_graph_get_next_endpoint(np, NULL); |
171 | if (!np) | 171 | if (!np) |
172 | return -ENXIO; | 172 | return -ENXIO; |
173 | np = v4l2_of_get_remote_port(np); | 173 | np = of_graph_get_remote_port(np); |
174 | if (!np) | 174 | if (!np) |
175 | return -ENXIO; | 175 | return -ENXIO; |
176 | 176 | ||
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index c1bce170df6f..d0f82da59ac5 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
22 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
23 | #include <linux/of_graph.h> | ||
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
25 | #include <linux/types.h> | 26 | #include <linux/types.h> |
@@ -473,7 +474,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, | |||
473 | 474 | ||
474 | pd->mux_id = (endpoint.port - 1) & 0x1; | 475 | pd->mux_id = (endpoint.port - 1) & 0x1; |
475 | 476 | ||
476 | rem = v4l2_of_get_remote_port_parent(ep); | 477 | rem = of_graph_get_remote_port_parent(ep); |
477 | of_node_put(ep); | 478 | of_node_put(ep); |
478 | if (rem == NULL) { | 479 | if (rem == NULL) { |
479 | v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", | 480 | v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", |
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index f3c3591fdc5d..fd1ae6549607 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/memory.h> | 20 | #include <linux/memory.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_graph.h> | ||
23 | #include <linux/phy/phy.h> | 24 | #include <linux/phy/phy.h> |
24 | #include <linux/platform_data/mipi-csis.h> | 25 | #include <linux/platform_data/mipi-csis.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
@@ -762,7 +763,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, | |||
762 | &state->max_num_lanes)) | 763 | &state->max_num_lanes)) |
763 | return -EINVAL; | 764 | return -EINVAL; |
764 | 765 | ||
765 | node = v4l2_of_get_next_endpoint(node, NULL); | 766 | node = of_graph_get_next_endpoint(node, NULL); |
766 | if (!node) { | 767 | if (!node) { |
767 | dev_err(&pdev->dev, "No port node at %s\n", | 768 | dev_err(&pdev->dev, "No port node at %s\n", |
768 | pdev->dev.of_node->full_name); | 769 | pdev->dev.of_node->full_name); |
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c index 42e3e8a5e361..f919db358bbe 100644 --- a/drivers/media/v4l2-core/v4l2-of.c +++ b/drivers/media/v4l2-core/v4l2-of.c | |||
@@ -152,120 +152,3 @@ int v4l2_of_parse_endpoint(const struct device_node *node, | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | EXPORT_SYMBOL(v4l2_of_parse_endpoint); | 154 | EXPORT_SYMBOL(v4l2_of_parse_endpoint); |
155 | |||
156 | /** | ||
157 | * v4l2_of_get_next_endpoint() - get next endpoint node | ||
158 | * @parent: pointer to the parent device node | ||
159 | * @prev: previous endpoint node, or NULL to get first | ||
160 | * | ||
161 | * Return: An 'endpoint' node pointer with refcount incremented. Refcount | ||
162 | * of the passed @prev node is not decremented, the caller have to use | ||
163 | * of_node_put() on it when done. | ||
164 | */ | ||
165 | struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent, | ||
166 | struct device_node *prev) | ||
167 | { | ||
168 | struct device_node *endpoint; | ||
169 | struct device_node *port = NULL; | ||
170 | |||
171 | if (!parent) | ||
172 | return NULL; | ||
173 | |||
174 | if (!prev) { | ||
175 | struct device_node *node; | ||
176 | /* | ||
177 | * It's the first call, we have to find a port subnode | ||
178 | * within this node or within an optional 'ports' node. | ||
179 | */ | ||
180 | node = of_get_child_by_name(parent, "ports"); | ||
181 | if (node) | ||
182 | parent = node; | ||
183 | |||
184 | port = of_get_child_by_name(parent, "port"); | ||
185 | |||
186 | if (port) { | ||
187 | /* Found a port, get an endpoint. */ | ||
188 | endpoint = of_get_next_child(port, NULL); | ||
189 | of_node_put(port); | ||
190 | } else { | ||
191 | endpoint = NULL; | ||
192 | } | ||
193 | |||
194 | if (!endpoint) | ||
195 | pr_err("%s(): no endpoint nodes specified for %s\n", | ||
196 | __func__, parent->full_name); | ||
197 | of_node_put(node); | ||
198 | } else { | ||
199 | port = of_get_parent(prev); | ||
200 | if (!port) | ||
201 | /* Hm, has someone given us the root node ?... */ | ||
202 | return NULL; | ||
203 | |||
204 | /* Avoid dropping prev node refcount to 0. */ | ||
205 | of_node_get(prev); | ||
206 | endpoint = of_get_next_child(port, prev); | ||
207 | if (endpoint) { | ||
208 | of_node_put(port); | ||
209 | return endpoint; | ||
210 | } | ||
211 | |||
212 | /* No more endpoints under this port, try the next one. */ | ||
213 | do { | ||
214 | port = of_get_next_child(parent, port); | ||
215 | if (!port) | ||
216 | return NULL; | ||
217 | } while (of_node_cmp(port->name, "port")); | ||
218 | |||
219 | /* Pick up the first endpoint in this port. */ | ||
220 | endpoint = of_get_next_child(port, NULL); | ||
221 | of_node_put(port); | ||
222 | } | ||
223 | |||
224 | return endpoint; | ||
225 | } | ||
226 | EXPORT_SYMBOL(v4l2_of_get_next_endpoint); | ||
227 | |||
228 | /** | ||
229 | * v4l2_of_get_remote_port_parent() - get remote port's parent node | ||
230 | * @node: pointer to a local endpoint device_node | ||
231 | * | ||
232 | * Return: Remote device node associated with remote endpoint node linked | ||
233 | * to @node. Use of_node_put() on it when done. | ||
234 | */ | ||
235 | struct device_node *v4l2_of_get_remote_port_parent( | ||
236 | const struct device_node *node) | ||
237 | { | ||
238 | struct device_node *np; | ||
239 | unsigned int depth; | ||
240 | |||
241 | /* Get remote endpoint node. */ | ||
242 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
243 | |||
244 | /* Walk 3 levels up only if there is 'ports' node. */ | ||
245 | for (depth = 3; depth && np; depth--) { | ||
246 | np = of_get_next_parent(np); | ||
247 | if (depth == 2 && of_node_cmp(np->name, "ports")) | ||
248 | break; | ||
249 | } | ||
250 | return np; | ||
251 | } | ||
252 | EXPORT_SYMBOL(v4l2_of_get_remote_port_parent); | ||
253 | |||
254 | /** | ||
255 | * v4l2_of_get_remote_port() - get remote port node | ||
256 | * @node: pointer to a local endpoint device_node | ||
257 | * | ||
258 | * Return: Remote port node associated with remote endpoint node linked | ||
259 | * to @node. Use of_node_put() on it when done. | ||
260 | */ | ||
261 | struct device_node *v4l2_of_get_remote_port(const struct device_node *node) | ||
262 | { | ||
263 | struct device_node *np; | ||
264 | |||
265 | /* Get remote endpoint node. */ | ||
266 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
267 | if (!np) | ||
268 | return NULL; | ||
269 | return of_get_next_parent(np); | ||
270 | } | ||
271 | EXPORT_SYMBOL(v4l2_of_get_remote_port); | ||
diff --git a/drivers/of/base.c b/drivers/of/base.c index 89e888a78899..b2f223fa47e9 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/cpu.h> | 21 | #include <linux/cpu.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_graph.h> | ||
24 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
26 | #include <linux/proc_fs.h> | 27 | #include <linux/proc_fs.h> |
@@ -1982,3 +1983,120 @@ struct device_node *of_find_next_cache_node(const struct device_node *np) | |||
1982 | 1983 | ||
1983 | return NULL; | 1984 | return NULL; |
1984 | } | 1985 | } |
1986 | |||
1987 | /** | ||
1988 | * of_graph_get_next_endpoint() - get next endpoint node | ||
1989 | * @parent: pointer to the parent device node | ||
1990 | * @prev: previous endpoint node, or NULL to get first | ||
1991 | * | ||
1992 | * Return: An 'endpoint' node pointer with refcount incremented. Refcount | ||
1993 | * of the passed @prev node is not decremented, the caller have to use | ||
1994 | * of_node_put() on it when done. | ||
1995 | */ | ||
1996 | struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | ||
1997 | struct device_node *prev) | ||
1998 | { | ||
1999 | struct device_node *endpoint; | ||
2000 | struct device_node *port = NULL; | ||
2001 | |||
2002 | if (!parent) | ||
2003 | return NULL; | ||
2004 | |||
2005 | if (!prev) { | ||
2006 | struct device_node *node; | ||
2007 | /* | ||
2008 | * It's the first call, we have to find a port subnode | ||
2009 | * within this node or within an optional 'ports' node. | ||
2010 | */ | ||
2011 | node = of_get_child_by_name(parent, "ports"); | ||
2012 | if (node) | ||
2013 | parent = node; | ||
2014 | |||
2015 | port = of_get_child_by_name(parent, "port"); | ||
2016 | |||
2017 | if (port) { | ||
2018 | /* Found a port, get an endpoint. */ | ||
2019 | endpoint = of_get_next_child(port, NULL); | ||
2020 | of_node_put(port); | ||
2021 | } else { | ||
2022 | endpoint = NULL; | ||
2023 | } | ||
2024 | |||
2025 | if (!endpoint) | ||
2026 | pr_err("%s(): no endpoint nodes specified for %s\n", | ||
2027 | __func__, parent->full_name); | ||
2028 | of_node_put(node); | ||
2029 | } else { | ||
2030 | port = of_get_parent(prev); | ||
2031 | if (!port) | ||
2032 | /* Hm, has someone given us the root node ?... */ | ||
2033 | return NULL; | ||
2034 | |||
2035 | /* Avoid dropping prev node refcount to 0. */ | ||
2036 | of_node_get(prev); | ||
2037 | endpoint = of_get_next_child(port, prev); | ||
2038 | if (endpoint) { | ||
2039 | of_node_put(port); | ||
2040 | return endpoint; | ||
2041 | } | ||
2042 | |||
2043 | /* No more endpoints under this port, try the next one. */ | ||
2044 | do { | ||
2045 | port = of_get_next_child(parent, port); | ||
2046 | if (!port) | ||
2047 | return NULL; | ||
2048 | } while (of_node_cmp(port->name, "port")); | ||
2049 | |||
2050 | /* Pick up the first endpoint in this port. */ | ||
2051 | endpoint = of_get_next_child(port, NULL); | ||
2052 | of_node_put(port); | ||
2053 | } | ||
2054 | |||
2055 | return endpoint; | ||
2056 | } | ||
2057 | EXPORT_SYMBOL(of_graph_get_next_endpoint); | ||
2058 | |||
2059 | /** | ||
2060 | * of_graph_get_remote_port_parent() - get remote port's parent node | ||
2061 | * @node: pointer to a local endpoint device_node | ||
2062 | * | ||
2063 | * Return: Remote device node associated with remote endpoint node linked | ||
2064 | * to @node. Use of_node_put() on it when done. | ||
2065 | */ | ||
2066 | struct device_node *of_graph_get_remote_port_parent( | ||
2067 | const struct device_node *node) | ||
2068 | { | ||
2069 | struct device_node *np; | ||
2070 | unsigned int depth; | ||
2071 | |||
2072 | /* Get remote endpoint node. */ | ||
2073 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
2074 | |||
2075 | /* Walk 3 levels up only if there is 'ports' node. */ | ||
2076 | for (depth = 3; depth && np; depth--) { | ||
2077 | np = of_get_next_parent(np); | ||
2078 | if (depth == 2 && of_node_cmp(np->name, "ports")) | ||
2079 | break; | ||
2080 | } | ||
2081 | return np; | ||
2082 | } | ||
2083 | EXPORT_SYMBOL(of_graph_get_remote_port_parent); | ||
2084 | |||
2085 | /** | ||
2086 | * of_graph_get_remote_port() - get remote port node | ||
2087 | * @node: pointer to a local endpoint device_node | ||
2088 | * | ||
2089 | * Return: Remote port node associated with remote endpoint node linked | ||
2090 | * to @node. Use of_node_put() on it when done. | ||
2091 | */ | ||
2092 | struct device_node *of_graph_get_remote_port(const struct device_node *node) | ||
2093 | { | ||
2094 | struct device_node *np; | ||
2095 | |||
2096 | /* Get remote endpoint node. */ | ||
2097 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
2098 | if (!np) | ||
2099 | return NULL; | ||
2100 | return of_get_next_parent(np); | ||
2101 | } | ||
2102 | EXPORT_SYMBOL(of_graph_get_remote_port); | ||
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h new file mode 100644 index 000000000000..3bbeb609a360 --- /dev/null +++ b/include/linux/of_graph.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * OF graph binding parsing helpers | ||
3 | * | ||
4 | * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd. | ||
5 | * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> | ||
6 | * | ||
7 | * Copyright (C) 2012 Renesas Electronics Corp. | ||
8 | * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | #ifndef __LINUX_OF_GRAPH_H | ||
15 | #define __LINUX_OF_GRAPH_H | ||
16 | |||
17 | #ifdef CONFIG_OF | ||
18 | struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | ||
19 | struct device_node *previous); | ||
20 | struct device_node *of_graph_get_remote_port_parent( | ||
21 | const struct device_node *node); | ||
22 | struct device_node *of_graph_get_remote_port(const struct device_node *node); | ||
23 | #else | ||
24 | |||
25 | static inline struct device_node *of_graph_get_next_endpoint( | ||
26 | const struct device_node *parent, | ||
27 | struct device_node *previous) | ||
28 | { | ||
29 | return NULL; | ||
30 | } | ||
31 | |||
32 | static inline struct device_node *of_graph_get_remote_port_parent( | ||
33 | const struct device_node *node) | ||
34 | { | ||
35 | return NULL; | ||
36 | } | ||
37 | |||
38 | static inline struct device_node *of_graph_get_remote_port( | ||
39 | const struct device_node *node) | ||
40 | { | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | #endif /* CONFIG_OF */ | ||
45 | |||
46 | #endif /* __LINUX_OF_GRAPH_H */ | ||
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h index 541cea4122e9..3a49735c56a0 100644 --- a/include/media/v4l2-of.h +++ b/include/media/v4l2-of.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
20 | #include <linux/of_graph.h> | ||
20 | 21 | ||
21 | #include <media/v4l2-mediabus.h> | 22 | #include <media/v4l2-mediabus.h> |
22 | 23 | ||
@@ -72,11 +73,6 @@ struct v4l2_of_endpoint { | |||
72 | #ifdef CONFIG_OF | 73 | #ifdef CONFIG_OF |
73 | int v4l2_of_parse_endpoint(const struct device_node *node, | 74 | int v4l2_of_parse_endpoint(const struct device_node *node, |
74 | struct v4l2_of_endpoint *endpoint); | 75 | struct v4l2_of_endpoint *endpoint); |
75 | struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent, | ||
76 | struct device_node *previous); | ||
77 | struct device_node *v4l2_of_get_remote_port_parent( | ||
78 | const struct device_node *node); | ||
79 | struct device_node *v4l2_of_get_remote_port(const struct device_node *node); | ||
80 | #else /* CONFIG_OF */ | 76 | #else /* CONFIG_OF */ |
81 | 77 | ||
82 | static inline int v4l2_of_parse_endpoint(const struct device_node *node, | 78 | 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, | |||
85 | return -ENOSYS; | 81 | return -ENOSYS; |
86 | } | 82 | } |
87 | 83 | ||
88 | static inline struct device_node *v4l2_of_get_next_endpoint( | ||
89 | const struct device_node *parent, | ||
90 | struct device_node *previous) | ||
91 | { | ||
92 | return NULL; | ||
93 | } | ||
94 | |||
95 | static inline struct device_node *v4l2_of_get_remote_port_parent( | ||
96 | const struct device_node *node) | ||
97 | { | ||
98 | return NULL; | ||
99 | } | ||
100 | |||
101 | static inline struct device_node *v4l2_of_get_remote_port( | ||
102 | const struct device_node *node) | ||
103 | { | ||
104 | return NULL; | ||
105 | } | ||
106 | |||
107 | #endif /* CONFIG_OF */ | 84 | #endif /* CONFIG_OF */ |
108 | 85 | ||
109 | #endif /* _V4L2_OF_H */ | 86 | #endif /* _V4L2_OF_H */ |