drivers/gpu/drm/drm_bridge.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/drm_bridge.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_bridge.c
Extension
.c
Size
57653 bytes
Lines
1730
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (iter->funcs->atomic_disable) {
			iter->funcs->atomic_disable(iter, state);
		} else if (iter->funcs->disable) {
			iter->funcs->disable(iter);
		}

		if (iter == bridge)
			break;
	}
	mutex_unlock(&encoder->bridge_chain_mutex);
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);

static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge,
						struct drm_atomic_commit *state)
{
	if (state && bridge->funcs->atomic_post_disable)
		bridge->funcs->atomic_post_disable(bridge, state);
	else if (bridge->funcs->post_disable)
		bridge->funcs->post_disable(bridge);
}

/**
 * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
 *					  in the encoder chain
 * @bridge: bridge control structure
 * @state: atomic state being committed
 *
 * Calls &drm_bridge_funcs.atomic_post_disable (falls back on
 * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain,
 * starting from the first bridge to the last. These are called after completing
 * &drm_encoder_helper_funcs.atomic_disable
 *
 * If a bridge sets @pre_enable_prev_first, then the @post_disable for that
 * bridge will be called before the previous one to reverse the @pre_enable
 * calling direction.
 *
 * Example:
 * Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E
 *
 * With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting
 * @post_disable order would be,
 * Bridge B, Bridge A, Bridge E, Bridge D, Bridge C.
 *
 * Note: the bridge passed should be the one closest to the encoder
 */
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
					  struct drm_atomic_commit *state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *next, *limit;

	if (!bridge)
		return;

	encoder = bridge->encoder;

	mutex_lock(&encoder->bridge_chain_mutex);
	list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
		limit = NULL;

		if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) {
			next = list_next_entry(bridge, chain_node);

			if (next->pre_enable_prev_first) {
				/* next bridge had requested that prev
				 * was enabled first, so disabled last
				 */
				limit = next;

				/* Find the next bridge that has NOT requested
				 * prev to be enabled first / disabled last
				 */
				list_for_each_entry_from(next, &encoder->bridge_chain,
							 chain_node) {
					if (!next->pre_enable_prev_first) {
						next = list_prev_entry(next, chain_node);
						limit = next;
						break;
					}

					if (list_is_last(&next->chain_node,
							 &encoder->bridge_chain)) {
						limit = next;
						break;
					}
				}

				/* Call these bridges in reverse order */
				list_for_each_entry_from_reverse(next, &encoder->bridge_chain,

Annotation

Implementation Notes