drm/plane: add drmm_universal_plane_alloc()

Add an alternative to drm_universal_plane_init() that allocates
and initializes a plane and registers drm_plane_cleanup() with
drmm_add_action_or_reset().

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Philipp Zabel 2020-12-10 16:38:30 +01:00
Родитель 59abba48c4
Коммит 0a1b813f06
2 изменённых файлов: 147 добавлений и 29 удалений

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

@ -30,6 +30,7 @@
#include <drm/drm_file.h>
#include <drm/drm_crtc.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_managed.h>
#include <drm/drm_vblank.h>
#include "drm_crtc_internal.h"
@ -152,31 +153,16 @@ done:
return 0;
}
/**
* drm_universal_plane_init - Initialize a new universal plane object
* @dev: DRM device
* @plane: plane object to init
* @possible_crtcs: bitmask of possible CRTCs
* @funcs: callbacks for the new plane
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
* @format_modifiers: array of struct drm_format modifiers terminated by
* DRM_FORMAT_MOD_INVALID
* @type: type of plane (overlay, primary, cursor)
* @name: printf style format string for the plane name, or NULL for default name
*
* Initializes a plane object of type @type.
*
* Returns:
* Zero on success, error code on failure.
*/
int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, ...)
__printf(9, 0)
static int __drm_universal_plane_init(struct drm_device *dev,
struct drm_plane *plane,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats,
unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, va_list ap)
{
struct drm_mode_config *config = &dev->mode_config;
unsigned int format_modifier_count = 0;
@ -237,11 +223,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
}
if (name) {
va_list ap;
va_start(ap, name);
plane->name = kvasprintf(GFP_KERNEL, name, ap);
va_end(ap);
} else {
plane->name = kasprintf(GFP_KERNEL, "plane-%d",
drm_num_planes(dev));
@ -286,8 +268,102 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
return 0;
}
/**
* drm_universal_plane_init - Initialize a new universal plane object
* @dev: DRM device
* @plane: plane object to init
* @possible_crtcs: bitmask of possible CRTCs
* @funcs: callbacks for the new plane
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
* @format_modifiers: array of struct drm_format modifiers terminated by
* DRM_FORMAT_MOD_INVALID
* @type: type of plane (overlay, primary, cursor)
* @name: printf style format string for the plane name, or NULL for default name
*
* Initializes a plane object of type @type. The &drm_plane_funcs.destroy hook
* should call drm_plane_cleanup() and kfree() the plane structure. The plane
* structure should not be allocated with devm_kzalloc().
*
* Note: consider using drmm_universal_plane_alloc() instead of
* drm_universal_plane_init() to let the DRM managed resource infrastructure
* take care of cleanup and deallocation.
*
* Returns:
* Zero on success, error code on failure.
*/
int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, ...)
{
va_list ap;
int ret;
WARN_ON(!funcs->destroy);
va_start(ap, name);
ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
formats, format_count, format_modifiers,
type, name, ap);
va_end(ap);
return ret;
}
EXPORT_SYMBOL(drm_universal_plane_init);
static void drmm_universal_plane_alloc_release(struct drm_device *dev, void *ptr)
{
struct drm_plane *plane = ptr;
if (WARN_ON(!plane->dev))
return;
drm_plane_cleanup(plane);
}
void *__drmm_universal_plane_alloc(struct drm_device *dev, size_t size,
size_t offset, uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, ...)
{
void *container;
struct drm_plane *plane;
va_list ap;
int ret;
if (WARN_ON(!funcs || funcs->destroy))
return ERR_PTR(-EINVAL);
container = drmm_kzalloc(dev, size, GFP_KERNEL);
if (!container)
return ERR_PTR(-ENOMEM);
plane = container + offset;
va_start(ap, name);
ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
formats, format_count, format_modifiers,
type, name, ap);
va_end(ap);
if (ret)
return ERR_PTR(ret);
ret = drmm_add_action_or_reset(dev, drmm_universal_plane_alloc_release,
plane);
if (ret)
return ERR_PTR(ret);
return container;
}
EXPORT_SYMBOL(__drmm_universal_plane_alloc);
int drm_plane_register_all(struct drm_device *dev)
{
unsigned int num_planes = 0;

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

@ -764,6 +764,48 @@ int drm_plane_init(struct drm_device *dev,
bool is_primary);
void drm_plane_cleanup(struct drm_plane *plane);
__printf(10, 11)
void *__drmm_universal_plane_alloc(struct drm_device *dev,
size_t size, size_t offset,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats,
unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type plane_type,
const char *name, ...);
/**
* drmm_universal_plane_alloc - Allocate and initialize an universal plane object
* @dev: DRM device
* @type: the type of the struct which contains struct &drm_plane
* @member: the name of the &drm_plane within @type
* @possible_crtcs: bitmask of possible CRTCs
* @funcs: callbacks for the new plane
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
* @format_modifiers: array of struct drm_format modifiers terminated by
* DRM_FORMAT_MOD_INVALID
* @plane_type: type of plane (overlay, primary, cursor)
* @name: printf style format string for the plane name, or NULL for default name
*
* Allocates and initializes a plane object of type @type. Cleanup is
* automatically handled through registering drm_plane_cleanup() with
* drmm_add_action().
*
* The @drm_plane_funcs.destroy hook must be NULL.
*
* Returns:
* Pointer to new plane, or ERR_PTR on failure.
*/
#define drmm_universal_plane_alloc(dev, type, member, possible_crtcs, funcs, formats, \
format_count, format_modifiers, plane_type, name, ...) \
((type *)__drmm_universal_plane_alloc(dev, sizeof(type), \
offsetof(type, member), \
possible_crtcs, funcs, formats, \
format_count, format_modifiers, \
plane_type, name, ##__VA_ARGS__))
/**
* drm_plane_index - find the index of a registered plane
* @plane: plane to find index for