Some drivers might want to use the modifier_info field of struct
drm_framebuffer to hold struct drm_afbc. The memory for the latter must
be managed by the driver. To eliminate the need to modify existing
invocations of kfree(fb), add a function to allocate struct drm_framebuffer
and its associated struct drm_afbc in one chunk.

Signed-off-by: Andrzej Pietrasiewicz <andrze...@collabora.com>
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 32 ++++++++++++++++++++
 include/drm/drm_gem_framebuffer_helper.h     |  1 +
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index e20f4d00b0a5..0338f303f988 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -21,6 +21,13 @@
 #include <drm/drm_modeset_helper.h>
 #include <drm/drm_simple_kms_helper.h>
 
+#define DRM_ALIGN_MASK(type) \
+       (__alignof__(type) - 1)
+#define DRM_INFO_OFFSET(type1, type2)  \
+       ((sizeof(type1) + DRM_ALIGN_MASK(type2)) & ~DRM_ALIGN_MASK(type2))
+#define DRM_COMPOUND_SIZE(type1, type2) \
+       (DRM_INFO_OFFSET(type1, type2) + sizeof(type2))
+
 #define AFBC_HEADER_SIZE               16
 #define AFBC_TH_LAYOUT_ALIGNMENT       8
 #define AFBC_SUPERBLOCK_PIXELS         256
@@ -59,6 +66,31 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
drm_framebuffer *fb,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
 
+/**
+ * drm_gem_fb_alloc_with_afbc() - Allocate struct drm_framebuffer together
+ *                               with a struct drm_afbc for easier freeing
+ *                               and assign drm_framebuffer's modifier_info
+ *
+ * Returns:
+ * Pointer to drm_framebuffer on success or NULL
+ */
+struct drm_framebuffer *drm_gem_fb_alloc_with_afbc(void)
+{
+       struct drm_framebuffer *fb;
+
+       /* alloc in one chunk to ease freeing */
+       fb = kzalloc(DRM_COMPOUND_SIZE(struct drm_framebuffer, struct drm_afbc),
+                    GFP_KERNEL);
+       if (!fb)
+               return NULL;
+
+       fb->modifier_info =
+               fb + DRM_INFO_OFFSET(struct drm_framebuffer, struct drm_afbc);
+
+       return fb;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_alloc_with_afbc);
+
 int drm_gem_fb_init_with_funcs(struct drm_framebuffer *fb,
                               struct drm_device *dev,
                               const struct drm_mode_fb_cmd2 *mode_cmd,
diff --git a/include/drm/drm_gem_framebuffer_helper.h 
b/include/drm/drm_gem_framebuffer_helper.h
index 3d6015194b3c..4e7b1e2c765b 100644
--- a/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -42,6 +42,7 @@ struct drm_afbc {
 
 struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
                                          unsigned int plane);
+struct drm_framebuffer *drm_gem_fb_alloc_with_afbc(void);
 int drm_gem_fb_init_with_funcs(struct drm_framebuffer *fb,
                               struct drm_device *dev,
                               const struct drm_mode_fb_cmd2 *mode_cmd,
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to