return IRQ_HANDLED;
}
-/* -----------------------------------------------------------------------------
- * 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
*/
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",