[PATCH 5/5] drm/atomic: Make private objs proper objects

Daniel Vetter daniel at ffwll.ch
Mon Jul 3 17:00:03 UTC 2017


On Mon, Jul 03, 2017 at 04:43:37PM +0300, ville.syrjala at linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> Make the atomic private object stuff less special by introducing proper
> base classes for the object and its state. Drivers can embed these in
> their own appropriate objects, after which these things will work
> exactly like the plane/crtc/connector states during atomic operations.
> 
> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

Won't apply without 1&4, but glossing over that detail I kinda like this.

Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>

> ---
>  drivers/gpu/drm/drm_atomic.c          |  78 +++++++++++++++------
>  drivers/gpu/drm/drm_atomic_helper.c   |  30 +++++++--
>  drivers/gpu/drm/drm_dp_mst_topology.c |  63 +++++++++--------
>  include/drm/drm_atomic.h              | 123 +++++++++++++++++++++-------------
>  include/drm/drm_atomic_helper.h       |   4 ++
>  include/drm/drm_dp_mst_helper.h       |  10 +++
>  6 files changed, 206 insertions(+), 102 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 5eb14c73c0fb..da7752230e4c 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -197,12 +197,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
>  	for (i = 0; i < state->num_private_objs; i++) {
>  		struct __drm_private_objs_state *p =
>  			__drm_atomic_state_private_obj(state, i);
> -		void *obj_state = p->obj_state;
> +		struct drm_private_obj *obj = p->ptr;
>  
> -		p->funcs->destroy_state(obj_state);
> -		p->obj = NULL;
> -		p->obj_state = NULL;
> -		p->funcs = NULL;
> +		if (WARN_ON(!obj))
> +			continue;
> +
> +		obj->funcs->atomic_destroy_state(obj, p->state);
> +		p->ptr = NULL;
> +		p->state = NULL;
>  	}
>  	state->num_private_objs = 0;
>  
> @@ -1000,11 +1002,44 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
>  }
>  
>  /**
> + * drm_atomic_private_obj_init - initialize private object
> + * @obj: private object
> + * @state: initial private object state
> + * @funcs: pointer to the struct of function pointers that identify the object
> + * type
> + *
> + * Initialize the private object, which can be embedded into any
> + * driver private object that needs its own atomic state.
> + */
> +void
> +drm_atomic_private_obj_init(struct drm_private_obj *obj,
> +			    struct drm_private_state *state,
> +			    const struct drm_private_state_funcs *funcs)
> +{
> +	memset(obj, 0, sizeof(*obj));
> +
> +	obj->state = state;
> +	obj->funcs = funcs;
> +}
> +EXPORT_SYMBOL(drm_atomic_private_obj_init);
> +
> +/**
> + * drm_atomic_private_obj_fini - finalize private object
> + * @obj: private object
> + *
> + * Finalize the private object.
> + */
> +void
> +drm_atomic_private_obj_fini(struct drm_private_obj *obj)
> +{
> +	obj->funcs->atomic_destroy_state(obj, obj->state);
> +}
> +EXPORT_SYMBOL(drm_atomic_private_obj_fini);
> +
> +/**
>   * drm_atomic_get_private_obj_state - get private object state
>   * @state: global atomic state
>   * @obj: private object to get the state for
> - * @funcs: pointer to the struct of function pointers that identify the object
> - * type
>   *
>   * This function returns the private object state for the given private object,
>   * allocating the state if needed. It does not grab any locks as the caller is
> @@ -1014,19 +1049,21 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
>   *
>   * Either the allocated state or the error code encoded into a pointer.
>   */
> -void *
> -drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
> -			      const struct drm_private_state_funcs *funcs)
> +struct drm_private_state *
> +drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
> +				 struct drm_private_obj *obj)
>  {
> +	const struct drm_private_state_funcs *funcs = obj->funcs;
>  	struct __drm_private_objs_state *p;
> +	struct drm_private_state *obj_state;
>  	int index = state->num_private_objs;
>  	int ret, i;
>  
>  	for (i = 0; i < state->num_private_objs; i++) {
>  		p = __drm_atomic_state_private_obj(state, i);
>  
> -		if (obj == p->obj)
> -			return p->obj_state;
> +		if (obj == p->ptr)
> +			return p->state;
>  	}
>  
>  	ret = drm_dynarray_reserve(&state->private_objs, index);
> @@ -1035,19 +1072,22 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
>  
>  	p = __drm_atomic_state_private_obj(state, index);
>  
> -	p->obj_state = funcs->duplicate_state(state, obj);
> -	if (!p->obj_state)
> +	obj_state = funcs->atomic_duplicate_state(obj);
> +	if (!obj_state)
>  		return ERR_PTR(-ENOMEM);
>  
> -	p->obj = obj;
> -	p->funcs = funcs;
> +	p->state = obj_state;
> +	p->old_state = obj->state;
> +	p->new_state = obj_state;
> +	p->ptr = obj;
> +	obj_state->state = state;
>  
>  	state->num_private_objs = index + 1;
>  
> -	DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n",
> -			 p->obj_state, state);
> +	DRM_DEBUG_ATOMIC("Added new private object [%p] state %p to %p\n",
> +			 obj, obj_state, state);
>  
> -	return p->obj_state;
> +	return obj_state;
>  }
>  EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
>  
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 5cd93c6d691e..78f0ff1ad982 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2267,8 +2267,8 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  	struct drm_plane *plane;
>  	struct drm_plane_state *old_plane_state, *new_plane_state;
>  	struct drm_crtc_commit *commit;
> -	void *obj, *obj_state;
> -	const struct drm_private_state_funcs *funcs;
> +	struct drm_private_obj *obj;
> +	struct drm_private_state *old_obj_state, *new_obj_state;
>  
>  	if (stall) {
>  		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
> @@ -2330,8 +2330,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  		plane->state = new_plane_state;
>  	}
>  
> -	__for_each_private_obj(state, obj, obj_state, i, funcs)
> -		funcs->swap_state(obj, &__drm_atomic_state_private_obj(state, i)->obj_state);
> +	for_each_oldnew_private_obj_in_state(state, obj, old_obj_state, new_obj_state, i) {
> +		WARN_ON(obj->state != old_obj_state);
> +
> +		old_obj_state->state = state;
> +		new_obj_state->state = NULL;
> +
> +		__drm_atomic_state_private_obj(state, i)->state = old_obj_state;
> +		obj->state = new_obj_state;
> +	}
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_swap_state);
>  
> @@ -3830,3 +3837,18 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
> +
> +/**
> + * __drm_atomic_helper_private_duplicate_state - copy atomic private state
> + * @obj: CRTC object
> + * @state: new private object state
> + *
> + * Copies atomic state from a private objects's current state and resets inferred values.
> + * This is useful for drivers that subclass the private state.
> + */
> +void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
> +						     struct drm_private_state *state)
> +{
> +	memcpy(state, obj->state, sizeof(*state));
> +}
> +EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> index bfd237c15e76..91510098f60e 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -31,6 +31,8 @@
>  #include <drm/drmP.h>
>  
>  #include <drm/drm_fixed.h>
> +#include <drm/drm_atomic.h>
> +#include <drm/drm_atomic_helper.h>
>  
>  /**
>   * DOC: dp mst helper
> @@ -2992,41 +2994,32 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
>  		(*mgr->cbs->hotplug)(mgr);
>  }
>  
> -void *drm_dp_mst_duplicate_state(struct drm_atomic_state *state, void *obj)
> +static struct drm_private_state *
> +drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
>  {
> -	struct drm_dp_mst_topology_mgr *mgr = obj;
> -	struct drm_dp_mst_topology_state *new_mst_state;
> +	struct drm_dp_mst_topology_state *state;
>  
> -	if (WARN_ON(!mgr->state))
> +	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
> +	if (!state)
>  		return NULL;
>  
> -	new_mst_state = kmemdup(mgr->state, sizeof(*new_mst_state), GFP_KERNEL);
> -	if (new_mst_state)
> -		new_mst_state->state = state;
> -	return new_mst_state;
> -}
> -
> -void drm_dp_mst_swap_state(void *obj, void **obj_state_ptr)
> -{
> -	struct drm_dp_mst_topology_mgr *mgr = obj;
> -	struct drm_dp_mst_topology_state **topology_state_ptr;
> -
> -	topology_state_ptr = (struct drm_dp_mst_topology_state **)obj_state_ptr;
> +	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
>  
> -	mgr->state->state = (*topology_state_ptr)->state;
> -	swap(*topology_state_ptr, mgr->state);
> -	mgr->state->state = NULL;
> +	return &state->base;
>  }
>  
> -void drm_dp_mst_destroy_state(void *obj_state)
> +static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
> +				     struct drm_private_state *state)
>  {
> -	kfree(obj_state);
> +	struct drm_dp_mst_topology_state *mst_state =
> +		to_dp_mst_topology_state(state);
> +
> +	kfree(mst_state);
>  }
>  
>  static const struct drm_private_state_funcs mst_state_funcs = {
> -	.duplicate_state = drm_dp_mst_duplicate_state,
> -	.swap_state = drm_dp_mst_swap_state,
> -	.destroy_state = drm_dp_mst_destroy_state,
> +	.atomic_duplicate_state = drm_dp_mst_duplicate_state,
> +	.atomic_destroy_state = drm_dp_mst_destroy_state,
>  };
>  
>  /**
> @@ -3050,8 +3043,7 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
>  	struct drm_device *dev = mgr->dev;
>  
>  	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> -	return drm_atomic_get_private_obj_state(state, mgr,
> -						&mst_state_funcs);
> +	return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, &mgr->base));
>  }
>  EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
>  
> @@ -3071,6 +3063,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>  				 int max_dpcd_transaction_bytes,
>  				 int max_payloads, int conn_base_id)
>  {
> +	struct drm_dp_mst_topology_state *mst_state;
> +
>  	mutex_init(&mgr->lock);
>  	mutex_init(&mgr->qlock);
>  	mutex_init(&mgr->payload_lock);
> @@ -3099,14 +3093,18 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
>  	if (test_calc_pbn_mode() < 0)
>  		DRM_ERROR("MST PBN self-test failed\n");
>  
> -	mgr->state = kzalloc(sizeof(*mgr->state), GFP_KERNEL);
> -	if (mgr->state == NULL)
> +	mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
> +	if (mst_state == NULL)
>  		return -ENOMEM;
> -	mgr->state->mgr = mgr;
> +
> +	mst_state->mgr = mgr;
>  
>  	/* max. time slots - one slot for MTP header */
> -	mgr->state->avail_slots = 63;
> -	mgr->funcs = &mst_state_funcs;
> +	mst_state->avail_slots = 63;
> +
> +	drm_atomic_private_obj_init(&mgr->base,
> +				    &mst_state->base,
> +				    &mst_state_funcs);
>  
>  	return 0;
>  }
> @@ -3128,8 +3126,7 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
>  	mutex_unlock(&mgr->payload_lock);
>  	mgr->dev = NULL;
>  	mgr->aux = NULL;
> -	kfree(mgr->state);
> -	mgr->state = NULL;
> +	drm_atomic_private_obj_fini(&mgr->base);
>  	mgr->funcs = NULL;
>  }
>  EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 809e8b4c3719..addec49a14bf 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -155,6 +155,9 @@ struct __drm_connectors_state {
>  	struct drm_connector_state *state, *old_state, *new_state;
>  };
>  
> +struct drm_private_obj;
> +struct drm_private_state;
> +
>  /**
>   * struct drm_private_state_funcs - atomic state functions for private objects
>   *
> @@ -167,7 +170,7 @@ struct __drm_connectors_state {
>   */
>  struct drm_private_state_funcs {
>  	/**
> -	 * @duplicate_state:
> +	 * @atomic_duplicate_state:
>  	 *
>  	 * Duplicate the current state of the private object and return it. It
>  	 * is an error to call this before obj->state has been initialized.
> @@ -177,29 +180,30 @@ struct drm_private_state_funcs {
>  	 * Duplicated atomic state or NULL when obj->state is not
>  	 * initialized or allocation failed.
>  	 */
> -	void *(*duplicate_state)(struct drm_atomic_state *state, void *obj);
> +	struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj);
>  
>  	/**
> -	 * @swap_state:
> +	 * @atomic_destroy_state:
>  	 *
> -	 * This function swaps the existing state of a private object @obj with
> -	 * it's newly created state, the pointer to which is passed as
> -	 * @obj_state_ptr.
> +	 * Frees the private object state created with @atomic_duplicate_state.
>  	 */
> -	void (*swap_state)(void *obj, void **obj_state_ptr);
> +	void (*atomic_destroy_state)(struct drm_private_obj *obj,
> +				     struct drm_private_state *state);
> +};
>  
> -	/**
> -	 * @destroy_state:
> -	 *
> -	 * Frees the private object state created with @duplicate_state.
> -	 */
> -	void (*destroy_state)(void *obj_state);
> +struct drm_private_obj {
> +	struct drm_private_state *state;
> +
> +	const struct drm_private_state_funcs *funcs;
> +};
> +
> +struct drm_private_state {
> +	struct drm_atomic_state *state;
>  };
>  
>  struct __drm_private_objs_state {
> -	void *obj;
> -	void *obj_state;
> -	const struct drm_private_state_funcs *funcs;
> +	struct drm_private_obj *ptr;
> +	struct drm_private_state *state, *old_state, *new_state;
>  };
>  
>  /**
> @@ -336,10 +340,14 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>  		struct drm_connector_state *state, struct drm_property *property,
>  		uint64_t val);
>  
> -void * __must_check
> +void drm_atomic_private_obj_init(struct drm_private_obj *obj,
> +				 struct drm_private_state *state,
> +				 const struct drm_private_state_funcs *funcs);
> +void drm_atomic_private_obj_fini(struct drm_private_obj *obj);
> +
> +struct drm_private_state * __must_check
>  drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
> -			      void *obj,
> -			      const struct drm_private_state_funcs *funcs);
> +				 struct drm_private_obj *obj);
>  
>  /**
>   * drm_atomic_get_existing_crtc_state - get crtc state, if it exists
> @@ -826,43 +834,66 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
>  		for_each_if (plane)
>  
>  /**
> - * __for_each_private_obj - iterate over all private objects
> + * for_each_oldnew_private_obj_in_state - iterate over all private objects in an atomic update
>   * @__state: &struct drm_atomic_state pointer
> - * @obj: private object iteration cursor
> - * @obj_state: private object state iteration cursor
> + * @obj: &struct drm_private_obj iteration cursor
> + * @old_obj_state: &struct drm_private_state iteration cursor for the old state
> + * @new_obj_state: &struct drm_private_state iteration cursor for the new state
>   * @__i: int iteration cursor, for macro-internal use
> - * @__funcs: &struct drm_private_state_funcs iteration cursor
>   *
> - * This macro iterates over the array containing private object data in atomic
> - * state
> + * This iterates over all private objects in an atomic update, tracking both
> + * old and new state. This is useful in places where the state delta needs
> + * to be considered, for example in atomic check functions.
>   */
> -#define __for_each_private_obj(__state, obj, obj_state, __i, __funcs)	\
> -	for ((__i) = 0;							\
> -	     (__i) < (__state)->num_private_objs &&			\
> -		     ((obj) = __drm_atomic_state_private_obj(__state, __i)->obj, \
> -		      (__funcs) = __drm_atomic_state_private_obj(__state, __i)->funcs, \
> -		      (obj_state) = __drm_atomic_state_private_obj(__state, __i)->obj_state, \
> -	      1);							\
> -	     (__i)++)							\
> +#define for_each_oldnew_private_obj_in_state(__state, obj, old_obj_state, new_obj_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->num_private_objs && \
> +		     ((obj) = __drm_atomic_state_private_obj(__state, __i)->ptr, \
> +		      (old_obj_state) = __drm_atomic_state_private_obj(__state, __i)->old_state, \
> +		      (new_obj_state) = __drm_atomic_state_private_obj(__state, __i)->new_state, 1); \
> +	     (__i)++) \
> +		for_each_if (obj)
> +
>  
>  /**
> - * for_each_private_obj - iterate over a specify type of private object
> + * for_each_old_private_obj_in_state - iterate over all private objects in an atomic update
>   * @__state: &struct drm_atomic_state pointer
> - * @obj_funcs: &struct drm_private_state_funcs function table to filter
> - * 	private objects
> - * @obj: private object iteration cursor
> - * @obj_state: private object state iteration cursor
> + * @obj: &struct drm_private_obj iteration cursor
> + * @old_obj_state: &struct drm_private_state iteration cursor for the old state
>   * @__i: int iteration cursor, for macro-internal use
> - * @__funcs: &struct drm_private_state_funcs iteration cursor
>   *
> - * This macro iterates over the private objects state array while filtering the
> - * objects based on the vfunc table that is passed as @obj_funcs. New macros
> - * can be created by passing in the vfunc table associated with a specific
> - * private object.
> + * This iterates over all private objects in an atomic update, tracking only
> + * the old state. This is useful in disable functions, where we need the old
> + * state the hardware is still in.
>   */
> -#define for_each_private_obj(__state, obj_funcs, obj, obj_state, __i, __funcs)	\
> -	__for_each_private_obj(__state, obj, obj_state, __i, __funcs)		\
> -		for_each_if (__funcs == obj_funcs)
> +#define for_each_old_private_obj_in_state(__state, obj, old_obj_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->num_private_objs && \
> +		     ((obj) = __drm_atomic_state_private_obj(__state, __i)->ptr, \
> +		      (old_obj_state) = __drm_atomic_state_private_obj(__state, __i)->old_state, 1); \
> +	     (__i)++) \
> +		for_each_if (obj)
> +
> +
> +/**
> + * for_each_new_private_obj_in_state - iterate over all private objects in an atomic update
> + * @__state: &struct drm_atomic_state pointer
> + * @obj: &struct drm_private_obj iteration cursor
> + * @new_obj_state: &struct drm_private_state iteration cursor for the new state
> + * @__i: int iteration cursor, for macro-internal use
> + *
> + * This iterates over all private objects in an atomic update, tracking only
> + * the new state. This is useful in enable functions, where we need the new state the
> + * hardware should be in when the atomic commit operation has completed.
> + */
> +#define for_each_new_private_obj_in_state(__state, obj, new_obj_state, __i) \
> +	for ((__i) = 0; \
> +	     (__i) < (__state)->num_private_objs && \
> +		     ((obj) = __drm_atomic_state_private_obj(__state, __i)->ptr, \
> +		      (new_obj_state) = __drm_atomic_state_private_obj(__state, __i)->new_state, 1); \
> +	     (__i)++) \
> +		for_each_if (obj)
> +
>  
>  /**
>   * drm_atomic_crtc_needs_modeset - compute combined modeset need
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index dd196cc0afd7..7db3438ff735 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -33,6 +33,8 @@
>  #include <drm/drm_modeset_helper.h>
>  
>  struct drm_atomic_state;
> +struct drm_private_obj;
> +struct drm_private_state;
>  
>  int drm_atomic_helper_check_modeset(struct drm_device *dev,
>  				struct drm_atomic_state *state);
> @@ -185,6 +187,8 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
>  				       u16 *red, u16 *green, u16 *blue,
>  				       uint32_t size,
>  				       struct drm_modeset_acquire_ctx *ctx);
> +void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
> +						     struct drm_private_state *state);
>  
>  /**
>   * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index 177ab6f86855..d55abb75f29a 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -404,12 +404,17 @@ struct drm_dp_payload {
>  	int vcpi;
>  };
>  
> +#define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base)
> +
>  struct drm_dp_mst_topology_state {
> +	struct drm_private_state base;
>  	int avail_slots;
>  	struct drm_atomic_state *state;
>  	struct drm_dp_mst_topology_mgr *mgr;
>  };
>  
> +#define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
> +
>  /**
>   * struct drm_dp_mst_topology_mgr - DisplayPort MST manager
>   *
> @@ -419,6 +424,11 @@ struct drm_dp_mst_topology_state {
>   */
>  struct drm_dp_mst_topology_mgr {
>  	/**
> +	 * @base: Base private object for atomic
> +	 */
> +	struct drm_private_obj base;
> +
> +	/**
>  	 * @dev: device pointer for adding i2c devices etc.
>  	 */
>  	struct drm_device *dev;
> -- 
> 2.13.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the dri-devel mailing list