[media] v4l: vsp1: Fix Suspend-to-RAM
Fix Suspend-to-RAM so that VSP1 driver continues to work after resuming. In detail, - Fix the judgment of ref count in resuming. - Add stopping VSP1 during suspend. [Refactor the suspend and resume code to lower suspend delay] Signed-off-by: Sei Fumizono <sei.fumizono.jw@hitachi-solutions.com> Signed-off-by: Yoshifumi Hosoya <yoshifumi.hosoya.wj@renesas.com> Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
45008ee929
commit
139c92866e
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* vsp1_drv.c -- R-Car VSP1 Driver
|
||||
*
|
||||
* Copyright (C) 2013-2014 Renesas Electronics Corporation
|
||||
* Copyright (C) 2013-2015 Renesas Electronics Corporation
|
||||
*
|
||||
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
|
||||
*
|
||||
|
@ -403,7 +403,10 @@ static int vsp1_pm_suspend(struct device *dev)
|
|||
if (vsp1->ref_count == 0)
|
||||
return 0;
|
||||
|
||||
vsp1_pipelines_suspend(vsp1);
|
||||
|
||||
clk_disable_unprepare(vsp1->clock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -413,10 +416,14 @@ static int vsp1_pm_resume(struct device *dev)
|
|||
|
||||
WARN_ON(mutex_is_locked(&vsp1->lock));
|
||||
|
||||
if (vsp1->ref_count)
|
||||
if (vsp1->ref_count == 0)
|
||||
return 0;
|
||||
|
||||
return clk_prepare_enable(vsp1->clock);
|
||||
clk_prepare_enable(vsp1->clock);
|
||||
|
||||
vsp1_pipelines_resume(vsp1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* vsp1_video.c -- R-Car VSP1 Video Node
|
||||
*
|
||||
* Copyright (C) 2013-2014 Renesas Electronics Corporation
|
||||
* Copyright (C) 2013-2015 Renesas Electronics Corporation
|
||||
*
|
||||
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
|
||||
*
|
||||
|
@ -703,6 +703,74 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
|
|||
}
|
||||
}
|
||||
|
||||
void vsp1_pipelines_suspend(struct vsp1_device *vsp1)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* To avoid increasing the system suspend time needlessly, loop over the
|
||||
* pipelines twice, first to set them all to the stopping state, and then
|
||||
* to wait for the stop to complete.
|
||||
*/
|
||||
for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
|
||||
struct vsp1_rwpf *wpf = vsp1->wpf[i];
|
||||
struct vsp1_pipeline *pipe;
|
||||
|
||||
if (wpf == NULL)
|
||||
continue;
|
||||
|
||||
pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
|
||||
if (pipe == NULL)
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(&pipe->irqlock, flags);
|
||||
if (pipe->state == VSP1_PIPELINE_RUNNING)
|
||||
pipe->state = VSP1_PIPELINE_STOPPING;
|
||||
spin_unlock_irqrestore(&pipe->irqlock, flags);
|
||||
}
|
||||
|
||||
for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
|
||||
struct vsp1_rwpf *wpf = vsp1->wpf[i];
|
||||
struct vsp1_pipeline *pipe;
|
||||
|
||||
if (wpf == NULL)
|
||||
continue;
|
||||
|
||||
pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
|
||||
if (pipe == NULL)
|
||||
continue;
|
||||
|
||||
ret = wait_event_timeout(pipe->wq,
|
||||
pipe->state == VSP1_PIPELINE_STOPPED,
|
||||
msecs_to_jiffies(500));
|
||||
if (ret == 0)
|
||||
dev_warn(vsp1->dev, "pipeline %u stop timeout\n",
|
||||
wpf->entity.index);
|
||||
}
|
||||
}
|
||||
|
||||
void vsp1_pipelines_resume(struct vsp1_device *vsp1)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Resume pipeline all running pipelines. */
|
||||
for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
|
||||
struct vsp1_rwpf *wpf = vsp1->wpf[i];
|
||||
struct vsp1_pipeline *pipe;
|
||||
|
||||
if (wpf == NULL)
|
||||
continue;
|
||||
|
||||
pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
|
||||
if (pipe == NULL)
|
||||
continue;
|
||||
|
||||
if (vsp1_pipeline_ready(pipe))
|
||||
vsp1_pipeline_run(pipe);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* videobuf2 Queue Operations
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* vsp1_video.h -- R-Car VSP1 Video Node
|
||||
*
|
||||
* Copyright (C) 2013-2014 Renesas Electronics Corporation
|
||||
* Copyright (C) 2013-2015 Renesas Electronics Corporation
|
||||
*
|
||||
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
|
||||
*
|
||||
|
@ -149,4 +149,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
|
|||
struct vsp1_entity *input,
|
||||
unsigned int alpha);
|
||||
|
||||
void vsp1_pipelines_suspend(struct vsp1_device *vsp1);
|
||||
void vsp1_pipelines_resume(struct vsp1_device *vsp1);
|
||||
|
||||
#endif /* __VSP1_VIDEO_H__ */
|
||||
|
|
Loading…
Reference in New Issue