* [PATCH 1/5] media: Use all bits of an enumeration
2016-01-27 13:50 [PATCH 0/5] Unify MC graph power management code Sakari Ailus
@ 2016-01-27 13:50 ` Sakari Ailus
2016-01-27 13:50 ` [PATCH 2/5] media: Always keep a graph walk large enough around Sakari Ailus
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Sakari Ailus @ 2016-01-27 13:50 UTC (permalink / raw)
To: linux-media
The allocation takes place in longs. Assign the size of the enum
accordingly.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/media-entity.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index e89d85a..2c579f4 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -73,8 +73,9 @@ static inline const char *intf_type(struct media_interface *intf)
__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum,
int idx_max)
{
- ent_enum->bmap = kcalloc(DIV_ROUND_UP(idx_max, BITS_PER_LONG),
- sizeof(long), GFP_KERNEL);
+ idx_max = ALIGN(idx_max, BITS_PER_LONG);
+ ent_enum->bmap = kcalloc(idx_max / BITS_PER_LONG, sizeof(long),
+ GFP_KERNEL);
if (!ent_enum->bmap)
return -ENOMEM;
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 2/5] media: Always keep a graph walk large enough around
2016-01-27 13:50 [PATCH 0/5] Unify MC graph power management code Sakari Ailus
2016-01-27 13:50 ` [PATCH 1/5] media: Use all bits of an enumeration Sakari Ailus
@ 2016-01-27 13:50 ` Sakari Ailus
2016-01-27 14:33 ` kbuild test robot
2016-01-27 13:50 ` [PATCH 3/5] v4l: Add generic pipeline power management code Sakari Ailus
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Sakari Ailus @ 2016-01-27 13:50 UTC (permalink / raw)
To: linux-media
Re-create the graph walk object as needed in order to have one large enough
available for all entities in the graph.
This enumeration is used for pipeline power management in the future.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/media-device.c | 21 +++++++++++++++++++++
include/media/media-device.h | 5 +++++
2 files changed, 26 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 4d1c13d..52d7809 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -577,6 +577,26 @@ int __must_check media_device_register_entity(struct media_device *mdev,
spin_unlock(&mdev->lock);
+ mutex_lock(&mdev->graph_mutex);
+ if (mdev->entity_internal_idx_max
+ >= mdev->pm_count_walk.ent_enum.idx_max) {
+ struct media_entity_graph new = { 0 };
+
+ /*
+ * Initialise the new graph walk before cleaning up
+ * the old one in order not to spoil the graph walk
+ * object of the media device if graph walk init fails.
+ */
+ ret = media_entity_graph_walk_init(&new, mdev);
+ if (ret) {
+ mutex_unlock(&mdev->graph_mutex);
+ return ret;
+ }
+ media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
+ mdev->pm_count_walk = new;
+ }
+ mutex_unlock(&mdev->graph_mutex);
+
return 0;
}
EXPORT_SYMBOL_GPL(media_device_register_entity);
@@ -652,6 +672,7 @@ void media_device_cleanup(struct media_device *mdev)
{
ida_destroy(&mdev->entity_internal_idx);
mdev->entity_internal_idx_max = 0;
+ media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
mutex_destroy(&mdev->graph_mutex);
}
EXPORT_SYMBOL_GPL(media_device_cleanup);
diff --git a/include/media/media-device.h b/include/media/media-device.h
index d385589..dba3986 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -323,6 +323,11 @@ struct media_device {
spinlock_t lock;
/* Serializes graph operations. */
struct mutex graph_mutex;
+ /*
+ * Graph walk for power state walk. Access serialised using
+ * graph_mutex.
+ */
+ struct media_entity_graph pm_count_walk;
int (*link_notify)(struct media_link *link, u32 flags,
unsigned int notification);
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 2/5] media: Always keep a graph walk large enough around
2016-01-27 13:50 ` [PATCH 2/5] media: Always keep a graph walk large enough around Sakari Ailus
@ 2016-01-27 14:33 ` kbuild test robot
0 siblings, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2016-01-27 14:33 UTC (permalink / raw)
To: Sakari Ailus; +Cc: kbuild-all, linux-media
[-- Attachment #1: Type: text/plain, Size: 2243 bytes --]
Hi Sakari,
[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.5-rc1 next-20160127]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Sakari-Ailus/Unify-MC-graph-power-management-code/20160127-215417
base: git://linuxtv.org/media_tree.git master
config: xtensa-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=xtensa
All warnings (new ones prefixed by >>):
drivers/media/media-device.c: In function 'media_device_register_entity':
>> drivers/media/media-device.c:583:10: warning: missing braces around initializer [-Wmissing-braces]
struct media_entity_graph new = { 0 };
^
drivers/media/media-device.c:583:10: warning: (near initialization for 'new.stack') [-Wmissing-braces]
vim +583 drivers/media/media-device.c
567 mdev->entity_internal_idx_max =
568 max(mdev->entity_internal_idx_max, entity->internal_idx);
569
570 /* Initialize media_gobj embedded at the entity */
571 media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
572
573 /* Initialize objects at the pads */
574 for (i = 0; i < entity->num_pads; i++)
575 media_gobj_create(mdev, MEDIA_GRAPH_PAD,
576 &entity->pads[i].graph_obj);
577
578 spin_unlock(&mdev->lock);
579
580 mutex_lock(&mdev->graph_mutex);
581 if (mdev->entity_internal_idx_max
582 >= mdev->pm_count_walk.ent_enum.idx_max) {
> 583 struct media_entity_graph new = { 0 };
584
585 /*
586 * Initialise the new graph walk before cleaning up
587 * the old one in order not to spoil the graph walk
588 * object of the media device if graph walk init fails.
589 */
590 ret = media_entity_graph_walk_init(&new, mdev);
591 if (ret) {
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 44066 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/5] v4l: Add generic pipeline power management code
2016-01-27 13:50 [PATCH 0/5] Unify MC graph power management code Sakari Ailus
2016-01-27 13:50 ` [PATCH 1/5] media: Use all bits of an enumeration Sakari Ailus
2016-01-27 13:50 ` [PATCH 2/5] media: Always keep a graph walk large enough around Sakari Ailus
@ 2016-01-27 13:50 ` Sakari Ailus
2016-01-27 14:05 ` Hans Verkuil
` (2 more replies)
2016-01-27 13:50 ` [PATCH 4/5] v4l: omap3isp: Use V4L2 graph PM operations Sakari Ailus
2016-01-27 13:50 ` [PATCH 5/5] staging: v4l: omap4iss: " Sakari Ailus
4 siblings, 3 replies; 11+ messages in thread
From: Sakari Ailus @ 2016-01-27 13:50 UTC (permalink / raw)
To: linux-media
When the Media controller framework was merged, it was decided not to add
pipeline power management code for it was not seen generic. As a result, a
number of drivers have copied the same piece of code, with same bugfixes
done to them at different points of time (or not at all).
Add these functions to V4L2. Their use is optional for drivers.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/v4l2-core/v4l2-common.c | 174 ++++++++++++++++++++++++++++++++++
include/media/v4l2-common.h | 37 ++++++++
2 files changed, 211 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 5b80850..0e063a9 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -405,3 +405,177 @@ void v4l2_get_timestamp(struct timeval *tv)
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
}
EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
+
+/* -----------------------------------------------------------------------------
+ * Pipeline power management
+ *
+ * Entities must be powered up when part of a pipeline that contains at least
+ * one open video device node.
+ *
+ * To achieve this use the entity use_count field to track the number of users.
+ * For entities corresponding to video device nodes the use_count field stores
+ * the users count of the node. For entities corresponding to subdevs the
+ * use_count field stores the total number of users of all video device nodes
+ * in the pipeline.
+ *
+ * The v4l2_pipeline_pm_use() function must be called in the open() and
+ * close() handlers of video device nodes. It increments or decrements the use
+ * count of all subdev entities in the pipeline.
+ *
+ * To react to link management on powered pipelines, the link setup notification
+ * callback updates the use count of all entities in the source and sink sides
+ * of the link.
+ */
+
+/*
+ * pipeline_pm_use_count - Count the number of users of a pipeline
+ * @entity: The entity
+ *
+ * Return the total number of users of all video device nodes in the pipeline.
+ */
+static int pipeline_pm_use_count(struct media_entity *entity,
+ struct media_entity_graph *graph)
+{
+ int use = 0;
+
+ media_entity_graph_walk_start(graph, entity);
+
+ while ((entity = media_entity_graph_walk_next(graph))) {
+ if (is_media_entity_v4l2_io(entity))
+ use += entity->use_count;
+ }
+
+ return use;
+}
+
+/*
+ * pipeline_pm_power_one - Apply power change to an entity
+ * @entity: The entity
+ * @change: Use count change
+ *
+ * Change the entity use count by @change. If the entity is a subdev update its
+ * power state by calling the core::s_power operation when the use count goes
+ * from 0 to != 0 or from != 0 to 0.
+ *
+ * Return 0 on success or a negative error code on failure.
+ */
+static int pipeline_pm_power_one(struct media_entity *entity, int change)
+{
+ struct v4l2_subdev *subdev;
+ int ret;
+
+ subdev = is_media_entity_v4l2_subdev(entity)
+ ? media_entity_to_v4l2_subdev(entity) : NULL;
+
+ if (entity->use_count == 0 && change > 0 && subdev != NULL) {
+ ret = v4l2_subdev_call(subdev, core, s_power, 1);
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return ret;
+ }
+
+ entity->use_count += change;
+ WARN_ON(entity->use_count < 0);
+
+ if (entity->use_count == 0 && change < 0 && subdev != NULL)
+ v4l2_subdev_call(subdev, core, s_power, 0);
+
+ return 0;
+}
+
+/*
+ * pipeline_pm_power - Apply power change to all entities in a pipeline
+ * @entity: The entity
+ * @change: Use count change
+ *
+ * Walk the pipeline to update the use count and the power state of all non-node
+ * entities.
+ *
+ * Return 0 on success or a negative error code on failure.
+ */
+static int pipeline_pm_power(struct media_entity *entity, int change,
+ struct media_entity_graph *graph)
+{
+ struct media_entity *first = entity;
+ int ret = 0;
+
+ if (!change)
+ return 0;
+
+ media_entity_graph_walk_start(graph, entity);
+
+ while (!ret && (entity = media_entity_graph_walk_next(graph)))
+ if (is_media_entity_v4l2_subdev(entity))
+ ret = pipeline_pm_power_one(entity, change);
+
+ if (!ret)
+ return ret;
+
+ media_entity_graph_walk_start(graph, first);
+
+ while ((first = media_entity_graph_walk_next(graph))
+ && first != entity)
+ if (is_media_entity_v4l2_subdev(first))
+ pipeline_pm_power_one(first, -change);
+
+ return ret;
+}
+
+int v4l2_pipeline_pm_use(struct media_entity *entity, int use)
+{
+ struct media_device *mdev = entity->graph_obj.mdev;
+ int change = use ? 1 : -1;
+ int ret;
+
+ mutex_lock(&mdev->graph_mutex);
+
+ /* Apply use count to node. */
+ entity->use_count += change;
+ WARN_ON(entity->use_count < 0);
+
+ /* Apply power change to connected non-nodes. */
+ ret = pipeline_pm_power(entity, change, &mdev->pm_count_walk);
+ if (ret < 0)
+ entity->use_count -= change;
+
+ mutex_unlock(&mdev->graph_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_use);
+
+int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
+ unsigned int notification)
+{
+ struct media_entity_graph *graph = &link->graph_obj.mdev->pm_count_walk;
+ struct media_entity *source = link->source->entity;
+ struct media_entity *sink = link->sink->entity;
+ int source_use;
+ int sink_use;
+ int ret = 0;
+
+ source_use = pipeline_pm_use_count(source, graph);
+ sink_use = pipeline_pm_use_count(sink, graph);
+
+ if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+ !(flags & MEDIA_LNK_FL_ENABLED)) {
+ /* Powering off entities is assumed to never fail. */
+ pipeline_pm_power(source, -sink_use, graph);
+ pipeline_pm_power(sink, -source_use, graph);
+ return 0;
+ }
+
+ if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
+ (flags & MEDIA_LNK_FL_ENABLED)) {
+
+ ret = pipeline_pm_power(source, sink_use, graph);
+ if (ret < 0)
+ return ret;
+
+ ret = pipeline_pm_power(sink, source_use, graph);
+ if (ret < 0)
+ pipeline_pm_power(source, -sink_use, graph);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_pipeline_link_notify);
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1cc0c5b..0c23940 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -189,4 +189,41 @@ const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
void v4l2_get_timestamp(struct timeval *tv);
+/**
+ * v4l2_pipeline_pm_use - Update the use count of an entity
+ * @entity: The entity
+ * @use: Use (1) or stop using (0) the entity
+ *
+ * Update the use count of all entities in the pipeline and power entities on or
+ * off accordingly.
+ *
+ * This function is intended to be called in video node open (use ==
+ * 1) and release (use == 0). It uses struct media_entity.use_count to
+ * track the power status. The use of this function should be paired
+ * with v4l2_pipeline_link_notify().
+ *
+ * Return 0 on success or a negative error code on failure. Powering entities
+ * off is assumed to never fail. No failure can occur when the use parameter is
+ * set to 0.
+ */
+int v4l2_pipeline_pm_use(struct media_entity *entity, int use);
+
+
+/**
+ * v4l2_pipeline_link_notify - Link management notification callback
+ * @link: The link
+ * @flags: New link flags that will be applied
+ * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
+ *
+ * React to link management on powered pipelines by updating the use count of
+ * all entities in the source and sink sides of the link. Entities are powered
+ * on or off accordingly. The use of this function should be paired
+ * with v4l2_pipeline_pm_use().
+ *
+ * Return 0 on success or a negative error code on failure. Powering entities
+ * off is assumed to never fail. This function will not fail for disconnection
+ * events.
+ */
+int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
+ unsigned int notification);
#endif /* V4L2_COMMON_H_ */
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 3/5] v4l: Add generic pipeline power management code
2016-01-27 13:50 ` [PATCH 3/5] v4l: Add generic pipeline power management code Sakari Ailus
@ 2016-01-27 14:05 ` Hans Verkuil
2016-01-27 14:39 ` Sakari Ailus
2016-01-27 14:18 ` kbuild test robot
2016-01-27 15:16 ` kbuild test robot
2 siblings, 1 reply; 11+ messages in thread
From: Hans Verkuil @ 2016-01-27 14:05 UTC (permalink / raw)
To: Sakari Ailus, linux-media
On 01/27/16 14:50, Sakari Ailus wrote:
> When the Media controller framework was merged, it was decided not to add
> pipeline power management code for it was not seen generic. As a result, a
> number of drivers have copied the same piece of code, with same bugfixes
> done to them at different points of time (or not at all).
>
> Add these functions to V4L2. Their use is optional for drivers.
>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
> drivers/media/v4l2-core/v4l2-common.c | 174 ++++++++++++++++++++++++++++++++++
> include/media/v4l2-common.h | 37 ++++++++
I think I would prefer to see a v4l2-mc.c source rather than adding it to common.
Since this is specific to both v4l2 and MC it only has to be compiled
if both config options are set.
Besides, I think we need to move more common mc code to such a file.
Regards,
Hans
> 2 files changed, 211 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
> index 5b80850..0e063a9 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -405,3 +405,177 @@ void v4l2_get_timestamp(struct timeval *tv)
> tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
> }
> EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
> +
> +/* -----------------------------------------------------------------------------
> + * Pipeline power management
> + *
> + * Entities must be powered up when part of a pipeline that contains at least
> + * one open video device node.
> + *
> + * To achieve this use the entity use_count field to track the number of users.
> + * For entities corresponding to video device nodes the use_count field stores
> + * the users count of the node. For entities corresponding to subdevs the
> + * use_count field stores the total number of users of all video device nodes
> + * in the pipeline.
> + *
> + * The v4l2_pipeline_pm_use() function must be called in the open() and
> + * close() handlers of video device nodes. It increments or decrements the use
> + * count of all subdev entities in the pipeline.
> + *
> + * To react to link management on powered pipelines, the link setup notification
> + * callback updates the use count of all entities in the source and sink sides
> + * of the link.
> + */
> +
> +/*
> + * pipeline_pm_use_count - Count the number of users of a pipeline
> + * @entity: The entity
> + *
> + * Return the total number of users of all video device nodes in the pipeline.
> + */
> +static int pipeline_pm_use_count(struct media_entity *entity,
> + struct media_entity_graph *graph)
> +{
> + int use = 0;
> +
> + media_entity_graph_walk_start(graph, entity);
> +
> + while ((entity = media_entity_graph_walk_next(graph))) {
> + if (is_media_entity_v4l2_io(entity))
> + use += entity->use_count;
> + }
> +
> + return use;
> +}
> +
> +/*
> + * pipeline_pm_power_one - Apply power change to an entity
> + * @entity: The entity
> + * @change: Use count change
> + *
> + * Change the entity use count by @change. If the entity is a subdev update its
> + * power state by calling the core::s_power operation when the use count goes
> + * from 0 to != 0 or from != 0 to 0.
> + *
> + * Return 0 on success or a negative error code on failure.
> + */
> +static int pipeline_pm_power_one(struct media_entity *entity, int change)
> +{
> + struct v4l2_subdev *subdev;
> + int ret;
> +
> + subdev = is_media_entity_v4l2_subdev(entity)
> + ? media_entity_to_v4l2_subdev(entity) : NULL;
> +
> + if (entity->use_count == 0 && change > 0 && subdev != NULL) {
> + ret = v4l2_subdev_call(subdev, core, s_power, 1);
> + if (ret < 0 && ret != -ENOIOCTLCMD)
> + return ret;
> + }
> +
> + entity->use_count += change;
> + WARN_ON(entity->use_count < 0);
> +
> + if (entity->use_count == 0 && change < 0 && subdev != NULL)
> + v4l2_subdev_call(subdev, core, s_power, 0);
> +
> + return 0;
> +}
> +
> +/*
> + * pipeline_pm_power - Apply power change to all entities in a pipeline
> + * @entity: The entity
> + * @change: Use count change
> + *
> + * Walk the pipeline to update the use count and the power state of all non-node
> + * entities.
> + *
> + * Return 0 on success or a negative error code on failure.
> + */
> +static int pipeline_pm_power(struct media_entity *entity, int change,
> + struct media_entity_graph *graph)
> +{
> + struct media_entity *first = entity;
> + int ret = 0;
> +
> + if (!change)
> + return 0;
> +
> + media_entity_graph_walk_start(graph, entity);
> +
> + while (!ret && (entity = media_entity_graph_walk_next(graph)))
> + if (is_media_entity_v4l2_subdev(entity))
> + ret = pipeline_pm_power_one(entity, change);
> +
> + if (!ret)
> + return ret;
> +
> + media_entity_graph_walk_start(graph, first);
> +
> + while ((first = media_entity_graph_walk_next(graph))
> + && first != entity)
> + if (is_media_entity_v4l2_subdev(first))
> + pipeline_pm_power_one(first, -change);
> +
> + return ret;
> +}
> +
> +int v4l2_pipeline_pm_use(struct media_entity *entity, int use)
> +{
> + struct media_device *mdev = entity->graph_obj.mdev;
> + int change = use ? 1 : -1;
> + int ret;
> +
> + mutex_lock(&mdev->graph_mutex);
> +
> + /* Apply use count to node. */
> + entity->use_count += change;
> + WARN_ON(entity->use_count < 0);
> +
> + /* Apply power change to connected non-nodes. */
> + ret = pipeline_pm_power(entity, change, &mdev->pm_count_walk);
> + if (ret < 0)
> + entity->use_count -= change;
> +
> + mutex_unlock(&mdev->graph_mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_use);
> +
> +int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
> + unsigned int notification)
> +{
> + struct media_entity_graph *graph = &link->graph_obj.mdev->pm_count_walk;
> + struct media_entity *source = link->source->entity;
> + struct media_entity *sink = link->sink->entity;
> + int source_use;
> + int sink_use;
> + int ret = 0;
> +
> + source_use = pipeline_pm_use_count(source, graph);
> + sink_use = pipeline_pm_use_count(sink, graph);
> +
> + if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
> + !(flags & MEDIA_LNK_FL_ENABLED)) {
> + /* Powering off entities is assumed to never fail. */
> + pipeline_pm_power(source, -sink_use, graph);
> + pipeline_pm_power(sink, -source_use, graph);
> + return 0;
> + }
> +
> + if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
> + (flags & MEDIA_LNK_FL_ENABLED)) {
> +
> + ret = pipeline_pm_power(source, sink_use, graph);
> + if (ret < 0)
> + return ret;
> +
> + ret = pipeline_pm_power(sink, source_use, graph);
> + if (ret < 0)
> + pipeline_pm_power(source, -sink_use, graph);
> + }
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_pipeline_link_notify);
> diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
> index 1cc0c5b..0c23940 100644
> --- a/include/media/v4l2-common.h
> +++ b/include/media/v4l2-common.h
> @@ -189,4 +189,41 @@ const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
>
> void v4l2_get_timestamp(struct timeval *tv);
>
> +/**
> + * v4l2_pipeline_pm_use - Update the use count of an entity
> + * @entity: The entity
> + * @use: Use (1) or stop using (0) the entity
> + *
> + * Update the use count of all entities in the pipeline and power entities on or
> + * off accordingly.
> + *
> + * This function is intended to be called in video node open (use ==
> + * 1) and release (use == 0). It uses struct media_entity.use_count to
> + * track the power status. The use of this function should be paired
> + * with v4l2_pipeline_link_notify().
> + *
> + * Return 0 on success or a negative error code on failure. Powering entities
> + * off is assumed to never fail. No failure can occur when the use parameter is
> + * set to 0.
> + */
> +int v4l2_pipeline_pm_use(struct media_entity *entity, int use);
> +
> +
> +/**
> + * v4l2_pipeline_link_notify - Link management notification callback
> + * @link: The link
> + * @flags: New link flags that will be applied
> + * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
> + *
> + * React to link management on powered pipelines by updating the use count of
> + * all entities in the source and sink sides of the link. Entities are powered
> + * on or off accordingly. The use of this function should be paired
> + * with v4l2_pipeline_pm_use().
> + *
> + * Return 0 on success or a negative error code on failure. Powering entities
> + * off is assumed to never fail. This function will not fail for disconnection
> + * events.
> + */
> +int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
> + unsigned int notification);
> #endif /* V4L2_COMMON_H_ */
>
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 3/5] v4l: Add generic pipeline power management code
2016-01-27 14:05 ` Hans Verkuil
@ 2016-01-27 14:39 ` Sakari Ailus
0 siblings, 0 replies; 11+ messages in thread
From: Sakari Ailus @ 2016-01-27 14:39 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media
On Wed, Jan 27, 2016 at 03:05:16PM +0100, Hans Verkuil wrote:
> On 01/27/16 14:50, Sakari Ailus wrote:
> > When the Media controller framework was merged, it was decided not to add
> > pipeline power management code for it was not seen generic. As a result, a
> > number of drivers have copied the same piece of code, with same bugfixes
> > done to them at different points of time (or not at all).
> >
> > Add these functions to V4L2. Their use is optional for drivers.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> > drivers/media/v4l2-core/v4l2-common.c | 174 ++++++++++++++++++++++++++++++++++
> > include/media/v4l2-common.h | 37 ++++++++
>
> I think I would prefer to see a v4l2-mc.c source rather than adding it to common.
> Since this is specific to both v4l2 and MC it only has to be compiled
> if both config options are set.
>
> Besides, I think we need to move more common mc code to such a file.
Ok. I'll move these to a separate file.
--
Sakari Ailus
e-mail: sakari.ailus@iki.fi XMPP: sailus@retiisi.org.uk
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/5] v4l: Add generic pipeline power management code
2016-01-27 13:50 ` [PATCH 3/5] v4l: Add generic pipeline power management code Sakari Ailus
2016-01-27 14:05 ` Hans Verkuil
@ 2016-01-27 14:18 ` kbuild test robot
2016-01-27 15:16 ` kbuild test robot
2 siblings, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2016-01-27 14:18 UTC (permalink / raw)
To: Sakari Ailus; +Cc: kbuild-all, linux-media
[-- Attachment #1: Type: text/plain, Size: 5043 bytes --]
Hi Sakari,
[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.5-rc1 next-20160127]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Sakari-Ailus/Unify-MC-graph-power-management-code/20160127-215417
base: git://linuxtv.org/media_tree.git master
config: x86_64-randconfig-x013-01270835 (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
In file included from include/linux/list.h:8:0,
from include/linux/module.h:9,
from drivers/media/v4l2-core/v4l2-common.c:47:
drivers/media/v4l2-core/v4l2-common.c: In function 'pipeline_pm_power_one':
>> include/linux/kernel.h:841:27: error: 'struct v4l2_subdev' has no member named 'entity'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/media/v4l2-subdev.h:740:2: note: in expansion of macro 'container_of'
container_of(ent, struct v4l2_subdev, entity)
^
>> drivers/media/v4l2-core/v4l2-common.c:468:11: note: in expansion of macro 'media_entity_to_v4l2_subdev'
? media_entity_to_v4l2_subdev(entity) : NULL;
^
include/linux/kernel.h:841:48: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/media/v4l2-subdev.h:740:2: note: in expansion of macro 'container_of'
container_of(ent, struct v4l2_subdev, entity)
^
>> drivers/media/v4l2-core/v4l2-common.c:468:11: note: in expansion of macro 'media_entity_to_v4l2_subdev'
? media_entity_to_v4l2_subdev(entity) : NULL;
^
In file included from include/linux/compiler.h:56:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/list.h:4,
from include/linux/module.h:9,
from drivers/media/v4l2-core/v4l2-common.c:47:
>> include/linux/compiler-gcc.h:158:2: error: 'struct v4l2_subdev' has no member named 'entity'
__builtin_offsetof(a, b)
^
include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
^
include/linux/kernel.h:842:29: note: in expansion of macro 'offsetof'
(type *)( (char *)__mptr - offsetof(type,member) );})
^
>> include/media/v4l2-subdev.h:740:2: note: in expansion of macro 'container_of'
container_of(ent, struct v4l2_subdev, entity)
^
>> drivers/media/v4l2-core/v4l2-common.c:468:11: note: in expansion of macro 'media_entity_to_v4l2_subdev'
? media_entity_to_v4l2_subdev(entity) : NULL;
^
drivers/media/v4l2-core/v4l2-common.c: In function 'v4l2_pipeline_link_notify':
>> drivers/media/v4l2-core/v4l2-common.c:559:22: error: 'MEDIA_DEV_NOTIFY_POST_LINK_CH' undeclared (first use in this function)
if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
^
drivers/media/v4l2-core/v4l2-common.c:559:22: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/media/v4l2-core/v4l2-common.c:567:22: error: 'MEDIA_DEV_NOTIFY_PRE_LINK_CH' undeclared (first use in this function)
if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
^
vim +841 include/linux/kernel.h
^1da177e Linus Torvalds 2005-04-16 835 * @ptr: the pointer to the member.
^1da177e Linus Torvalds 2005-04-16 836 * @type: the type of the container struct this is embedded in.
^1da177e Linus Torvalds 2005-04-16 837 * @member: the name of the member within the struct.
^1da177e Linus Torvalds 2005-04-16 838 *
^1da177e Linus Torvalds 2005-04-16 839 */
^1da177e Linus Torvalds 2005-04-16 840 #define container_of(ptr, type, member) ({ \
^1da177e Linus Torvalds 2005-04-16 @841 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^1da177e Linus Torvalds 2005-04-16 842 (type *)( (char *)__mptr - offsetof(type,member) );})
^1da177e Linus Torvalds 2005-04-16 843
b9d4f426 Arnaud Lacombe 2011-07-25 844 /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
:::::: The code at line 841 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 26819 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 3/5] v4l: Add generic pipeline power management code
2016-01-27 13:50 ` [PATCH 3/5] v4l: Add generic pipeline power management code Sakari Ailus
2016-01-27 14:05 ` Hans Verkuil
2016-01-27 14:18 ` kbuild test robot
@ 2016-01-27 15:16 ` kbuild test robot
2 siblings, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2016-01-27 15:16 UTC (permalink / raw)
To: Sakari Ailus; +Cc: kbuild-all, linux-media
[-- Attachment #1: Type: text/plain, Size: 6464 bytes --]
Hi Sakari,
[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.5-rc1 next-20160127]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Sakari-Ailus/Unify-MC-graph-power-management-code/20160127-215417
base: git://linuxtv.org/media_tree.git master
config: x86_64-randconfig-s1-01272247 (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
In file included from include/linux/list.h:8:0,
from include/linux/module.h:9,
from drivers/media/v4l2-core/v4l2-common.c:47:
drivers/media/v4l2-core/v4l2-common.c: In function 'pipeline_pm_power_one':
include/linux/kernel.h:841:27: error: 'struct v4l2_subdev' has no member named 'entity'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/media/v4l2-subdev.h:740:2: note: in expansion of macro 'container_of'
container_of(ent, struct v4l2_subdev, entity)
^
drivers/media/v4l2-core/v4l2-common.c:468:11: note: in expansion of macro 'media_entity_to_v4l2_subdev'
? media_entity_to_v4l2_subdev(entity) : NULL;
^
include/linux/kernel.h:841:48: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/media/v4l2-subdev.h:740:2: note: in expansion of macro 'container_of'
container_of(ent, struct v4l2_subdev, entity)
^
drivers/media/v4l2-core/v4l2-common.c:468:11: note: in expansion of macro 'media_entity_to_v4l2_subdev'
? media_entity_to_v4l2_subdev(entity) : NULL;
^
In file included from include/linux/compiler.h:56:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/list.h:4,
from include/linux/module.h:9,
from drivers/media/v4l2-core/v4l2-common.c:47:
include/linux/compiler-gcc.h:158:2: error: 'struct v4l2_subdev' has no member named 'entity'
__builtin_offsetof(a, b)
^
include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
^
include/linux/kernel.h:842:29: note: in expansion of macro 'offsetof'
(type *)( (char *)__mptr - offsetof(type,member) );})
^
include/media/v4l2-subdev.h:740:2: note: in expansion of macro 'container_of'
container_of(ent, struct v4l2_subdev, entity)
^
drivers/media/v4l2-core/v4l2-common.c:468:11: note: in expansion of macro 'media_entity_to_v4l2_subdev'
? media_entity_to_v4l2_subdev(entity) : NULL;
^
In file included from include/uapi/linux/stddef.h:1:0,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/list.h:4,
from include/linux/module.h:9,
from drivers/media/v4l2-core/v4l2-common.c:47:
drivers/media/v4l2-core/v4l2-common.c: In function 'v4l2_pipeline_link_notify':
drivers/media/v4l2-core/v4l2-common.c:559:22: error: 'MEDIA_DEV_NOTIFY_POST_LINK_CH' undeclared (first use in this function)
if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
^
include/linux/compiler.h:147:28: note: in definition of macro '__trace_if'
if (__builtin_constant_p((cond)) ? !!(cond) : \
^
>> drivers/media/v4l2-core/v4l2-common.c:559:2: note: in expansion of macro 'if'
if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
^
drivers/media/v4l2-core/v4l2-common.c:559:22: note: each undeclared identifier is reported only once for each function it appears in
if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
^
include/linux/compiler.h:147:28: note: in definition of macro '__trace_if'
if (__builtin_constant_p((cond)) ? !!(cond) : \
^
>> drivers/media/v4l2-core/v4l2-common.c:559:2: note: in expansion of macro 'if'
if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
^
drivers/media/v4l2-core/v4l2-common.c:567:22: error: 'MEDIA_DEV_NOTIFY_PRE_LINK_CH' undeclared (first use in this function)
if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
^
include/linux/compiler.h:147:28: note: in definition of macro '__trace_if'
if (__builtin_constant_p((cond)) ? !!(cond) : \
^
drivers/media/v4l2-core/v4l2-common.c:567:2: note: in expansion of macro 'if'
if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
^
vim +/if +559 drivers/media/v4l2-core/v4l2-common.c
543 }
544 EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_use);
545
546 int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
547 unsigned int notification)
548 {
549 struct media_entity_graph *graph = &link->graph_obj.mdev->pm_count_walk;
550 struct media_entity *source = link->source->entity;
551 struct media_entity *sink = link->sink->entity;
552 int source_use;
553 int sink_use;
554 int ret = 0;
555
556 source_use = pipeline_pm_use_count(source, graph);
557 sink_use = pipeline_pm_use_count(sink, graph);
558
> 559 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
560 !(flags & MEDIA_LNK_FL_ENABLED)) {
561 /* Powering off entities is assumed to never fail. */
562 pipeline_pm_power(source, -sink_use, graph);
563 pipeline_pm_power(sink, -source_use, graph);
564 return 0;
565 }
566
567 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 24932 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/5] v4l: omap3isp: Use V4L2 graph PM operations
2016-01-27 13:50 [PATCH 0/5] Unify MC graph power management code Sakari Ailus
` (2 preceding siblings ...)
2016-01-27 13:50 ` [PATCH 3/5] v4l: Add generic pipeline power management code Sakari Ailus
@ 2016-01-27 13:50 ` Sakari Ailus
2016-01-27 13:50 ` [PATCH 5/5] staging: v4l: omap4iss: " Sakari Ailus
4 siblings, 0 replies; 11+ messages in thread
From: Sakari Ailus @ 2016-01-27 13:50 UTC (permalink / raw)
To: linux-media; +Cc: Laurent Pinchart
Power on devices represented by entities in the graph through the pipeline
state using V4L2 graph PM operations instead of what was in the omap3isp
driver.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/media/platform/omap3isp/isp.c | 212 +----------------------------
drivers/media/platform/omap3isp/isp.h | 4 -
drivers/media/platform/omap3isp/ispvideo.c | 11 +-
drivers/media/platform/omap3isp/ispvideo.h | 1 -
4 files changed, 3 insertions(+), 225 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 67efa9e..81a747d 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -657,216 +657,6 @@ static irqreturn_t isp_isr(int irq, void *_isp)
}
/* -----------------------------------------------------------------------------
- * Pipeline power management
- *
- * Entities must be powered up when part of a pipeline that contains at least
- * one open video device node.
- *
- * To achieve this use the entity use_count field to track the number of users.
- * For entities corresponding to video device nodes the use_count field stores
- * the users count of the node. For entities corresponding to subdevs the
- * use_count field stores the total number of users of all video device nodes
- * in the pipeline.
- *
- * The omap3isp_pipeline_pm_use() function must be called in the open() and
- * close() handlers of video device nodes. It increments or decrements the use
- * count of all subdev entities in the pipeline.
- *
- * To react to link management on powered pipelines, the link setup notification
- * callback updates the use count of all entities in the source and sink sides
- * of the link.
- */
-
-/*
- * isp_pipeline_pm_use_count - Count the number of users of a pipeline
- * @entity: The entity
- *
- * Return the total number of users of all video device nodes in the pipeline.
- */
-static int isp_pipeline_pm_use_count(struct media_entity *entity,
- struct media_entity_graph *graph)
-{
- int use = 0;
-
- media_entity_graph_walk_start(graph, entity);
-
- while ((entity = media_entity_graph_walk_next(graph))) {
- if (is_media_entity_v4l2_io(entity))
- use += entity->use_count;
- }
-
- return use;
-}
-
-/*
- * isp_pipeline_pm_power_one - Apply power change to an entity
- * @entity: The entity
- * @change: Use count change
- *
- * Change the entity use count by @change. If the entity is a subdev update its
- * power state by calling the core::s_power operation when the use count goes
- * from 0 to != 0 or from != 0 to 0.
- *
- * Return 0 on success or a negative error code on failure.
- */
-static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
-{
- struct v4l2_subdev *subdev;
- int ret;
-
- subdev = is_media_entity_v4l2_subdev(entity)
- ? media_entity_to_v4l2_subdev(entity) : NULL;
-
- if (entity->use_count == 0 && change > 0 && subdev != NULL) {
- ret = v4l2_subdev_call(subdev, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
- }
-
- entity->use_count += change;
- WARN_ON(entity->use_count < 0);
-
- if (entity->use_count == 0 && change < 0 && subdev != NULL)
- v4l2_subdev_call(subdev, core, s_power, 0);
-
- return 0;
-}
-
-/*
- * isp_pipeline_pm_power - Apply power change to all entities in a pipeline
- * @entity: The entity
- * @change: Use count change
- *
- * Walk the pipeline to update the use count and the power state of all non-node
- * entities.
- *
- * Return 0 on success or a negative error code on failure.
- */
-static int isp_pipeline_pm_power(struct media_entity *entity, int change,
- struct media_entity_graph *graph)
-{
- struct media_entity *first = entity;
- int ret = 0;
-
- if (!change)
- return 0;
-
- media_entity_graph_walk_start(graph, entity);
-
- while (!ret && (entity = media_entity_graph_walk_next(graph)))
- if (is_media_entity_v4l2_subdev(entity))
- ret = isp_pipeline_pm_power_one(entity, change);
-
- if (!ret)
- return ret;
-
- media_entity_graph_walk_start(graph, first);
-
- while ((first = media_entity_graph_walk_next(graph))
- && first != entity)
- if (is_media_entity_v4l2_subdev(first))
- isp_pipeline_pm_power_one(first, -change);
-
- return ret;
-}
-
-/*
- * omap3isp_pipeline_pm_use - Update the use count of an entity
- * @entity: The entity
- * @use: Use (1) or stop using (0) the entity
- *
- * Update the use count of all entities in the pipeline and power entities on or
- * off accordingly.
- *
- * Return 0 on success or a negative error code on failure. Powering entities
- * off is assumed to never fail. No failure can occur when the use parameter is
- * set to 0.
- */
-int omap3isp_pipeline_pm_use(struct media_entity *entity, int use,
- struct media_entity_graph *graph)
-{
- int change = use ? 1 : -1;
- int ret;
-
- mutex_lock(&entity->graph_obj.mdev->graph_mutex);
-
- /* Apply use count to node. */
- entity->use_count += change;
- WARN_ON(entity->use_count < 0);
-
- /* Apply power change to connected non-nodes. */
- ret = isp_pipeline_pm_power(entity, change, graph);
- if (ret < 0)
- entity->use_count -= change;
-
- mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
-
- return ret;
-}
-
-/*
- * isp_pipeline_link_notify - Link management notification callback
- * @link: The link
- * @flags: New link flags that will be applied
- * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
- *
- * React to link management on powered pipelines by updating the use count of
- * all entities in the source and sink sides of the link. Entities are powered
- * on or off accordingly.
- *
- * Return 0 on success or a negative error code on failure. Powering entities
- * off is assumed to never fail. This function will not fail for disconnection
- * events.
- */
-static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
- unsigned int notification)
-{
- struct media_entity_graph *graph =
- &container_of(link->graph_obj.mdev, struct isp_device,
- media_dev)->pm_count_graph;
- struct media_entity *source = link->source->entity;
- struct media_entity *sink = link->sink->entity;
- int source_use;
- int sink_use;
- int ret = 0;
-
- if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
- ret = media_entity_graph_walk_init(graph,
- link->graph_obj.mdev);
- if (ret)
- return ret;
- }
-
- source_use = isp_pipeline_pm_use_count(source, graph);
- sink_use = isp_pipeline_pm_use_count(sink, graph);
-
- if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
- !(flags & MEDIA_LNK_FL_ENABLED)) {
- /* Powering off entities is assumed to never fail. */
- isp_pipeline_pm_power(source, -sink_use, graph);
- isp_pipeline_pm_power(sink, -source_use, graph);
- return 0;
- }
-
- if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
- (flags & MEDIA_LNK_FL_ENABLED)) {
-
- ret = isp_pipeline_pm_power(source, sink_use, graph);
- if (ret < 0)
- return ret;
-
- ret = isp_pipeline_pm_power(sink, source_use, graph);
- if (ret < 0)
- isp_pipeline_pm_power(source, -sink_use, graph);
- }
-
- if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH)
- media_entity_graph_walk_cleanup(graph);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
* Pipeline stream management
*/
@@ -1889,7 +1679,7 @@ static int isp_register_entities(struct isp_device *isp)
strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
sizeof(isp->media_dev.model));
isp->media_dev.hw_revision = isp->revision;
- isp->media_dev.link_notify = isp_pipeline_link_notify;
+ isp->media_dev.link_notify = v4l2_pipeline_link_notify;
media_device_init(&isp->media_dev);
isp->v4l2_dev.mdev = &isp->media_dev;
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 49b7f71..7e6f663 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -177,7 +177,6 @@ struct isp_device {
struct v4l2_device v4l2_dev;
struct v4l2_async_notifier notifier;
struct media_device media_dev;
- struct media_entity_graph pm_count_graph;
struct device *dev;
u32 revision;
@@ -267,9 +266,6 @@ void omap3isp_subclk_enable(struct isp_device *isp,
void omap3isp_subclk_disable(struct isp_device *isp,
enum isp_subclk_resource res);
-int omap3isp_pipeline_pm_use(struct media_entity *entity, int use,
- struct media_entity_graph *graph);
-
int omap3isp_register_entities(struct platform_device *pdev,
struct v4l2_device *v4l2_dev);
void omap3isp_unregister_entities(struct platform_device *pdev);
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 2aff755..1b8f3d6 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1292,12 +1292,7 @@ static int isp_video_open(struct file *file)
goto done;
}
- ret = media_entity_graph_walk_init(&handle->graph,
- &video->isp->media_dev);
- if (ret)
- goto done;
-
- ret = omap3isp_pipeline_pm_use(&video->video.entity, 1, &handle->graph);
+ ret = v4l2_pipeline_pm_use(&video->video.entity, 1);
if (ret < 0) {
omap3isp_put(video->isp);
goto done;
@@ -1328,7 +1323,6 @@ static int isp_video_open(struct file *file)
done:
if (ret < 0) {
v4l2_fh_del(&handle->vfh);
- media_entity_graph_walk_cleanup(&handle->graph);
kfree(handle);
}
@@ -1348,8 +1342,7 @@ static int isp_video_release(struct file *file)
vb2_queue_release(&handle->queue);
mutex_unlock(&video->queue_lock);
- omap3isp_pipeline_pm_use(&video->video.entity, 0, &handle->graph);
- media_entity_graph_walk_cleanup(&handle->graph);
+ v4l2_pipeline_pm_use(&video->video.entity, 0);
/* Release the file handle. */
v4l2_fh_del(vfh);
diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h
index 1564298..6a48d58 100644
--- a/drivers/media/platform/omap3isp/ispvideo.h
+++ b/drivers/media/platform/omap3isp/ispvideo.h
@@ -189,7 +189,6 @@ struct isp_video_fh {
struct vb2_queue queue;
struct v4l2_format format;
struct v4l2_fract timeperframe;
- struct media_entity_graph graph;
};
#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 5/5] staging: v4l: omap4iss: Use V4L2 graph PM operations
2016-01-27 13:50 [PATCH 0/5] Unify MC graph power management code Sakari Ailus
` (3 preceding siblings ...)
2016-01-27 13:50 ` [PATCH 4/5] v4l: omap3isp: Use V4L2 graph PM operations Sakari Ailus
@ 2016-01-27 13:50 ` Sakari Ailus
4 siblings, 0 replies; 11+ messages in thread
From: Sakari Ailus @ 2016-01-27 13:50 UTC (permalink / raw)
To: linux-media; +Cc: Laurent Pinchart
Power on devices represented by entities in the graph through the pipeline
state using V4L2 graph PM operations instead of what was in the omap3isp
driver.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/staging/media/omap4iss/iss.c | 211 +----------------------------
drivers/staging/media/omap4iss/iss.h | 4 -
drivers/staging/media/omap4iss/iss_video.c | 13 +-
drivers/staging/media/omap4iss/iss_video.h | 1 -
4 files changed, 3 insertions(+), 226 deletions(-)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 30b473c..fb80d2b 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -363,215 +363,6 @@ static irqreturn_t iss_isr(int irq, void *_iss)
}
/* -----------------------------------------------------------------------------
- * Pipeline power management
- *
- * Entities must be powered up when part of a pipeline that contains at least
- * one open video device node.
- *
- * To achieve this use the entity use_count field to track the number of users.
- * For entities corresponding to video device nodes the use_count field stores
- * the users count of the node. For entities corresponding to subdevs the
- * use_count field stores the total number of users of all video device nodes
- * in the pipeline.
- *
- * The omap4iss_pipeline_pm_use() function must be called in the open() and
- * close() handlers of video device nodes. It increments or decrements the use
- * count of all subdev entities in the pipeline.
- *
- * To react to link management on powered pipelines, the link setup notification
- * callback updates the use count of all entities in the source and sink sides
- * of the link.
- */
-
-/*
- * iss_pipeline_pm_use_count - Count the number of users of a pipeline
- * @entity: The entity
- *
- * Return the total number of users of all video device nodes in the pipeline.
- */
-static int iss_pipeline_pm_use_count(struct media_entity *entity,
- struct media_entity_graph *graph)
-{
- int use = 0;
-
- media_entity_graph_walk_start(graph, entity);
-
- while ((entity = media_entity_graph_walk_next(graph))) {
- if (is_media_entity_v4l2_io(entity))
- use += entity->use_count;
- }
-
- return use;
-}
-
-/*
- * iss_pipeline_pm_power_one - Apply power change to an entity
- * @entity: The entity
- * @change: Use count change
- *
- * Change the entity use count by @change. If the entity is a subdev update its
- * power state by calling the core::s_power operation when the use count goes
- * from 0 to != 0 or from != 0 to 0.
- *
- * Return 0 on success or a negative error code on failure.
- */
-static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
-{
- struct v4l2_subdev *subdev;
-
- subdev = is_media_entity_v4l2_subdev(entity)
- ? media_entity_to_v4l2_subdev(entity) : NULL;
-
- if (entity->use_count == 0 && change > 0 && subdev) {
- int ret;
-
- ret = v4l2_subdev_call(subdev, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return ret;
- }
-
- entity->use_count += change;
- WARN_ON(entity->use_count < 0);
-
- if (entity->use_count == 0 && change < 0 && subdev)
- v4l2_subdev_call(subdev, core, s_power, 0);
-
- return 0;
-}
-
-/*
- * iss_pipeline_pm_power - Apply power change to all entities in a pipeline
- * @entity: The entity
- * @change: Use count change
- *
- * Walk the pipeline to update the use count and the power state of all non-node
- * entities.
- *
- * Return 0 on success or a negative error code on failure.
- */
-static int iss_pipeline_pm_power(struct media_entity *entity, int change,
- struct media_entity_graph *graph)
-{
- struct media_entity *first = entity;
- int ret = 0;
-
- if (!change)
- return 0;
-
- media_entity_graph_walk_start(graph, entity);
-
- while (!ret && (entity = media_entity_graph_walk_next(graph)))
- if (is_media_entity_v4l2_subdev(entity))
- ret = iss_pipeline_pm_power_one(entity, change);
-
- if (!ret)
- return 0;
-
- media_entity_graph_walk_start(graph, first);
-
- while ((first = media_entity_graph_walk_next(graph)) &&
- first != entity)
- if (is_media_entity_v4l2_subdev(first))
- iss_pipeline_pm_power_one(first, -change);
-
- return ret;
-}
-
-/*
- * omap4iss_pipeline_pm_use - Update the use count of an entity
- * @entity: The entity
- * @use: Use (1) or stop using (0) the entity
- *
- * Update the use count of all entities in the pipeline and power entities on or
- * off accordingly.
- *
- * Return 0 on success or a negative error code on failure. Powering entities
- * off is assumed to never fail. No failure can occur when the use parameter is
- * set to 0.
- */
-int omap4iss_pipeline_pm_use(struct media_entity *entity, int use,
- struct media_entity_graph *graph)
-{
- int change = use ? 1 : -1;
- int ret;
-
- mutex_lock(&entity->graph_obj.mdev->graph_mutex);
-
- /* Apply use count to node. */
- entity->use_count += change;
- WARN_ON(entity->use_count < 0);
-
- /* Apply power change to connected non-nodes. */
- ret = iss_pipeline_pm_power(entity, change, graph);
- if (ret < 0)
- entity->use_count -= change;
-
- mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
-
- return ret;
-}
-
-/*
- * iss_pipeline_link_notify - Link management notification callback
- * @link: The link
- * @flags: New link flags that will be applied
- *
- * React to link management on powered pipelines by updating the use count of
- * all entities in the source and sink sides of the link. Entities are powered
- * on or off accordingly.
- *
- * Return 0 on success or a negative error code on failure. Powering entities
- * off is assumed to never fail. This function will not fail for disconnection
- * events.
- */
-static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
- unsigned int notification)
-{
- struct media_entity_graph *graph =
- &container_of(link->graph_obj.mdev, struct iss_device,
- media_dev)->pm_count_graph;
- struct media_entity *source = link->source->entity;
- struct media_entity *sink = link->sink->entity;
- int source_use;
- int sink_use;
- int ret;
-
- if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
- ret = media_entity_graph_walk_init(graph,
- link->graph_obj.mdev);
- if (ret)
- return ret;
- }
-
- source_use = iss_pipeline_pm_use_count(source, graph);
- sink_use = iss_pipeline_pm_use_count(sink, graph);
-
- if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
- !(flags & MEDIA_LNK_FL_ENABLED)) {
- /* Powering off entities is assumed to never fail. */
- iss_pipeline_pm_power(source, -sink_use, graph);
- iss_pipeline_pm_power(sink, -source_use, graph);
- return 0;
- }
-
- if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
- (flags & MEDIA_LNK_FL_ENABLED)) {
- ret = iss_pipeline_pm_power(source, sink_use, graph);
- if (ret < 0)
- return ret;
-
- ret = iss_pipeline_pm_power(sink, source_use, graph);
- if (ret < 0)
- iss_pipeline_pm_power(source, -sink_use, graph);
- }
-
- if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH)
- media_entity_graph_walk_cleanup(graph);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
* Pipeline stream management
*/
@@ -1197,7 +988,7 @@ static int iss_register_entities(struct iss_device *iss)
strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
sizeof(iss->media_dev.model));
iss->media_dev.hw_revision = iss->revision;
- iss->media_dev.link_notify = iss_pipeline_link_notify;
+ iss->media_dev.link_notify = v4l2_pipeline_link_notify;
ret = media_device_register(&iss->media_dev);
if (ret < 0) {
dev_err(iss->dev, "Media device registration failed (%d)\n",
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
index 05f08a3..c58665a 100644
--- a/drivers/staging/media/omap4iss/iss.h
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -87,7 +87,6 @@ struct iss_reg {
struct iss_device {
struct v4l2_device v4l2_dev;
struct media_device media_dev;
- struct media_entity_graph pm_count_graph;
struct device *dev;
u32 revision;
@@ -152,9 +151,6 @@ void omap4iss_isp_subclk_enable(struct iss_device *iss,
void omap4iss_isp_subclk_disable(struct iss_device *iss,
enum iss_isp_subclk_resource res);
-int omap4iss_pipeline_pm_use(struct media_entity *entity, int use,
- struct media_entity_graph *graph);
-
int omap4iss_register_entities(struct platform_device *pdev,
struct v4l2_device *v4l2_dev);
void omap4iss_unregister_entities(struct platform_device *pdev);
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 058233a..ec47b04 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -1009,13 +1009,7 @@ static int iss_video_open(struct file *file)
goto done;
}
- ret = media_entity_graph_walk_init(&handle->graph,
- &video->iss->media_dev);
- if (ret)
- goto done;
-
- ret = omap4iss_pipeline_pm_use(&video->video.entity, 1,
- &handle->graph);
+ ret = v4l2_pipeline_pm_use(&video->video.entity, 1);
if (ret < 0) {
omap4iss_put(video->iss);
goto done;
@@ -1054,7 +1048,6 @@ static int iss_video_open(struct file *file)
done:
if (ret < 0) {
v4l2_fh_del(&handle->vfh);
- media_entity_graph_walk_cleanup(&handle->graph);
kfree(handle);
}
@@ -1070,13 +1063,11 @@ static int iss_video_release(struct file *file)
/* Disable streaming and free the buffers queue resources. */
iss_video_streamoff(file, vfh, video->type);
- omap4iss_pipeline_pm_use(&video->video.entity, 0, &handle->graph);
+ v4l2_pipeline_pm_use(&video->video.entity, 0);
/* Release the videobuf2 queue */
vb2_queue_release(&handle->queue);
- /* Release the file handle. */
- media_entity_graph_walk_cleanup(&handle->graph);
v4l2_fh_del(vfh);
kfree(handle);
file->private_data = NULL;
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h
index 34588b7..c8bd295 100644
--- a/drivers/staging/media/omap4iss/iss_video.h
+++ b/drivers/staging/media/omap4iss/iss_video.h
@@ -183,7 +183,6 @@ struct iss_video_fh {
struct vb2_queue queue;
struct v4l2_format format;
struct v4l2_fract timeperframe;
- struct media_entity_graph graph;
};
#define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh)
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread