drm/vblank: Register drmm cleanup action once per drm_vblank_crtc

Since we'll be allocating resources for kthread_create_worker() in the
next commit (which could fail and require us to clean up the mess),
let's simplify the cleanup process a bit by registering a
drm_vblank_init_release() action for each drm_vblank_crtc so they're
still cleaned up if we fail to initialize one of them.

Changes since v3:
* Use drmm_add_action_or_reset() - Daniel Vetter

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: dri-devel@lists.freedesktop.org
Cc: nouveau@lists.freedesktop.org
Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Acked-by: Dave Airlie <airlied@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200627194657.156514-2-lyude@redhat.com
This commit is contained in:
Lyude Paul 2020-04-14 12:34:52 -04:00
Родитель 9410113fc3
Коммит a7e5e06de2
1 изменённых файлов: 10 добавлений и 13 удалений

Просмотреть файл

@ -492,16 +492,12 @@ static void vblank_disable_fn(struct timer_list *t)
static void drm_vblank_init_release(struct drm_device *dev, void *ptr) static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
{ {
unsigned int pipe; struct drm_vblank_crtc *vblank = ptr;
for (pipe = 0; pipe < dev->num_crtcs; pipe++) { drm_WARN_ON(dev, READ_ONCE(vblank->enabled) &&
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; drm_core_check_feature(dev, DRIVER_MODESET));
drm_WARN_ON(dev, READ_ONCE(vblank->enabled) && del_timer_sync(&vblank->disable_timer);
drm_core_check_feature(dev, DRIVER_MODESET));
del_timer_sync(&vblank->disable_timer);
}
} }
/** /**
@ -511,7 +507,7 @@ static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
* *
* This function initializes vblank support for @num_crtcs display pipelines. * This function initializes vblank support for @num_crtcs display pipelines.
* Cleanup is handled automatically through a cleanup function added with * Cleanup is handled automatically through a cleanup function added with
* drmm_add_action(). * drmm_add_action_or_reset().
* *
* Returns: * Returns:
* Zero on success or a negative error code on failure. * Zero on success or a negative error code on failure.
@ -530,10 +526,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
dev->num_crtcs = num_crtcs; dev->num_crtcs = num_crtcs;
ret = drmm_add_action(dev, drm_vblank_init_release, NULL);
if (ret)
return ret;
for (i = 0; i < num_crtcs; i++) { for (i = 0; i < num_crtcs; i++) {
struct drm_vblank_crtc *vblank = &dev->vblank[i]; struct drm_vblank_crtc *vblank = &dev->vblank[i];
@ -542,6 +534,11 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
init_waitqueue_head(&vblank->queue); init_waitqueue_head(&vblank->queue);
timer_setup(&vblank->disable_timer, vblank_disable_fn, 0); timer_setup(&vblank->disable_timer, vblank_disable_fn, 0);
seqlock_init(&vblank->seqlock); seqlock_init(&vblank->seqlock);
ret = drmm_add_action_or_reset(dev, drm_vblank_init_release,
vblank);
if (ret)
return ret;
} }
return 0; return 0;