Commit c8d54cd5 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

[media] media: Add an API to manage entity enumerations

This is useful in e.g. knowing whether certain operations have already
been performed for an entity. The users include the framework itself (for
graph walking) and a number of drivers.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 665faa97
......@@ -70,6 +70,46 @@ static inline const char *intf_type(struct media_interface *intf)
}
};
/**
* __media_entity_enum_init - Initialise an entity enumeration
*
* @ent_enum: Entity enumeration to be initialised
* @idx_max: Maximum number of entities in the enumeration
*
* Returns zero on success or a negative error code.
*/
__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum,
int idx_max)
{
if (idx_max > MEDIA_ENTITY_ENUM_MAX_ID) {
ent_enum->bmap = kcalloc(DIV_ROUND_UP(idx_max, BITS_PER_LONG),
sizeof(long), GFP_KERNEL);
if (!ent_enum->bmap)
return -ENOMEM;
} else {
ent_enum->bmap = ent_enum->prealloc_bmap;
}
bitmap_zero(ent_enum->bmap, idx_max);
ent_enum->idx_max = idx_max;
return 0;
}
EXPORT_SYMBOL_GPL(__media_entity_enum_init);
/**
* media_entity_enum_cleanup - Release resources of an entity enumeration
*
* @e: Entity enumeration to be released
*/
void media_entity_enum_cleanup(struct media_entity_enum *ent_enum)
{
if (ent_enum->bmap != ent_enum->prealloc_bmap)
kfree(ent_enum->bmap);
ent_enum->bmap = NULL;
}
EXPORT_SYMBOL_GPL(media_entity_enum_cleanup);
/**
* dev_dbg_obj - Prints in debug mode a change on some object
*
......
......@@ -341,6 +341,21 @@ struct media_device {
/* media_devnode to media_device */
#define to_media_device(node) container_of(node, struct media_device, devnode)
/**
* media_entity_enum_init - Initialise an entity enumeration
*
* @e: Entity enumeration to be initialised
* @mdev: The related media device
*
* Returns zero on success or a negative error code.
*/
static inline __must_check int media_entity_enum_init(
struct media_entity_enum *ent_enum, struct media_device *mdev)
{
return __media_entity_enum_init(ent_enum,
mdev->entity_internal_idx_max + 1);
}
/**
* media_device_init() - Initializes a media device element
*
......
......@@ -23,7 +23,7 @@
#ifndef _MEDIA_ENTITY_H
#define _MEDIA_ENTITY_H
#include <linux/bitops.h>
#include <linux/bitmap.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/media.h>
......@@ -71,6 +71,32 @@ struct media_gobj {
struct list_head list;
};
#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16
#define MEDIA_ENTITY_ENUM_MAX_ID 64
/*
* The number of pads can't be bigger than the number of entities,
* as the worse-case scenario is to have one entity linked up to
* MEDIA_ENTITY_ENUM_MAX_ID - 1 entities.
*/
#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1)
/**
* struct media_entity_enum - An enumeration of media entities.
*
* @prealloc_bmap: Pre-allocated space reserved for media entities if the
* total number of entities does not exceed
* MEDIA_ENTITY_ENUM_MAX_ID.
* @bmap: Bit map in which each bit represents one entity at struct
* media_entity->internal_idx.
* @idx_max: Number of bits in bmap
*/
struct media_entity_enum {
DECLARE_BITMAP(prealloc_bmap, MEDIA_ENTITY_ENUM_MAX_ID);
unsigned long *bmap;
int idx_max;
};
struct media_pipeline {
};
......@@ -329,15 +355,114 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)
}
}
#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16
#define MEDIA_ENTITY_ENUM_MAX_ID 64
__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum,
int idx_max);
void media_entity_enum_cleanup(struct media_entity_enum *e);
/*
* The number of pads can't be bigger than the number of entities,
* as the worse-case scenario is to have one entity linked up to
* MEDIA_ENTITY_ENUM_MAX_ID - 1 entities.
/**
* media_entity_enum_zero - Clear the entire enum
*
* @e: Entity enumeration to be cleared
*/
#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1)
static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum)
{
bitmap_zero(ent_enum->bmap, ent_enum->idx_max);
}
/**
* media_entity_enum_set - Mark a single entity in the enum
*
* @e: Entity enumeration
* @entity: Entity to be marked
*/
static inline void media_entity_enum_set(struct media_entity_enum *ent_enum,
struct media_entity *entity)
{
if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
return;
__set_bit(entity->internal_idx, ent_enum->bmap);
}
/**
* media_entity_enum_clear - Unmark a single entity in the enum
*
* @e: Entity enumeration
* @entity: Entity to be unmarked
*/
static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum,
struct media_entity *entity)
{
if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
return;
__clear_bit(entity->internal_idx, ent_enum->bmap);
}
/**
* media_entity_enum_test - Test whether the entity is marked
*
* @e: Entity enumeration
* @entity: Entity to be tested
*
* Returns true if the entity was marked.
*/
static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum,
struct media_entity *entity)
{
if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
return true;
return test_bit(entity->internal_idx, ent_enum->bmap);
}
/**
* media_entity_enum_test - Test whether the entity is marked, and mark it
*
* @e: Entity enumeration
* @entity: Entity to be tested
*
* Returns true if the entity was marked, and mark it before doing so.
*/
static inline bool media_entity_enum_test_and_set(
struct media_entity_enum *ent_enum, struct media_entity *entity)
{
if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
return true;
return __test_and_set_bit(entity->internal_idx, ent_enum->bmap);
}
/**
* media_entity_enum_test - Test whether the entire enum is empty
*
* @e: Entity enumeration
* @entity: Entity to be tested
*
* Returns true if the entity was marked.
*/
static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum)
{
return bitmap_empty(ent_enum->bmap, ent_enum->idx_max);
}
/**
* media_entity_enum_intersects - Test whether two enums intersect
*
* @e: First entity enumeration
* @f: Second entity enumeration
*
* Returns true if entity enumerations e and f intersect, otherwise false.
*/
static inline bool media_entity_enum_intersects(
struct media_entity_enum *ent_enum1,
struct media_entity_enum *ent_enum2)
{
WARN_ON(ent_enum1->idx_max != ent_enum2->idx_max);
return bitmap_intersects(ent_enum1->bmap, ent_enum2->bmap,
min(ent_enum1->idx_max, ent_enum2->idx_max));
}
struct media_entity_graph {
struct {
......
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