Hi Tomi,

On Wednesday 04 December 2013 14:28:37 Tomi Valkeinen wrote:
> Add helpers to get ports and endpoints from DT data.
> 
> While all the functions in dss-of.c might be useful for panel drivers if
> they need to parse full port/endpoint data, at the moment we only need a
> few of them outside dss-of.c, so only those functions are exported.

I totally understand that it was easier to add this code to the OMAP DSS 
driver, but I believe we should refactor the existing drivers/media/v4l2-
core/v4l2-of.c and move it to a non V4L2-specific location (what about 
drivers/media ?) sooner rather than later. That's on my to-do list for 
Saturday.

> Signed-off-by: Tomi Valkeinen <tomi.valkei...@ti.com>
> ---
>  drivers/video/omap2/dss/Makefile |   2 +-
>  drivers/video/omap2/dss/dss-of.c | 160 ++++++++++++++++++++++++++++++++++++
>  include/video/omapdss.h          |   6 ++
>  3 files changed, 167 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/video/omap2/dss/dss-of.c
> 
> diff --git a/drivers/video/omap2/dss/Makefile
> b/drivers/video/omap2/dss/Makefile index d3aa91bdd6a8..8aec8bda27cc 100644
> --- a/drivers/video/omap2/dss/Makefile
> +++ b/drivers/video/omap2/dss/Makefile
> @@ -1,7 +1,7 @@
>  obj-$(CONFIG_OMAP2_DSS) += omapdss.o
>  # Core DSS files
>  omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
> -     output.o
> +     output.o dss-of.o
>  # DSS compat layer files
>  omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
>       dispc-compat.o display-sysfs.o
> diff --git a/drivers/video/omap2/dss/dss-of.c
> b/drivers/video/omap2/dss/dss-of.c new file mode 100644
> index 000000000000..9aa61d4bdb3d
> --- /dev/null
> +++ b/drivers/video/omap2/dss/dss-of.c
> @@ -0,0 +1,160 @@
> +/*
> + * Copyright (C) 2013 Texas Instruments
> + * Author: Tomi Valkeinen <tomi.valkei...@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published
> by + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> WITHOUT + * ANY WARRANTY; without even the implied warranty of
> MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> General Public License for + * more details.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/seq_file.h>
> +
> +#include <video/omapdss.h>
> +
> +#include "dss.h"
> +#include "dss_features.h"
> +
> +static struct device_node *
> +omapdss_of_get_next_port(const struct device_node *parent,
> +                      struct device_node *prev)
> +{
> +     struct device_node *port = NULL;
> +
> +     if (!parent)
> +             return NULL;
> +
> +     if (!prev) {
> +             struct device_node *ports;
> +             /*
> +              * It's the first call, we have to find a port subnode
> +              * within this node or within an optional 'ports' node.
> +              */
> +             ports = of_get_child_by_name(parent, "ports");
> +             if (ports)
> +                     parent = ports;
> +
> +             port = of_get_child_by_name(parent, "port");
> +
> +             /* release the 'ports' node */
> +             of_node_put(ports);
> +     } else {
> +             struct device_node *ports;
> +
> +             ports = of_get_parent(prev);
> +             if (!ports)
> +                     return NULL;
> +
> +             do {
> +                     port = of_get_next_child(ports, prev);
> +                     if (!port) {
> +                             of_node_put(ports);
> +                             return NULL;
> +                     }
> +                     prev = port;
> +             } while (of_node_cmp(port->name, "port") != 0);
> +     }
> +
> +     return port;
> +}
> +
> +static struct device_node *
> +omapdss_of_get_next_endpoint(const struct device_node *parent,
> +                          struct device_node *prev)
> +{
> +     struct device_node *ep = NULL;
> +
> +     if (!parent)
> +             return NULL;
> +
> +     do {
> +             ep = of_get_next_child(parent, prev);
> +             if (!ep)
> +                     return NULL;
> +             prev = ep;
> +     } while (of_node_cmp(ep->name, "endpoint") != 0);
> +
> +     return ep;
> +}
> +
> +static struct device_node *
> +omapdss_of_get_remote_device_node(const struct device_node *node)
> +{
> +     struct device_node *np;
> +     int i;
> +
> +     np = of_parse_phandle(node, "remote-endpoint", 0);
> +
> +     if (!np)
> +             return NULL;
> +
> +     np = of_get_next_parent(np);
> +
> +     for (i = 0; i < 3 && np; ++i) {
> +             struct property *prop;
> +
> +             prop = of_find_property(np, "compatible", NULL);
> +
> +             if (prop)
> +                     return np;
> +
> +             np = of_get_next_parent(np);
> +     }
> +
> +     return NULL;
> +}
> +
> +struct device_node *
> +omapdss_of_get_first_endpoint(const struct device_node *parent)
> +{
> +     struct device_node *port;
> +     struct device_node *ep;
> +
> +     port = omapdss_of_get_next_port(parent, NULL);
> +     if (port) {
> +             ep = omapdss_of_get_next_endpoint(port, NULL);
> +             of_node_put(port);
> +     } else {
> +             ep = omapdss_of_get_next_endpoint(parent, NULL);
> +     }
> +
> +     return ep;
> +}
> +EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
> +
> +struct omap_dss_device *
> +omapdss_of_find_source_for_first_ep(struct device_node *node)
> +{
> +     struct device_node *ep;
> +     struct device_node *src_node;
> +     struct omap_dss_device *src;
> +
> +     ep = omapdss_of_get_first_endpoint(node);
> +     if (!ep)
> +             return ERR_PTR(-EINVAL);
> +
> +     src_node = omapdss_of_get_remote_device_node(ep);
> +
> +     of_node_put(ep);
> +
> +     if (!src_node)
> +             return ERR_PTR(-EINVAL);
> +
> +     src = omap_dss_find_output_by_node(src_node);
> +
> +     of_node_put(src_node);
> +
> +     if (!src)
> +             return ERR_PTR(-EPROBE_DEFER);
> +
> +     return src;
> +}
> +EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
> diff --git a/include/video/omapdss.h b/include/video/omapdss.h
> index 3d7c51a6f9ff..c510591df1b8 100644
> --- a/include/video/omapdss.h
> +++ b/include/video/omapdss.h
> @@ -1019,4 +1019,10 @@ static inline bool omapdss_device_is_enabled(struct
> omap_dss_device *dssdev) return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
>  }
> 
> +struct device_node *
> +omapdss_of_get_first_endpoint(const struct device_node *parent);
> +
> +struct omap_dss_device *
> +omapdss_of_find_source_for_first_ep(struct device_node *node);
> +
>  #endif
-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to