On Tue, Sep 08, 2015 at 03:00:45PM +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 > v3: explicitly pass lock acquisition context, improve kerneldoc > > Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> Applied to drm-misc with 2 tiny spelling fixes in the kerneldoc. Thanks, Daniel > --- > drivers/gpu/drm/drm_atomic_helper.c | 78 +++++++++++++++++++++++++++++++++++++ > include/drm/drm_atomic_helper.h | 3 ++ > 2 files changed, 81 insertions(+) > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c > index 634aa617811b..3232f4b838e4 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -2349,6 +2349,84 @@ 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 > + * @ctx: lock acquisition context > + * > + * Makes a copy of the current atomic state by looping over all objects and > + * duplicating their respective states. > + * > + * Note that this treats atomic state as persistent between save and restore. > + * Drivers must make sure that this is possible and won't result in confusion > + * or erroneous behaviour. > + * > + * Note that if callers haven't already acquired all modeset locks this might > + * return -EDEADLK, which must be handled by calling drm_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_modeset_acquire_ctx *ctx) > +{ > + struct drm_atomic_state *state; > + struct drm_connector *conn; > + struct drm_plane *plane; > + struct drm_crtc *crtc; > + int err = 0; > + > + state = drm_atomic_state_alloc(dev); > + if (!state) > + return ERR_PTR(-ENOMEM); > + > + state->acquire_ctx = ctx; > + > + 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..1547eb43c14a 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -118,6 +118,9 @@ __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, > + struct drm_modeset_acquire_ctx *ctx); > void > __drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, > struct drm_connector_state *state); > -- > 2.5.0 > -- 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