drm/bridge: analogix: Plug atomic state hooks to the default implementation
[linux-block.git] / drivers / gpu / drm / drm_bridge.c
CommitLineData
3d3f8b1f
AK
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <linux/err.h>
25#include <linux/module.h>
199e4e96 26#include <linux/mutex.h>
3d3f8b1f 27
75146591 28#include <drm/drm_atomic_state_helper.h>
199e4e96 29#include <drm/drm_bridge.h>
3bb80f24 30#include <drm/drm_encoder.h>
3d3f8b1f 31
4a878c03
LP
32#include "drm_crtc_internal.h"
33
2331b4e4
AT
34/**
35 * DOC: overview
36 *
ea0dd85a 37 * &struct drm_bridge represents a device that hangs on to an encoder. These are
da024fe5 38 * handy when a regular &drm_encoder entity isn't enough to represent the entire
2331b4e4
AT
39 * encoder chain.
40 *
da024fe5 41 * A bridge is always attached to a single &drm_encoder at a time, but can be
da5335b8 42 * either connected to it directly, or through an intermediate bridge::
2331b4e4 43 *
da024fe5 44 * encoder ---> bridge B ---> bridge A
2331b4e4
AT
45 *
46 * Here, the output of the encoder feeds to bridge B, and that furthers feeds to
47 * bridge A.
48 *
49 * The driver using the bridge is responsible to make the associations between
50 * the encoder and bridges. Once these links are made, the bridges will
51 * participate along with encoder functions to perform mode_set/enable/disable
da024fe5 52 * through the ops provided in &drm_bridge_funcs.
2331b4e4
AT
53 *
54 * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes,
da024fe5
DV
55 * CRTCs, encoders or connectors and hence are not visible to userspace. They
56 * just provide additional hooks to get the desired output at the end of the
57 * encoder chain.
58 *
05193dc3 59 * Bridges can also be chained up using the &drm_bridge.chain_node field.
da024fe5
DV
60 *
61 * Both legacy CRTC helpers and the new atomic modeset helpers support bridges.
2331b4e4
AT
62 */
63
3d3f8b1f
AK
64static DEFINE_MUTEX(bridge_lock);
65static LIST_HEAD(bridge_list);
66
2331b4e4
AT
67/**
68 * drm_bridge_add - add the given bridge to the global bridge list
69 *
70 * @bridge: bridge control structure
2331b4e4 71 */
99286884 72void drm_bridge_add(struct drm_bridge *bridge)
3d3f8b1f
AK
73{
74 mutex_lock(&bridge_lock);
75 list_add_tail(&bridge->list, &bridge_list);
76 mutex_unlock(&bridge_lock);
3d3f8b1f
AK
77}
78EXPORT_SYMBOL(drm_bridge_add);
79
2331b4e4
AT
80/**
81 * drm_bridge_remove - remove the given bridge from the global bridge list
82 *
83 * @bridge: bridge control structure
84 */
3d3f8b1f
AK
85void drm_bridge_remove(struct drm_bridge *bridge)
86{
87 mutex_lock(&bridge_lock);
88 list_del_init(&bridge->list);
89 mutex_unlock(&bridge_lock);
90}
91EXPORT_SYMBOL(drm_bridge_remove);
92
75146591
BB
93static struct drm_private_state *
94drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj)
95{
96 struct drm_bridge *bridge = drm_priv_to_bridge(obj);
97 struct drm_bridge_state *state;
98
99 state = bridge->funcs->atomic_duplicate_state(bridge);
100 return state ? &state->base : NULL;
101}
102
103static void
104drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj,
105 struct drm_private_state *s)
106{
107 struct drm_bridge_state *state = drm_priv_to_bridge_state(s);
108 struct drm_bridge *bridge = drm_priv_to_bridge(obj);
109
110 bridge->funcs->atomic_destroy_state(bridge, state);
111}
112
113static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = {
114 .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state,
115 .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state,
116};
117
2331b4e4 118/**
3bb80f24 119 * drm_bridge_attach - attach the bridge to an encoder's chain
2331b4e4 120 *
3bb80f24
LP
121 * @encoder: DRM encoder
122 * @bridge: bridge to attach
123 * @previous: previous bridge in the chain (optional)
2331b4e4 124 *
3bb80f24
LP
125 * Called by a kms driver to link the bridge to an encoder's chain. The previous
126 * argument specifies the previous bridge in the chain. If NULL, the bridge is
127 * linked directly at the encoder's output. Otherwise it is linked at the
128 * previous bridge's output.
2331b4e4 129 *
3bb80f24
LP
130 * If non-NULL the previous bridge must be already attached by a call to this
131 * function.
2331b4e4 132 *
169cc4c7
PR
133 * Note that bridges attached to encoders are auto-detached during encoder
134 * cleanup in drm_encoder_cleanup(), so drm_bridge_attach() should generally
135 * *not* be balanced with a drm_bridge_detach() in driver code.
136 *
2331b4e4
AT
137 * RETURNS:
138 * Zero on success, error code on failure
139 */
3bb80f24
LP
140int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
141 struct drm_bridge *previous)
3d3f8b1f 142{
3bb80f24
LP
143 int ret;
144
145 if (!encoder || !bridge)
146 return -EINVAL;
147
148 if (previous && (!previous->dev || previous->encoder != encoder))
3d3f8b1f
AK
149 return -EINVAL;
150
151 if (bridge->dev)
152 return -EBUSY;
153
3bb80f24
LP
154 bridge->dev = encoder->dev;
155 bridge->encoder = encoder;
156
05193dc3
BB
157 if (previous)
158 list_add(&bridge->chain_node, &previous->chain_node);
159 else
160 list_add(&bridge->chain_node, &encoder->bridge_chain);
161
3bb80f24
LP
162 if (bridge->funcs->attach) {
163 ret = bridge->funcs->attach(bridge);
75146591
BB
164 if (ret < 0)
165 goto err_reset_bridge;
166 }
167
168 if (bridge->funcs->atomic_reset) {
169 struct drm_bridge_state *state;
170
171 state = bridge->funcs->atomic_reset(bridge);
172 if (IS_ERR(state)) {
173 ret = PTR_ERR(state);
174 goto err_detach_bridge;
09912635 175 }
75146591
BB
176
177 drm_atomic_private_obj_init(bridge->dev, &bridge->base,
178 &state->base,
179 &drm_bridge_priv_state_funcs);
6ed7e962
BB
180 }
181
3d3f8b1f 182 return 0;
75146591
BB
183
184err_detach_bridge:
185 if (bridge->funcs->detach)
186 bridge->funcs->detach(bridge);
187
188err_reset_bridge:
189 bridge->dev = NULL;
190 bridge->encoder = NULL;
191 list_del(&bridge->chain_node);
192 return ret;
3d3f8b1f
AK
193}
194EXPORT_SYMBOL(drm_bridge_attach);
195
cf3bef95
AM
196void drm_bridge_detach(struct drm_bridge *bridge)
197{
198 if (WARN_ON(!bridge))
199 return;
200
201 if (WARN_ON(!bridge->dev))
202 return;
203
75146591
BB
204 if (bridge->funcs->atomic_reset)
205 drm_atomic_private_obj_fini(&bridge->base);
206
cf3bef95
AM
207 if (bridge->funcs->detach)
208 bridge->funcs->detach(bridge);
209
05193dc3 210 list_del(&bridge->chain_node);
cf3bef95
AM
211 bridge->dev = NULL;
212}
cf3bef95 213
2331b4e4
AT
214/**
215 * DOC: bridge callbacks
216 *
da024fe5
DV
217 * The &drm_bridge_funcs ops are populated by the bridge driver. The DRM
218 * internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c
219 * These helpers call a specific &drm_bridge_funcs op for all the bridges
2331b4e4
AT
220 * during encoder configuration.
221 *
da024fe5 222 * For detailed specification of the bridge callbacks see &drm_bridge_funcs.
2331b4e4
AT
223 */
224
862e686c 225/**
ea099adf
BB
226 * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the
227 * encoder chain
862e686c
AT
228 * @bridge: bridge control structure
229 * @mode: desired mode to be set for the bridge
230 * @adjusted_mode: updated mode that works for this bridge
231 *
4541d31e 232 * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the
862e686c
AT
233 * encoder chain, starting from the first bridge to the last.
234 *
235 * Note: the bridge passed should be the one closest to the encoder
236 *
237 * RETURNS:
238 * true on success, false on failure
239 */
ea099adf
BB
240bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
241 const struct drm_display_mode *mode,
242 struct drm_display_mode *adjusted_mode)
862e686c 243{
05193dc3 244 struct drm_encoder *encoder;
862e686c
AT
245
246 if (!bridge)
247 return true;
248
05193dc3
BB
249 encoder = bridge->encoder;
250 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
251 if (!bridge->funcs->mode_fixup)
252 continue;
862e686c 253
05193dc3
BB
254 if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode))
255 return false;
256 }
862e686c 257
05193dc3 258 return true;
862e686c 259}
ea099adf 260EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
862e686c 261
b1240f81 262/**
ea099adf
BB
263 * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
264 * encoder chain.
b1240f81
JA
265 * @bridge: bridge control structure
266 * @mode: desired mode to be validated
267 *
268 * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
269 * chain, starting from the first bridge to the last. If at least one bridge
270 * does not accept the mode the function returns the error code.
271 *
272 * Note: the bridge passed should be the one closest to the encoder.
273 *
274 * RETURNS:
275 * MODE_OK on success, drm_mode_status Enum error code on failure
276 */
ea099adf
BB
277enum drm_mode_status
278drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
279 const struct drm_display_mode *mode)
b1240f81 280{
05193dc3 281 struct drm_encoder *encoder;
b1240f81
JA
282
283 if (!bridge)
05193dc3 284 return MODE_OK;
b1240f81 285
05193dc3
BB
286 encoder = bridge->encoder;
287 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
288 enum drm_mode_status ret;
289
290 if (!bridge->funcs->mode_valid)
291 continue;
b1240f81 292
05193dc3
BB
293 ret = bridge->funcs->mode_valid(bridge, mode);
294 if (ret != MODE_OK)
295 return ret;
296 }
b1240f81 297
05193dc3 298 return MODE_OK;
b1240f81 299}
ea099adf 300EXPORT_SYMBOL(drm_bridge_chain_mode_valid);
b1240f81 301
862e686c 302/**
ea099adf 303 * drm_bridge_chain_disable - disables all bridges in the encoder chain
862e686c
AT
304 * @bridge: bridge control structure
305 *
4541d31e 306 * Calls &drm_bridge_funcs.disable op for all the bridges in the encoder
862e686c
AT
307 * chain, starting from the last bridge to the first. These are called before
308 * calling the encoder's prepare op.
309 *
310 * Note: the bridge passed should be the one closest to the encoder
311 */
ea099adf 312void drm_bridge_chain_disable(struct drm_bridge *bridge)
862e686c 313{
05193dc3
BB
314 struct drm_encoder *encoder;
315 struct drm_bridge *iter;
316
862e686c
AT
317 if (!bridge)
318 return;
319
05193dc3
BB
320 encoder = bridge->encoder;
321 list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
322 if (iter->funcs->disable)
323 iter->funcs->disable(iter);
862e686c 324
05193dc3
BB
325 if (iter == bridge)
326 break;
327 }
862e686c 328}
ea099adf 329EXPORT_SYMBOL(drm_bridge_chain_disable);
862e686c
AT
330
331/**
ea099adf
BB
332 * drm_bridge_chain_post_disable - cleans up after disabling all bridges in the
333 * encoder chain
862e686c
AT
334 * @bridge: bridge control structure
335 *
4541d31e 336 * Calls &drm_bridge_funcs.post_disable op for all the bridges in the
862e686c
AT
337 * encoder chain, starting from the first bridge to the last. These are called
338 * after completing the encoder's prepare op.
339 *
340 * Note: the bridge passed should be the one closest to the encoder
341 */
ea099adf 342void drm_bridge_chain_post_disable(struct drm_bridge *bridge)
862e686c 343{
05193dc3
BB
344 struct drm_encoder *encoder;
345
862e686c
AT
346 if (!bridge)
347 return;
348
05193dc3
BB
349 encoder = bridge->encoder;
350 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
351 if (bridge->funcs->post_disable)
352 bridge->funcs->post_disable(bridge);
353 }
862e686c 354}
ea099adf 355EXPORT_SYMBOL(drm_bridge_chain_post_disable);
862e686c
AT
356
357/**
ea099adf
BB
358 * drm_bridge_chain_mode_set - set proposed mode for all bridges in the
359 * encoder chain
862e686c 360 * @bridge: bridge control structure
ea099adf
BB
361 * @mode: desired mode to be set for the encoder chain
362 * @adjusted_mode: updated mode that works for this encoder chain
862e686c 363 *
4541d31e 364 * Calls &drm_bridge_funcs.mode_set op for all the bridges in the
862e686c
AT
365 * encoder chain, starting from the first bridge to the last.
366 *
367 * Note: the bridge passed should be the one closest to the encoder
368 */
ea099adf
BB
369void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
370 const struct drm_display_mode *mode,
371 const struct drm_display_mode *adjusted_mode)
862e686c 372{
05193dc3
BB
373 struct drm_encoder *encoder;
374
862e686c
AT
375 if (!bridge)
376 return;
377
05193dc3
BB
378 encoder = bridge->encoder;
379 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
380 if (bridge->funcs->mode_set)
381 bridge->funcs->mode_set(bridge, mode, adjusted_mode);
382 }
862e686c 383}
ea099adf 384EXPORT_SYMBOL(drm_bridge_chain_mode_set);
862e686c
AT
385
386/**
ea099adf
BB
387 * drm_bridge_chain_pre_enable - prepares for enabling all bridges in the
388 * encoder chain
862e686c
AT
389 * @bridge: bridge control structure
390 *
4541d31e 391 * Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder
862e686c
AT
392 * chain, starting from the last bridge to the first. These are called
393 * before calling the encoder's commit op.
394 *
395 * Note: the bridge passed should be the one closest to the encoder
396 */
ea099adf 397void drm_bridge_chain_pre_enable(struct drm_bridge *bridge)
862e686c 398{
05193dc3
BB
399 struct drm_encoder *encoder;
400 struct drm_bridge *iter;
401
862e686c
AT
402 if (!bridge)
403 return;
404
05193dc3
BB
405 encoder = bridge->encoder;
406 list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
407 if (iter->funcs->pre_enable)
408 iter->funcs->pre_enable(iter);
409 }
862e686c 410}
ea099adf 411EXPORT_SYMBOL(drm_bridge_chain_pre_enable);
862e686c
AT
412
413/**
ea099adf 414 * drm_bridge_chain_enable - enables all bridges in the encoder chain
862e686c
AT
415 * @bridge: bridge control structure
416 *
4541d31e 417 * Calls &drm_bridge_funcs.enable op for all the bridges in the encoder
862e686c
AT
418 * chain, starting from the first bridge to the last. These are called
419 * after completing the encoder's commit op.
420 *
421 * Note that the bridge passed should be the one closest to the encoder
422 */
ea099adf 423void drm_bridge_chain_enable(struct drm_bridge *bridge)
862e686c 424{
05193dc3
BB
425 struct drm_encoder *encoder;
426
862e686c
AT
427 if (!bridge)
428 return;
429
05193dc3
BB
430 encoder = bridge->encoder;
431 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
432 if (bridge->funcs->enable)
433 bridge->funcs->enable(bridge);
434 }
862e686c 435}
ea099adf 436EXPORT_SYMBOL(drm_bridge_chain_enable);
862e686c 437
5ade071b 438/**
ea099adf 439 * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain
5ade071b 440 * @bridge: bridge control structure
f3fdbc72 441 * @old_state: old atomic state
5ade071b
SP
442 *
443 * Calls &drm_bridge_funcs.atomic_disable (falls back on
444 * &drm_bridge_funcs.disable) op for all the bridges in the encoder chain,
445 * starting from the last bridge to the first. These are called before calling
446 * &drm_encoder_helper_funcs.atomic_disable
447 *
448 * Note: the bridge passed should be the one closest to the encoder
449 */
ea099adf 450void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
f3fdbc72 451 struct drm_atomic_state *old_state)
5ade071b 452{
05193dc3
BB
453 struct drm_encoder *encoder;
454 struct drm_bridge *iter;
455
5ade071b
SP
456 if (!bridge)
457 return;
458
05193dc3
BB
459 encoder = bridge->encoder;
460 list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
b470743b
BB
461 if (iter->funcs->atomic_disable)
462 iter->funcs->atomic_disable(iter, old_state);
463 else if (iter->funcs->disable)
05193dc3 464 iter->funcs->disable(iter);
5ade071b 465
05193dc3
BB
466 if (iter == bridge)
467 break;
468 }
5ade071b 469}
ea099adf 470EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
5ade071b
SP
471
472/**
ea099adf
BB
473 * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
474 * in the encoder chain
5ade071b 475 * @bridge: bridge control structure
f3fdbc72 476 * @old_state: old atomic state
5ade071b
SP
477 *
478 * Calls &drm_bridge_funcs.atomic_post_disable (falls back on
479 * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain,
480 * starting from the first bridge to the last. These are called after completing
481 * &drm_encoder_helper_funcs.atomic_disable
482 *
483 * Note: the bridge passed should be the one closest to the encoder
484 */
ea099adf 485void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
f3fdbc72 486 struct drm_atomic_state *old_state)
5ade071b 487{
05193dc3
BB
488 struct drm_encoder *encoder;
489
5ade071b
SP
490 if (!bridge)
491 return;
492
05193dc3
BB
493 encoder = bridge->encoder;
494 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
b470743b
BB
495 if (bridge->funcs->atomic_post_disable)
496 bridge->funcs->atomic_post_disable(bridge, old_state);
497 else if (bridge->funcs->post_disable)
05193dc3
BB
498 bridge->funcs->post_disable(bridge);
499 }
5ade071b 500}
ea099adf 501EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
5ade071b
SP
502
503/**
ea099adf
BB
504 * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in
505 * the encoder chain
5ade071b 506 * @bridge: bridge control structure
f3fdbc72 507 * @old_state: old atomic state
5ade071b
SP
508 *
509 * Calls &drm_bridge_funcs.atomic_pre_enable (falls back on
510 * &drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain,
511 * starting from the last bridge to the first. These are called before calling
512 * &drm_encoder_helper_funcs.atomic_enable
513 *
514 * Note: the bridge passed should be the one closest to the encoder
515 */
ea099adf 516void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
f3fdbc72 517 struct drm_atomic_state *old_state)
5ade071b 518{
05193dc3
BB
519 struct drm_encoder *encoder;
520 struct drm_bridge *iter;
521
5ade071b
SP
522 if (!bridge)
523 return;
524
05193dc3
BB
525 encoder = bridge->encoder;
526 list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
b470743b
BB
527 if (iter->funcs->atomic_pre_enable)
528 iter->funcs->atomic_pre_enable(iter, old_state);
529 else if (iter->funcs->pre_enable)
05193dc3 530 iter->funcs->pre_enable(iter);
5ade071b 531
05193dc3
BB
532 if (iter == bridge)
533 break;
534 }
5ade071b 535}
ea099adf 536EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
5ade071b
SP
537
538/**
ea099adf 539 * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain
5ade071b 540 * @bridge: bridge control structure
f3fdbc72 541 * @old_state: old atomic state
5ade071b
SP
542 *
543 * Calls &drm_bridge_funcs.atomic_enable (falls back on
544 * &drm_bridge_funcs.enable) op for all the bridges in the encoder chain,
545 * starting from the first bridge to the last. These are called after completing
546 * &drm_encoder_helper_funcs.atomic_enable
547 *
548 * Note: the bridge passed should be the one closest to the encoder
549 */
ea099adf 550void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
f3fdbc72 551 struct drm_atomic_state *old_state)
5ade071b 552{
05193dc3
BB
553 struct drm_encoder *encoder;
554
5ade071b
SP
555 if (!bridge)
556 return;
557
05193dc3
BB
558 encoder = bridge->encoder;
559 list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
b470743b
BB
560 if (bridge->funcs->atomic_enable)
561 bridge->funcs->atomic_enable(bridge, old_state);
562 else if (bridge->funcs->enable)
05193dc3
BB
563 bridge->funcs->enable(bridge);
564 }
5ade071b 565}
ea099adf 566EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
5ade071b 567
3d3f8b1f 568#ifdef CONFIG_OF
2331b4e4
AT
569/**
570 * of_drm_find_bridge - find the bridge corresponding to the device node in
571 * the global bridge list
572 *
573 * @np: device node
574 *
575 * RETURNS:
576 * drm_bridge control struct on success, NULL on failure
577 */
3d3f8b1f
AK
578struct drm_bridge *of_drm_find_bridge(struct device_node *np)
579{
580 struct drm_bridge *bridge;
581
582 mutex_lock(&bridge_lock);
583
584 list_for_each_entry(bridge, &bridge_list, list) {
585 if (bridge->of_node == np) {
586 mutex_unlock(&bridge_lock);
587 return bridge;
588 }
589 }
590
591 mutex_unlock(&bridge_lock);
592 return NULL;
593}
594EXPORT_SYMBOL(of_drm_find_bridge);
595#endif
596
597MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
598MODULE_DESCRIPTION("DRM bridge infrastructure");
599MODULE_LICENSE("GPL and additional rights");