Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013 Texas Instruments
0004  * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
0005  */
0006 
0007 #include <linux/device.h>
0008 #include <linux/err.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/of_graph.h>
0012 #include <linux/seq_file.h>
0013 
0014 #include <video/omapfb_dss.h>
0015 
0016 #include "dss.h"
0017 
0018 struct device_node *
0019 omapdss_of_get_next_port(const struct device_node *parent,
0020              struct device_node *prev)
0021 {
0022     struct device_node *port = NULL;
0023 
0024     if (!parent)
0025         return NULL;
0026 
0027     if (!prev) {
0028         struct device_node *ports;
0029         /*
0030          * It's the first call, we have to find a port subnode
0031          * within this node or within an optional 'ports' node.
0032          */
0033         ports = of_get_child_by_name(parent, "ports");
0034         if (ports)
0035             parent = ports;
0036 
0037         port = of_get_child_by_name(parent, "port");
0038 
0039         /* release the 'ports' node */
0040         of_node_put(ports);
0041     } else {
0042         struct device_node *ports;
0043 
0044         ports = of_get_parent(prev);
0045         if (!ports)
0046             return NULL;
0047 
0048         do {
0049             port = of_get_next_child(ports, prev);
0050             if (!port) {
0051                 of_node_put(ports);
0052                 return NULL;
0053             }
0054             prev = port;
0055         } while (!of_node_name_eq(port, "port"));
0056 
0057         of_node_put(ports);
0058     }
0059 
0060     return port;
0061 }
0062 EXPORT_SYMBOL_GPL(omapdss_of_get_next_port);
0063 
0064 struct device_node *
0065 omapdss_of_get_next_endpoint(const struct device_node *parent,
0066                  struct device_node *prev)
0067 {
0068     struct device_node *ep = NULL;
0069 
0070     if (!parent)
0071         return NULL;
0072 
0073     do {
0074         ep = of_get_next_child(parent, prev);
0075         if (!ep)
0076             return NULL;
0077         prev = ep;
0078     } while (!of_node_name_eq(ep, "endpoint"));
0079 
0080     return ep;
0081 }
0082 EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
0083 
0084 struct device_node *dss_of_port_get_parent_device(struct device_node *port)
0085 {
0086     struct device_node *np;
0087     int i;
0088 
0089     if (!port)
0090         return NULL;
0091 
0092     np = of_get_parent(port);
0093 
0094     for (i = 0; i < 2 && np; ++i) {
0095         struct property *prop;
0096 
0097         prop = of_find_property(np, "compatible", NULL);
0098 
0099         if (prop)
0100             return np;
0101 
0102         np = of_get_next_parent(np);
0103     }
0104 
0105     return NULL;
0106 }
0107 
0108 u32 dss_of_port_get_port_number(struct device_node *port)
0109 {
0110     int r;
0111     u32 reg;
0112 
0113     r = of_property_read_u32(port, "reg", &reg);
0114     if (r)
0115         reg = 0;
0116 
0117     return reg;
0118 }
0119 
0120 static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
0121 {
0122     struct device_node *np;
0123 
0124     np = of_graph_get_remote_endpoint(node);
0125     if (!np)
0126         return NULL;
0127 
0128     np = of_get_next_parent(np);
0129 
0130     return np;
0131 }
0132 
0133 struct device_node *
0134 omapdss_of_get_first_endpoint(const struct device_node *parent)
0135 {
0136     struct device_node *port, *ep;
0137 
0138     port = omapdss_of_get_next_port(parent, NULL);
0139 
0140     if (!port)
0141         return NULL;
0142 
0143     ep = omapdss_of_get_next_endpoint(port, NULL);
0144 
0145     of_node_put(port);
0146 
0147     return ep;
0148 }
0149 EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
0150 
0151 struct omap_dss_device *
0152 omapdss_of_find_source_for_first_ep(struct device_node *node)
0153 {
0154     struct device_node *ep;
0155     struct device_node *src_port;
0156     struct omap_dss_device *src;
0157 
0158     ep = omapdss_of_get_first_endpoint(node);
0159     if (!ep)
0160         return ERR_PTR(-EINVAL);
0161 
0162     src_port = omapdss_of_get_remote_port(ep);
0163     if (!src_port) {
0164         of_node_put(ep);
0165         return ERR_PTR(-EINVAL);
0166     }
0167 
0168     of_node_put(ep);
0169 
0170     src = omap_dss_find_output_by_port_node(src_port);
0171 
0172     of_node_put(src_port);
0173 
0174     return src ? src : ERR_PTR(-EPROBE_DEFER);
0175 }
0176 EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);