@@ -3,8 +3,10 @@
#include <linux/list.h>
#include <linux/of_graph.h>
#include <drm/drmP.h>
+#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
#include <drm/drm_encoder.h>
+#include <drm/drm_panel.h>
#include <drm/drm_of.h>
static void drm_release_of(struct device *dev, void *data)
@@ -208,3 +210,53 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
return -EINVAL;
}
EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
+
+/*
+ * drm_of_find_panel_or_bridge - return connected panel or bridge device
+ * @np: device tree node containing encoder output ports
+ * @panel: pointer to hold returned drm_panel
+ * @bridge: pointer to hold returned drm_bridge
+ *
+ * Given a DT node's port and endpoint number, find the connected node and
+ * return either the associated struct drm_panel or drm_bridge device. Either
+ * @panel or @bridge must not be NULL.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge)
+{
+ int ret = -EPROBE_DEFER;
+ struct device_node *remote;
+
+ if (!panel && !bridge)
+ return -EINVAL;
+
+ remote = of_graph_get_remote_node(np, port, endpoint);
+ if (!remote)
+ return -ENODEV;
+
+ if (panel) {
+ *panel = of_drm_find_panel(remote);
+ if (*panel)
+ ret = 0;
+ }
+
+ /* No panel found yet, check for a bridge next. */
+ if (bridge) {
+ if (ret) {
+ *bridge = of_drm_find_bridge(remote);
+ if (*bridge)
+ ret = 0;
+ } else {
+ *bridge = NULL;
+ }
+
+ }
+
+ of_node_put(remote);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
@@ -8,6 +8,8 @@ struct component_match;
struct device;
struct drm_device;
struct drm_encoder;
+struct drm_panel;
+struct drm_bridge;
struct device_node;
#ifdef CONFIG_OF
@@ -23,6 +25,10 @@ extern int drm_of_component_probe(struct device *dev,
extern int drm_of_encoder_active_endpoint(struct device_node *node,
struct drm_encoder *encoder,
struct of_endpoint *endpoint);
+extern int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge);
#else
static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
struct device_node *port)
@@ -52,6 +58,13 @@ static inline int drm_of_encoder_active_endpoint(struct device_node *node,
{
return -EINVAL;
}
+static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge)
+{
+ return -EINVAL;
+}
#endif
static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,