diff options
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index b676006a95a0..22b8f5eced80 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -173,28 +173,37 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) | |||
| 173 | static void exynos_drm_preclose(struct drm_device *dev, | 173 | static void exynos_drm_preclose(struct drm_device *dev, |
| 174 | struct drm_file *file) | 174 | struct drm_file *file) |
| 175 | { | 175 | { |
| 176 | exynos_drm_subdrv_close(dev, file); | ||
| 177 | } | ||
| 178 | |||
| 179 | static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) | ||
| 180 | { | ||
| 176 | struct exynos_drm_private *private = dev->dev_private; | 181 | struct exynos_drm_private *private = dev->dev_private; |
| 177 | struct drm_pending_vblank_event *e, *t; | 182 | struct drm_pending_vblank_event *v, *vt; |
| 183 | struct drm_pending_event *e, *et; | ||
| 178 | unsigned long flags; | 184 | unsigned long flags; |
| 179 | 185 | ||
| 180 | /* release events of current file */ | 186 | if (!file->driver_priv) |
| 187 | return; | ||
| 188 | |||
| 189 | /* Release all events not unhandled by page flip handler. */ | ||
| 181 | spin_lock_irqsave(&dev->event_lock, flags); | 190 | spin_lock_irqsave(&dev->event_lock, flags); |
| 182 | list_for_each_entry_safe(e, t, &private->pageflip_event_list, | 191 | list_for_each_entry_safe(v, vt, &private->pageflip_event_list, |
| 183 | base.link) { | 192 | base.link) { |
| 184 | if (e->base.file_priv == file) { | 193 | if (v->base.file_priv == file) { |
| 185 | list_del(&e->base.link); | 194 | list_del(&v->base.link); |
| 186 | e->base.destroy(&e->base); | 195 | drm_vblank_put(dev, v->pipe); |
| 196 | v->base.destroy(&v->base); | ||
| 187 | } | 197 | } |
| 188 | } | 198 | } |
| 189 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 190 | 199 | ||
| 191 | exynos_drm_subdrv_close(dev, file); | 200 | /* Release all events handled by page flip handler but not freed. */ |
| 192 | } | 201 | list_for_each_entry_safe(e, et, &file->event_list, link) { |
| 202 | list_del(&e->link); | ||
| 203 | e->destroy(e); | ||
| 204 | } | ||
| 205 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 193 | 206 | ||
| 194 | static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) | ||
| 195 | { | ||
| 196 | if (!file->driver_priv) | ||
| 197 | return; | ||
| 198 | 207 | ||
| 199 | kfree(file->driver_priv); | 208 | kfree(file->driver_priv); |
| 200 | file->driver_priv = NULL; | 209 | file->driver_priv = NULL; |
