summaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/imx/imx-media-of.c
diff options
context:
space:
mode:
authorSteve Longerbeam2017-12-15 02:04:41 +0100
committerMauro Carvalho Chehab2017-12-15 20:04:30 +0100
commitf5abe1c5f9bd3e5a4dad5079f6cd51641f2bf2a3 (patch)
tree5a5cad276166e32da66d999ca58c071177f894af /drivers/staging/media/imx/imx-media-of.c
parentmedia: staging/imx: remove static media link arrays (diff)
downloadkernel-qcow2-linux-f5abe1c5f9bd3e5a4dad5079f6cd51641f2bf2a3.tar.gz
kernel-qcow2-linux-f5abe1c5f9bd3e5a4dad5079f6cd51641f2bf2a3.tar.xz
kernel-qcow2-linux-f5abe1c5f9bd3e5a4dad5079f6cd51641f2bf2a3.zip
media: staging/imx: of: allow for recursing downstream
Calling of_parse_subdev() recursively to a downstream path that has already been followed is ok, it just means that call will return immediately since the subdevice was already added to the async list. With that there is no need to determine whether a subdevice's port is a sink or source, so 'num_{sink|src}_pads' is no longer used and is removed. Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/staging/media/imx/imx-media-of.c')
-rw-r--r--drivers/staging/media/imx/imx-media-of.c78
1 files changed, 21 insertions, 57 deletions
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index d35c99e9f049..a085e5213ef0 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -41,11 +41,12 @@ static int of_get_port_count(const struct device_node *np)
/*
* find the remote device node given local endpoint node
*/
-static void of_get_remote(struct device_node *epnode,
+static bool of_get_remote(struct device_node *epnode,
struct device_node **remote_node)
{
struct device_node *rp, *rpp;
struct device_node *remote;
+ bool is_csi_port;
rp = of_graph_get_remote_port(epnode);
rpp = of_graph_get_remote_port_parent(epnode);
@@ -54,9 +55,11 @@ static void of_get_remote(struct device_node *epnode,
/* the remote is one of the CSI ports */
remote = rp;
of_node_put(rpp);
+ is_csi_port = true;
} else {
remote = rpp;
of_node_put(rp);
+ is_csi_port = false;
}
if (!of_device_is_available(remote)) {
@@ -65,6 +68,8 @@ static void of_get_remote(struct device_node *epnode,
} else {
*remote_node = remote;
}
+
+ return is_csi_port;
}
static int
@@ -72,7 +77,7 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
bool is_csi_port)
{
struct imx_media_subdev *imxsd;
- int i, num_pads, ret;
+ int i, num_ports, ret;
if (!of_device_is_available(sd_np)) {
dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__,
@@ -94,77 +99,36 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
return ret;
}
- if (is_csi_port) {
- /*
- * the ipu-csi has one sink port and two source ports.
- * The source ports are not represented in the device tree,
- * but are described by the internal pads and links later.
- */
- num_pads = CSI_NUM_PADS;
- imxsd->num_sink_pads = CSI_NUM_SINK_PADS;
- } else if (of_device_is_compatible(sd_np, "fsl,imx6-mipi-csi2")) {
- num_pads = of_get_port_count(sd_np);
- /* the mipi csi2 receiver has only one sink port */
- imxsd->num_sink_pads = 1;
- } else if (of_device_is_compatible(sd_np, "video-mux")) {
- num_pads = of_get_port_count(sd_np);
- /* for the video mux, all but the last port are sinks */
- imxsd->num_sink_pads = num_pads - 1;
- } else {
- num_pads = of_get_port_count(sd_np);
- if (num_pads != 1) {
- /* confused, but no reason to give up here */
- dev_warn(imxmd->md.dev,
- "%s: unknown device %s with %d ports\n",
- __func__, sd_np->name, num_pads);
- return 0;
- }
+ /*
+ * the ipu-csi has one sink port. The source pads are not
+ * represented in the device tree by port nodes, but are
+ * described by the internal pads and links later.
+ */
+ num_ports = is_csi_port ? 1 : of_get_port_count(sd_np);
- /*
- * we got to this node from this single source port,
- * there are no sink pads.
- */
- imxsd->num_sink_pads = 0;
- }
-
- if (imxsd->num_sink_pads >= num_pads)
- return -EINVAL;
-
- imxsd->num_src_pads = num_pads - imxsd->num_sink_pads;
-
- dev_dbg(imxmd->md.dev, "%s: %s has %d pads (%d sink, %d src)\n",
- __func__, sd_np->name, num_pads,
- imxsd->num_sink_pads, imxsd->num_src_pads);
-
- for (i = 0; i < num_pads; i++) {
+ for (i = 0; i < num_ports; i++) {
struct device_node *epnode = NULL, *port, *remote_np;
- if (is_csi_port)
- port = (i < imxsd->num_sink_pads) ? sd_np : NULL;
- else
- port = of_graph_get_port_by_id(sd_np, i);
+ port = is_csi_port ? sd_np : of_graph_get_port_by_id(sd_np, i);
if (!port)
continue;
for_each_child_of_node(port, epnode) {
- of_get_remote(epnode, &remote_np);
+ bool remote_is_csi;
+
+ remote_is_csi = of_get_remote(epnode, &remote_np);
if (!remote_np)
continue;
- if (i < imxsd->num_sink_pads) {
- /* follow sink endpoints upstream */
- ret = of_parse_subdev(imxmd, remote_np, false);
- if (ret)
- break;
- }
-
+ ret = of_parse_subdev(imxmd, remote_np, remote_is_csi);
of_node_put(remote_np);
+ if (ret)
+ break;
}
if (port != sd_np)
of_node_put(port);
if (ret) {
- of_node_put(remote_np);
of_node_put(epnode);
break;
}