Commit c23d686f authored by Daniel Vetter's avatar Daniel Vetter

drm: Manage drm_vblank_cleanup with drmm_

Nothing special here, except that this is the first time that we
automatically clean up something that's initialized with an explicit
driver call. But the cleanup was done at the very end of the release
sequence for all drivers, and that's still the case. At least without
more uses of drmm_ through explicit driver calls.

Also for this one we need drmm_kcalloc, so lets add those.

The motivation here is to allow us to remove the explicit calls to
drm_dev_fini() from all drivers.

v2: Sort includes (Laurent)

v3: Motivate the change in the commit message better (Sam)
Acked-by: default avatarSam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200323144950.3018436-25-daniel.vetter@ffwll.ch
parent 641b9103
...@@ -751,7 +751,6 @@ EXPORT_SYMBOL(devm_drm_dev_init); ...@@ -751,7 +751,6 @@ EXPORT_SYMBOL(devm_drm_dev_init);
*/ */
void drm_dev_fini(struct drm_device *dev) void drm_dev_fini(struct drm_device *dev)
{ {
drm_vblank_cleanup(dev);
} }
EXPORT_SYMBOL(drm_dev_fini); EXPORT_SYMBOL(drm_dev_fini);
......
...@@ -94,7 +94,6 @@ void drm_managed_release(struct drm_device *dev); ...@@ -94,7 +94,6 @@ void drm_managed_release(struct drm_device *dev);
/* drm_vblank.c */ /* drm_vblank.c */
void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe); void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
void drm_vblank_cleanup(struct drm_device *dev);
/* IOCTLS */ /* IOCTLS */
int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_framebuffer.h> #include <drm/drm_framebuffer.h>
#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
...@@ -425,14 +426,10 @@ static void vblank_disable_fn(struct timer_list *t) ...@@ -425,14 +426,10 @@ static void vblank_disable_fn(struct timer_list *t)
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
} }
void drm_vblank_cleanup(struct drm_device *dev) static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
{ {
unsigned int pipe; unsigned int pipe;
/* Bail if the driver didn't call drm_vblank_init() */
if (dev->num_crtcs == 0)
return;
for (pipe = 0; pipe < dev->num_crtcs; pipe++) { for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
...@@ -441,10 +438,6 @@ void drm_vblank_cleanup(struct drm_device *dev) ...@@ -441,10 +438,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
del_timer_sync(&vblank->disable_timer); del_timer_sync(&vblank->disable_timer);
} }
kfree(dev->vblank);
dev->num_crtcs = 0;
} }
/** /**
...@@ -453,25 +446,29 @@ void drm_vblank_cleanup(struct drm_device *dev) ...@@ -453,25 +446,29 @@ void drm_vblank_cleanup(struct drm_device *dev)
* @num_crtcs: number of CRTCs supported by @dev * @num_crtcs: number of CRTCs supported by @dev
* *
* This function initializes vblank support for @num_crtcs display pipelines. * This function initializes vblank support for @num_crtcs display pipelines.
* Cleanup is handled by the DRM core, or through calling drm_dev_fini() for * Cleanup is handled automatically through a cleanup function added with
* drivers with a &drm_driver.release callback. * drmm_add_action().
* *
* Returns: * Returns:
* Zero on success or a negative error code on failure. * Zero on success or a negative error code on failure.
*/ */
int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
{ {
int ret = -ENOMEM; int ret;
unsigned int i; unsigned int i;
spin_lock_init(&dev->vbl_lock); spin_lock_init(&dev->vbl_lock);
spin_lock_init(&dev->vblank_time_lock); spin_lock_init(&dev->vblank_time_lock);
dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
if (!dev->vblank)
return -ENOMEM;
dev->num_crtcs = num_crtcs; dev->num_crtcs = num_crtcs;
dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL); ret = drmm_add_action(dev, drm_vblank_init_release, NULL);
if (!dev->vblank) if (ret)
goto err; 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];
...@@ -486,10 +483,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) ...@@ -486,10 +483,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
return 0; return 0;
err:
dev->num_crtcs = 0;
return ret;
} }
EXPORT_SYMBOL(drm_vblank_init); EXPORT_SYMBOL(drm_vblank_init);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#define _DRM_MANAGED_H_ #define _DRM_MANAGED_H_
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/overflow.h>
#include <linux/types.h> #include <linux/types.h>
struct drm_device; struct drm_device;
...@@ -31,6 +32,21 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp) ...@@ -31,6 +32,21 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
{ {
return drmm_kmalloc(dev, size, gfp | __GFP_ZERO); return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
} }
static inline void *drmm_kmalloc_array(struct drm_device *dev,
size_t n, size_t size, gfp_t flags)
{
size_t bytes;
if (unlikely(check_mul_overflow(n, size, &bytes)))
return NULL;
return drmm_kmalloc(dev, bytes, flags);
}
static inline void *drmm_kcalloc(struct drm_device *dev,
size_t n, size_t size, gfp_t flags)
{
return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
}
char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp); char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
void drmm_kfree(struct drm_device *dev, void *data); void drmm_kfree(struct drm_device *dev, void *data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment