On Wed, Aug 12, 2015 at 04:37:28PM +0200, Thierry Reding wrote: > From: Thierry Reding <treding@xxxxxxxxxx> > > This function can be used to duplicate an atomic state object. This is > useful for example to implement suspend/resume, where the state before > suspend can be saved and restored upon resume. > > v2: move locking to caller, be more explicit about prerequisites > > Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> > --- > drivers/gpu/drm/drm_atomic_helper.c | 80 +++++++++++++++++++++++++++++++++++++ > include/drm/drm_atomic_helper.h | 2 + > 2 files changed, 82 insertions(+) > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c > index fd06595c2ee5..1f84df3b0a5d 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -2358,6 +2358,86 @@ drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) > EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state); > > /** > + * drm_atomic_helper_duplicate_state - duplicate an atomic state object > + * @dev: DRM device > + * > + * Makes a copy of the current atomic state by looping over all objects and > + * duplicating their respective states. This is used for example by suspend/ > + * resume support code to save the state prior to suspend such that it can > + * be restored upon resume. > + * > + * Note that this treats atomic state as persistent between save and restore. > + * Drivers must make sure that this is guaranteed. s/guaranteed/is possible and won't result in confusion/ maybe? > + * > + * Calls to this function must be guarded by drm_modeset_lock_all() and > + * drm_modeset_unlock_all(). If you pass in the acquire ctx explicitly this isn't strictly true since you're using the get_*_state functions, which might return -EDEADLK. So maybe instead: "Note that if callers haven't already acquired all modeset locks this might return -EDEADLK, which must be handled by the caller using rm_modeset_backoff()." > + * > + * Returns: > + * A pointer to the copy of the atomic state object on success or an > + * ERR_PTR()-encoded error code on failure. > + */ > +struct drm_atomic_state * > +drm_atomic_helper_duplicate_state(struct drm_device *dev) > +{ > + struct drm_atomic_state *state; > + struct drm_connector *conn; > + struct drm_plane *plane; > + struct drm_crtc *crtc; > + int err = 0; > + > + if (WARN_ON(!dev->mode_config.acquire_ctx)) > + return ERR_PTR(-EINVAL); > + > + state = drm_atomic_state_alloc(dev); > + if (!state) > + return ERR_PTR(-ENOMEM); > + > + state->acquire_ctx = dev->mode_config.acquire_ctx; The hidden acquire_ctx was just a hack to avoid needing to redo _all_ driver entry points by adding a ctx parameter. I want to remove this long-term, so please don't spread it and instead just add a ctx parameter to this function. Didn't spot anything else. -Daniel > + > + drm_for_each_crtc(crtc, dev) { > + struct drm_crtc_state *crtc_state; > + > + crtc_state = drm_atomic_get_crtc_state(state, crtc); > + if (IS_ERR(crtc_state)) { > + err = PTR_ERR(crtc_state); > + goto free; > + } > + } > + > + drm_for_each_plane(plane, dev) { > + struct drm_plane_state *plane_state; > + > + plane_state = drm_atomic_get_plane_state(state, plane); > + if (IS_ERR(plane_state)) { > + err = PTR_ERR(plane_state); > + goto free; > + } > + } > + > + drm_for_each_connector(conn, dev) { > + struct drm_connector_state *conn_state; > + > + conn_state = drm_atomic_get_connector_state(state, conn); > + if (IS_ERR(conn_state)) { > + err = PTR_ERR(conn_state); > + goto free; > + } > + } > + > + /* clear the acquire context so that it isn't accidentally reused */ > + state->acquire_ctx = NULL; > + > +free: > + if (err < 0) { > + drm_atomic_state_free(state); > + state = ERR_PTR(err); > + } > + > + return state; > +} > +EXPORT_SYMBOL(drm_atomic_helper_duplicate_state); > + > +/** > * __drm_atomic_helper_connector_destroy_state - release connector state > * @connector: connector object > * @state: connector state object to release > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h > index 4ffe9dca07c4..5d27612997ce 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -118,6 +118,8 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, > struct drm_connector_state *state); > struct drm_connector_state * > drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); > +struct drm_atomic_state * > +drm_atomic_helper_duplicate_state(struct drm_device *dev); > void > __drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, > struct drm_connector_state *state); > -- > 2.4.5 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel