Browse Source

Merge tag 'drm-misc-fixes-2017-08-18' of git://anongit.freedesktop.org/git/drm-misc into drm-fixes

Core Changes:
- Fix framebuffer leak in setplane error condition (Nikil)
- Prevent BUG in atomic_ioctl by properly resetting state on EDEADLK (Maarten)
- Add missing return in atomic_check_only if atomic_check fails (Maarten)

Driver Changes:
- rockchip: Don't try to suspend if device not initialized (Jeffy)

Cc: Jeffy Chen <jeffy.chen@rock-chips.com>
Cc: Nikhil Mahale <nmahale@nvidia.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

* tag 'drm-misc-fixes-2017-08-18' of git://anongit.freedesktop.org/git/drm-misc:
  drm/atomic: If the atomic check fails, return its value first
  drm/atomic: Handle -EDEADLK with out-fences correctly
  drm: Fix framebuffer leak
  drm/rockchip: Fix suspend crash when drm is not bound
Dave Airlie 8 years ago
parent
commit
b313f780de

+ 8 - 3
drivers/gpu/drm/drm_atomic.c

@@ -1655,6 +1655,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
 	if (config->funcs->atomic_check)
 	if (config->funcs->atomic_check)
 		ret = config->funcs->atomic_check(state->dev, state);
 		ret = config->funcs->atomic_check(state->dev, state);
 
 
+	if (ret)
+		return ret;
+
 	if (!state->allow_modeset) {
 	if (!state->allow_modeset) {
 		for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
 		for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
 			if (drm_atomic_crtc_needs_modeset(crtc_state)) {
 			if (drm_atomic_crtc_needs_modeset(crtc_state)) {
@@ -1665,7 +1668,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
 		}
 		}
 	}
 	}
 
 
-	return ret;
+	return 0;
 }
 }
 EXPORT_SYMBOL(drm_atomic_check_only);
 EXPORT_SYMBOL(drm_atomic_check_only);
 
 
@@ -2167,10 +2170,10 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 	struct drm_atomic_state *state;
 	struct drm_atomic_state *state;
 	struct drm_modeset_acquire_ctx ctx;
 	struct drm_modeset_acquire_ctx ctx;
 	struct drm_plane *plane;
 	struct drm_plane *plane;
-	struct drm_out_fence_state *fence_state = NULL;
+	struct drm_out_fence_state *fence_state;
 	unsigned plane_mask;
 	unsigned plane_mask;
 	int ret = 0;
 	int ret = 0;
-	unsigned int i, j, num_fences = 0;
+	unsigned int i, j, num_fences;
 
 
 	/* disallow for drivers not supporting atomic: */
 	/* disallow for drivers not supporting atomic: */
 	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
 	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
@@ -2211,6 +2214,8 @@ retry:
 	plane_mask = 0;
 	plane_mask = 0;
 	copied_objs = 0;
 	copied_objs = 0;
 	copied_props = 0;
 	copied_props = 0;
+	fence_state = NULL;
+	num_fences = 0;
 
 
 	for (i = 0; i < arg->count_objs; i++) {
 	for (i = 0; i < arg->count_objs; i++) {
 		uint32_t obj_id, count_props;
 		uint32_t obj_id, count_props;

+ 1 - 0
drivers/gpu/drm/drm_plane.c

@@ -601,6 +601,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
 
 
 		crtc = drm_crtc_find(dev, plane_req->crtc_id);
 		crtc = drm_crtc_find(dev, plane_req->crtc_id);
 		if (!crtc) {
 		if (!crtc) {
+			drm_framebuffer_put(fb);
 			DRM_DEBUG_KMS("Unknown crtc ID %d\n",
 			DRM_DEBUG_KMS("Unknown crtc ID %d\n",
 				      plane_req->crtc_id);
 				      plane_req->crtc_id);
 			return -ENOENT;
 			return -ENOENT;

+ 10 - 2
drivers/gpu/drm/rockchip/rockchip_drm_drv.c

@@ -275,11 +275,15 @@ static void rockchip_drm_fb_resume(struct drm_device *drm)
 static int rockchip_drm_sys_suspend(struct device *dev)
 static int rockchip_drm_sys_suspend(struct device *dev)
 {
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 	struct drm_device *drm = dev_get_drvdata(dev);
-	struct rockchip_drm_private *priv = drm->dev_private;
+	struct rockchip_drm_private *priv;
+
+	if (!drm)
+		return 0;
 
 
 	drm_kms_helper_poll_disable(drm);
 	drm_kms_helper_poll_disable(drm);
 	rockchip_drm_fb_suspend(drm);
 	rockchip_drm_fb_suspend(drm);
 
 
+	priv = drm->dev_private;
 	priv->state = drm_atomic_helper_suspend(drm);
 	priv->state = drm_atomic_helper_suspend(drm);
 	if (IS_ERR(priv->state)) {
 	if (IS_ERR(priv->state)) {
 		rockchip_drm_fb_resume(drm);
 		rockchip_drm_fb_resume(drm);
@@ -293,8 +297,12 @@ static int rockchip_drm_sys_suspend(struct device *dev)
 static int rockchip_drm_sys_resume(struct device *dev)
 static int rockchip_drm_sys_resume(struct device *dev)
 {
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 	struct drm_device *drm = dev_get_drvdata(dev);
-	struct rockchip_drm_private *priv = drm->dev_private;
+	struct rockchip_drm_private *priv;
+
+	if (!drm)
+		return 0;
 
 
+	priv = drm->dev_private;
 	drm_atomic_helper_resume(drm, priv->state);
 	drm_atomic_helper_resume(drm, priv->state);
 	rockchip_drm_fb_resume(drm);
 	rockchip_drm_fb_resume(drm);
 	drm_kms_helper_poll_enable(drm);
 	drm_kms_helper_poll_enable(drm);