@@ -481,3 +481,37 @@ int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
return ret;
}
EXPORT_SYMBOL_GPL(v4l2_pipeline_link_notify);
+
+int v4l2_subdev_routing_pm_use(struct media_entity *entity,
+ struct v4l2_subdev_route *route)
+{
+ struct media_graph *graph =
+ &entity->graph_obj.mdev->pm_count_walk;
+ struct media_pad *source = &entity->pads[route->source_pad];
+ struct media_pad *sink = &entity->pads[route->sink_pad];
+ int source_use;
+ int sink_use;
+ int ret;
+
+ source_use = pipeline_pm_use_count(source, graph);
+ sink_use = pipeline_pm_use_count(sink, graph);
+
+ if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) {
+ /* Route disabled. */
+ pipeline_pm_power(source, -sink_use, graph);
+ pipeline_pm_power(sink, -source_use, graph);
+ return 0;
+ }
+
+ /* Route 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_subdev_routing_pm_use);
@@ -26,6 +26,7 @@
/* We don't need to include pci.h or usb.h here */
struct pci_dev;
struct usb_device;
+struct v4l2_subdev_route;
#ifdef CONFIG_MEDIA_CONTROLLER
/**
@@ -132,6 +133,22 @@ int v4l2_pipeline_pm_use(struct media_entity *entity, int use);
int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
unsigned int notification);
+/**
+ * v4l2_subdev_routing_pm_use - Handle power state changes due to S_ROUTING
+ * @entity: The entity
+ * @route: The new state of the route
+ *
+ * Propagate the use count across a route in a pipeline whenever the
+ * route is enabled or disabled. The function is called before
+ * changing the route state when enabling a route, and after changing
+ * the route state when disabling a route.
+ *
+ * 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_subdev_routing_pm_use(struct media_entity *entity,
+ struct v4l2_subdev_route *route);
#else /* CONFIG_MEDIA_CONTROLLER */
static inline int v4l2_mc_create_media_graph(struct media_device *mdev)
@@ -164,5 +181,10 @@ static inline int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
return 0;
}
+static inline int v4l2_subdev_routing_pm_use(struct media_entity *entity,
+ struct v4l2_subdev_route *route)
+{
+ return 0;
+}
#endif /* CONFIG_MEDIA_CONTROLLER */
#endif /* _V4L2_MC_H */