Re: [PATCH 10/26] OMAPDSS: add of helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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.valkeinen@xxxxxx>
> ---
>  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.valkeinen@xxxxxx>
> + *
> + * 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux