0001
0002
0003
0004
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
0031
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
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", ®);
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);