1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013 Texas Instruments 4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> 5 */ 6 7 #include <linux/device.h> 8 #include <linux/err.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/of_graph.h> 12 #include <linux/seq_file.h> 13 14 #include <video/omapfb_dss.h> 15 16 #include "dss.h" 17 18 struct device_node * 19 omapdss_of_get_next_port(const struct device_node *parent, 20 struct device_node *prev) 21 { 22 struct device_node *port = NULL; 23 24 if (!parent) 25 return NULL; 26 27 if (!prev) { 28 struct device_node *ports; 29 /* 30 * It's the first call, we have to find a port subnode 31 * within this node or within an optional 'ports' node. 32 */ 33 ports = of_get_child_by_name(parent, "ports"); 34 if (ports) 35 parent = ports; 36 37 port = of_get_child_by_name(parent, "port"); 38 39 /* release the 'ports' node */ 40 of_node_put(ports); 41 } else { 42 struct device_node *ports; 43 44 ports = of_get_parent(prev); 45 if (!ports) 46 return NULL; 47 48 do { 49 port = of_get_next_child(ports, prev); 50 if (!port) { 51 of_node_put(ports); 52 return NULL; 53 } 54 prev = port; 55 } while (!of_node_name_eq(port, "port")); 56 57 of_node_put(ports); 58 } 59 60 return port; 61 } 62 EXPORT_SYMBOL_GPL(omapdss_of_get_next_port); 63 64 struct device_node * 65 omapdss_of_get_next_endpoint(const struct device_node *parent, 66 struct device_node *prev) 67 { 68 struct device_node *ep = NULL; 69 70 if (!parent) 71 return NULL; 72 73 do { 74 ep = of_get_next_child(parent, prev); 75 if (!ep) 76 return NULL; 77 prev = ep; 78 } while (!of_node_name_eq(ep, "endpoint")); 79 80 return ep; 81 } 82 EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint); 83 84 struct device_node *dss_of_port_get_parent_device(struct device_node *port) 85 { 86 struct device_node *np; 87 int i; 88 89 if (!port) 90 return NULL; 91 92 np = of_get_parent(port); 93 94 for (i = 0; i < 2 && np; ++i) { 95 struct property *prop; 96 97 prop = of_find_property(np, "compatible", NULL); 98 99 if (prop) 100 return np; 101 102 np = of_get_next_parent(np); 103 } 104 105 return NULL; 106 } 107 108 u32 dss_of_port_get_port_number(struct device_node *port) 109 { 110 int r; 111 u32 reg; 112 113 r = of_property_read_u32(port, "reg", ®); 114 if (r) 115 reg = 0; 116 117 return reg; 118 } 119 120 struct omap_dss_device * 121 omapdss_of_find_source_for_first_ep(struct device_node *node) 122 { 123 struct device_node *ep; 124 struct device_node *src_port; 125 struct omap_dss_device *src; 126 127 ep = of_graph_get_endpoint_by_regs(node, 0, -1); 128 if (!ep) 129 return ERR_PTR(-EINVAL); 130 131 src_port = of_graph_get_remote_port(ep); 132 if (!src_port) { 133 of_node_put(ep); 134 return ERR_PTR(-EINVAL); 135 } 136 137 of_node_put(ep); 138 139 src = omap_dss_find_output_by_port_node(src_port); 140 141 of_node_put(src_port); 142 143 return src ? src : ERR_PTR(-EPROBE_DEFER); 144 } 145 EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep); 146