Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/modeset-helper: Add simple modeset suspend/resume helpers

Add drm_mode_config_helper_suspend/resume() which takes care of
atomic modeset suspend/resume for simple use cases.
The suspend state is stored in struct drm_mode_config.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20171106191812.38927-3-noralf@tronnes.org

+88
+76
drivers/gpu/drm/drm_modeset_helper.c
··· 20 20 * OF THIS SOFTWARE. 21 21 */ 22 22 23 + #include <drm/drm_atomic_helper.h> 24 + #include <drm/drm_crtc_helper.h> 25 + #include <drm/drm_fb_helper.h> 23 26 #include <drm/drm_modeset_helper.h> 24 27 #include <drm/drm_plane_helper.h> 25 28 ··· 159 156 NULL); 160 157 } 161 158 EXPORT_SYMBOL(drm_crtc_init); 159 + 160 + /** 161 + * drm_mode_config_helper_suspend - Modeset suspend helper 162 + * @dev: DRM device 163 + * 164 + * This helper function takes care of suspending the modeset side. It disables 165 + * output polling if initialized, suspends fbdev if used and finally calls 166 + * drm_atomic_helper_suspend(). 167 + * If suspending fails, fbdev and polling is re-enabled. 168 + * 169 + * Returns: 170 + * Zero on success, negative error code on error. 171 + * 172 + * See also: 173 + * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked(). 174 + */ 175 + int drm_mode_config_helper_suspend(struct drm_device *dev) 176 + { 177 + struct drm_atomic_state *state; 178 + 179 + if (!dev) 180 + return 0; 181 + 182 + drm_kms_helper_poll_disable(dev); 183 + drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1); 184 + state = drm_atomic_helper_suspend(dev); 185 + if (IS_ERR(state)) { 186 + drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); 187 + drm_kms_helper_poll_enable(dev); 188 + return PTR_ERR(state); 189 + } 190 + 191 + dev->mode_config.suspend_state = state; 192 + 193 + return 0; 194 + } 195 + EXPORT_SYMBOL(drm_mode_config_helper_suspend); 196 + 197 + /** 198 + * drm_mode_config_helper_resume - Modeset resume helper 199 + * @dev: DRM device 200 + * 201 + * This helper function takes care of resuming the modeset side. It calls 202 + * drm_atomic_helper_resume(), resumes fbdev if used and enables output polling 203 + * if initiaized. 204 + * 205 + * Returns: 206 + * Zero on success, negative error code on error. 207 + * 208 + * See also: 209 + * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable(). 210 + */ 211 + int drm_mode_config_helper_resume(struct drm_device *dev) 212 + { 213 + int ret; 214 + 215 + if (!dev) 216 + return 0; 217 + 218 + if (WARN_ON(!dev->mode_config.suspend_state)) 219 + return -EINVAL; 220 + 221 + ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state); 222 + if (ret) 223 + DRM_ERROR("Failed to resume (%d)\n", ret); 224 + dev->mode_config.suspend_state = NULL; 225 + 226 + drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); 227 + drm_kms_helper_poll_enable(dev); 228 + 229 + return ret; 230 + } 231 + EXPORT_SYMBOL(drm_mode_config_helper_resume);
+9
include/drm/drm_mode_config.h
··· 753 753 /* cursor size */ 754 754 uint32_t cursor_width, cursor_height; 755 755 756 + /** 757 + * @suspend_state: 758 + * 759 + * Atomic state when suspended. 760 + * Set by drm_mode_config_helper_suspend() and cleared by 761 + * drm_mode_config_helper_resume(). 762 + */ 763 + struct drm_atomic_state *suspend_state; 764 + 756 765 const struct drm_mode_config_helper_funcs *helper_private; 757 766 }; 758 767
+3
include/drm/drm_modeset_helper.h
··· 34 34 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, 35 35 const struct drm_crtc_funcs *funcs); 36 36 37 + int drm_mode_config_helper_suspend(struct drm_device *dev); 38 + int drm_mode_config_helper_resume(struct drm_device *dev); 39 + 37 40 #endif