aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2017-03-22 09:26:05 -0400
committerSean Paul <seanpaul@chromium.org>2017-04-06 17:00:27 -0400
commit1f2db3034c9f16ed918e34809167546f21d0fcb4 (patch)
tree327a2d7a070f91fd7a49aa2344c5ec1209df6e5d
parentb61c8d5d9a27715dd31781910aef12be4882ebfd (diff)
drm: of: introduce drm_of_find_panel_or_bridge
Many drivers have a common pattern of searching the OF graph for either an attached panel or bridge and then finding the DRM struct for the panel or bridge. Also, most drivers need to handle deferred probing when the DRM device is not yet instantiated. Create a common function, drm_of_find_panel_or_bridge, to find the connected node and the associated DRM panel or bridge device. Signed-off-by: Rob Herring <robh@kernel.org> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> [seanpaul dropped extern from drm_of.h] Signed-off-by: Sean Paul <seanpaul@chromium.org>
-rw-r--r--drivers/gpu/drm/drm_of.c52
-rw-r--r--include/drm/drm_of.h13
2 files changed, 65 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index b5f2f0fece99..2120f33bdf4a 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -3,8 +3,10 @@
3#include <linux/list.h> 3#include <linux/list.h>
4#include <linux/of_graph.h> 4#include <linux/of_graph.h>
5#include <drm/drmP.h> 5#include <drm/drmP.h>
6#include <drm/drm_bridge.h>
6#include <drm/drm_crtc.h> 7#include <drm/drm_crtc.h>
7#include <drm/drm_encoder.h> 8#include <drm/drm_encoder.h>
9#include <drm/drm_panel.h>
8#include <drm/drm_of.h> 10#include <drm/drm_of.h>
9 11
10static void drm_release_of(struct device *dev, void *data) 12static void drm_release_of(struct device *dev, void *data)
@@ -208,3 +210,53 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
208 return -EINVAL; 210 return -EINVAL;
209} 211}
210EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint); 212EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
213
214/*
215 * drm_of_find_panel_or_bridge - return connected panel or bridge device
216 * @np: device tree node containing encoder output ports
217 * @panel: pointer to hold returned drm_panel
218 * @bridge: pointer to hold returned drm_bridge
219 *
220 * Given a DT node's port and endpoint number, find the connected node and
221 * return either the associated struct drm_panel or drm_bridge device. Either
222 * @panel or @bridge must not be NULL.
223 *
224 * Returns zero if successful, or one of the standard error codes if it fails.
225 */
226int drm_of_find_panel_or_bridge(const struct device_node *np,
227 int port, int endpoint,
228 struct drm_panel **panel,
229 struct drm_bridge **bridge)
230{
231 int ret = -EPROBE_DEFER;
232 struct device_node *remote;
233
234 if (!panel && !bridge)
235 return -EINVAL;
236
237 remote = of_graph_get_remote_node(np, port, endpoint);
238 if (!remote)
239 return -ENODEV;
240
241 if (panel) {
242 *panel = of_drm_find_panel(remote);
243 if (*panel)
244 ret = 0;
245 }
246
247 /* No panel found yet, check for a bridge next. */
248 if (bridge) {
249 if (ret) {
250 *bridge = of_drm_find_bridge(remote);
251 if (*bridge)
252 ret = 0;
253 } else {
254 *bridge = NULL;
255 }
256
257 }
258
259 of_node_put(remote);
260 return ret;
261}
262EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index d1fc563f068a..104dd517fdbe 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -8,6 +8,8 @@ struct component_match;
8struct device; 8struct device;
9struct drm_device; 9struct drm_device;
10struct drm_encoder; 10struct drm_encoder;
11struct drm_panel;
12struct drm_bridge;
11struct device_node; 13struct device_node;
12 14
13#ifdef CONFIG_OF 15#ifdef CONFIG_OF
@@ -23,6 +25,10 @@ int drm_of_component_probe(struct device *dev,
23int drm_of_encoder_active_endpoint(struct device_node *node, 25int drm_of_encoder_active_endpoint(struct device_node *node,
24 struct drm_encoder *encoder, 26 struct drm_encoder *encoder,
25 struct of_endpoint *endpoint); 27 struct of_endpoint *endpoint);
28int drm_of_find_panel_or_bridge(const struct device_node *np,
29 int port, int endpoint,
30 struct drm_panel **panel,
31 struct drm_bridge **bridge);
26#else 32#else
27static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, 33static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
28 struct device_node *port) 34 struct device_node *port)
@@ -52,6 +58,13 @@ static inline int drm_of_encoder_active_endpoint(struct device_node *node,
52{ 58{
53 return -EINVAL; 59 return -EINVAL;
54} 60}
61static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
62 int port, int endpoint,
63 struct drm_panel **panel,
64 struct drm_bridge **bridge)
65{
66 return -EINVAL;
67}
55#endif 68#endif
56 69
57static inline int drm_of_encoder_active_endpoint_id(struct device_node *node, 70static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,