143 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2013 Texas Instruments4 * 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 18struct device_node *19omapdss_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 subnode31 * 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}62EXPORT_SYMBOL_GPL(omapdss_of_get_next_port);63 64struct device_node *65omapdss_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}82EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);83 84struct 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 108u32 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 120struct omap_dss_device *121omapdss_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 of_node_put(ep);133 if (!src_port)134 return ERR_PTR(-EINVAL);135 136 src = omap_dss_find_output_by_port_node(src_port);137 138 of_node_put(src_port);139 140 return src ? src : ERR_PTR(-EPROBE_DEFER);141}142EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);143