diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-05-31 09:37:26 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-06-12 21:16:27 -0400 |
commit | 813f5c0ac5ccf7dd9c216a8f7fbe827ca36cb83f (patch) | |
tree | f4d4ebfcea1fa7fa25d4d3b447301bef13628e6e /drivers/media | |
parent | 4434adff80bf24c1c558a1605599665301185bdb (diff) |
[media] media: Change media device link_notify behaviour
Currently the media device link_notify callback is invoked before the
actual change of state of a link when the link is being enabled, and
after the actual change of state when the link is being disabled.
This doesn't allow a media device driver to perform any operations
on a full graph before a link is disabled, as well as performing
any tasks on a modified graph right after a link's state is changed.
This patch modifies signature of the link_notify callback. This
callback is now called always before and after a link's state change.
To distinguish the notifications a 'notification' argument is added
to the link_notify callback: MEDIA_DEV_NOTIFY_PRE_LINK_CH indicates
notification before link's state change and
MEDIA_DEV_NOTIFY_POST_LINK_CH corresponds to a notification after
link flags change.
[mchehab@redhat.com: whitespace cleanups]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/media-entity.c | 18 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.c | 18 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/isp.c | 41 |
3 files changed, 40 insertions, 37 deletions
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0438209d020a..df72f7d99d80 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c | |||
@@ -496,25 +496,17 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) | |||
496 | 496 | ||
497 | mdev = source->parent; | 497 | mdev = source->parent; |
498 | 498 | ||
499 | if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) { | 499 | if (mdev->link_notify) { |
500 | ret = mdev->link_notify(link->source, link->sink, | 500 | ret = mdev->link_notify(link, flags, |
501 | MEDIA_LNK_FL_ENABLED); | 501 | MEDIA_DEV_NOTIFY_PRE_LINK_CH); |
502 | if (ret < 0) | 502 | if (ret < 0) |
503 | return ret; | 503 | return ret; |
504 | } | 504 | } |
505 | 505 | ||
506 | ret = __media_entity_setup_link_notify(link, flags); | 506 | ret = __media_entity_setup_link_notify(link, flags); |
507 | if (ret < 0) | ||
508 | goto err; | ||
509 | 507 | ||
510 | if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) | 508 | if (mdev->link_notify) |
511 | mdev->link_notify(link->source, link->sink, 0); | 509 | mdev->link_notify(link, flags, MEDIA_DEV_NOTIFY_POST_LINK_CH); |
512 | |||
513 | return 0; | ||
514 | |||
515 | err: | ||
516 | if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) | ||
517 | mdev->link_notify(link->source, link->sink, 0); | ||
518 | 510 | ||
519 | return ret; | 511 | return ret; |
520 | } | 512 | } |
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index b5624931d16d..5298dd6680ae 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c | |||
@@ -1287,34 +1287,36 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) | |||
1287 | return __fimc_md_set_camclk(fmd, si, on); | 1287 | return __fimc_md_set_camclk(fmd, si, on); |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | static int fimc_md_link_notify(struct media_pad *source, | 1290 | static int fimc_md_link_notify(struct media_link *link, u32 flags, |
1291 | struct media_pad *sink, u32 flags) | 1291 | unsigned int notification) |
1292 | { | 1292 | { |
1293 | struct media_entity *sink = link->sink->entity; | ||
1293 | struct exynos_video_entity *ve; | 1294 | struct exynos_video_entity *ve; |
1294 | struct video_device *vdev; | 1295 | struct video_device *vdev; |
1295 | struct fimc_pipeline *pipeline; | 1296 | struct fimc_pipeline *pipeline; |
1296 | int i, ret = 0; | 1297 | int i, ret = 0; |
1297 | 1298 | ||
1298 | if (media_entity_type(sink->entity) != MEDIA_ENT_T_DEVNODE_V4L) | 1299 | if (media_entity_type(sink) != MEDIA_ENT_T_DEVNODE_V4L || |
1300 | notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) | ||
1299 | return 0; | 1301 | return 0; |
1300 | 1302 | ||
1301 | vdev = media_entity_to_video_device(sink->entity); | 1303 | vdev = media_entity_to_video_device(sink); |
1302 | ve = vdev_to_exynos_video_entity(vdev); | 1304 | ve = vdev_to_exynos_video_entity(vdev); |
1303 | pipeline = to_fimc_pipeline(ve->pipe); | 1305 | pipeline = to_fimc_pipeline(ve->pipe); |
1304 | 1306 | ||
1305 | if (!(flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) { | 1307 | if (!(link->flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) { |
1306 | if (sink->entity->use_count > 0) | 1308 | if (sink->use_count > 0) |
1307 | ret = __fimc_pipeline_close(ve->pipe); | 1309 | ret = __fimc_pipeline_close(ve->pipe); |
1308 | 1310 | ||
1309 | for (i = 0; i < IDX_MAX; i++) | 1311 | for (i = 0; i < IDX_MAX; i++) |
1310 | pipeline->subdevs[i] = NULL; | 1312 | pipeline->subdevs[i] = NULL; |
1311 | } else if (sink->entity->use_count > 0) { | 1313 | } else if (sink->use_count > 0) { |
1312 | /* | 1314 | /* |
1313 | * Link activation. Enable power of pipeline elements only if | 1315 | * Link activation. Enable power of pipeline elements only if |
1314 | * the pipeline is already in use, i.e. its video node is open. | 1316 | * the pipeline is already in use, i.e. its video node is open. |
1315 | * Recreate the controls destroyed during the link deactivation. | 1317 | * Recreate the controls destroyed during the link deactivation. |
1316 | */ | 1318 | */ |
1317 | ret = __fimc_pipeline_open(ve->pipe, sink->entity, true); | 1319 | ret = __fimc_pipeline_open(ve->pipe, sink, true); |
1318 | } | 1320 | } |
1319 | 1321 | ||
1320 | return ret ? -EPIPE : ret; | 1322 | return ret ? -EPIPE : ret; |
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index ff5a20afa691..df3a0ec7fd2c 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c | |||
@@ -792,9 +792,9 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) | |||
792 | 792 | ||
793 | /* | 793 | /* |
794 | * isp_pipeline_link_notify - Link management notification callback | 794 | * isp_pipeline_link_notify - Link management notification callback |
795 | * @source: Pad at the start of the link | 795 | * @link: The link |
796 | * @sink: Pad at the end of the link | ||
797 | * @flags: New link flags that will be applied | 796 | * @flags: New link flags that will be applied |
797 | * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*) | ||
798 | * | 798 | * |
799 | * React to link management on powered pipelines by updating the use count of | 799 | * React to link management on powered pipelines by updating the use count of |
800 | * all entities in the source and sink sides of the link. Entities are powered | 800 | * all entities in the source and sink sides of the link. Entities are powered |
@@ -804,29 +804,38 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) | |||
804 | * off is assumed to never fail. This function will not fail for disconnection | 804 | * off is assumed to never fail. This function will not fail for disconnection |
805 | * events. | 805 | * events. |
806 | */ | 806 | */ |
807 | static int isp_pipeline_link_notify(struct media_pad *source, | 807 | static int isp_pipeline_link_notify(struct media_link *link, u32 flags, |
808 | struct media_pad *sink, u32 flags) | 808 | unsigned int notification) |
809 | { | 809 | { |
810 | int source_use = isp_pipeline_pm_use_count(source->entity); | 810 | struct media_entity *source = link->source->entity; |
811 | int sink_use = isp_pipeline_pm_use_count(sink->entity); | 811 | struct media_entity *sink = link->sink->entity; |
812 | int source_use = isp_pipeline_pm_use_count(source); | ||
813 | int sink_use = isp_pipeline_pm_use_count(sink); | ||
812 | int ret; | 814 | int ret; |
813 | 815 | ||
814 | if (!(flags & MEDIA_LNK_FL_ENABLED)) { | 816 | if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && |
817 | !(link->flags & MEDIA_LNK_FL_ENABLED)) { | ||
815 | /* Powering off entities is assumed to never fail. */ | 818 | /* Powering off entities is assumed to never fail. */ |
816 | isp_pipeline_pm_power(source->entity, -sink_use); | 819 | isp_pipeline_pm_power(source, -sink_use); |
817 | isp_pipeline_pm_power(sink->entity, -source_use); | 820 | isp_pipeline_pm_power(sink, -source_use); |
818 | return 0; | 821 | return 0; |
819 | } | 822 | } |
820 | 823 | ||
821 | ret = isp_pipeline_pm_power(source->entity, sink_use); | 824 | if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && |
822 | if (ret < 0) | 825 | (flags & MEDIA_LNK_FL_ENABLED)) { |
823 | return ret; | ||
824 | 826 | ||
825 | ret = isp_pipeline_pm_power(sink->entity, source_use); | 827 | ret = isp_pipeline_pm_power(source, sink_use); |
826 | if (ret < 0) | 828 | if (ret < 0) |
827 | isp_pipeline_pm_power(source->entity, -sink_use); | 829 | return ret; |
828 | 830 | ||
829 | return ret; | 831 | ret = isp_pipeline_pm_power(sink, source_use); |
832 | if (ret < 0) | ||
833 | isp_pipeline_pm_power(source, -sink_use); | ||
834 | |||
835 | return ret; | ||
836 | } | ||
837 | |||
838 | return 0; | ||
830 | } | 839 | } |
831 | 840 | ||
832 | /* ----------------------------------------------------------------------------- | 841 | /* ----------------------------------------------------------------------------- |