From f76d4881d1287f059304dbb087e0a280b2cf0923 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 2 Apr 2015 14:03:26 +0900 Subject: [PATCH] CHROMIUM: [media] rk3288-vpu: Add suspend/resume handlers Currently the driver does not implement suspend and resume PM ops. However when system is entering suspend, the driver should prevent submitting further runs to the hardware and wait for current run to be finished. To resume playback after leaving sleep state, next run, if available, must be submitted to the hardware. This patch adds proper suspend and resume callbacks to handle this. BUG=chrome-os-partner:38565 TEST=suspend and resume veyron_jerry several times with video playing Signed-off-by: Tomasz Figa Reviewed-on: https://chromium-review.googlesource.com/263662 Reviewed-by: Pawel Osciak Change-Id: Id07b7d681ef78655879ce77c9705b1c25231df9d Signed-off-by: Jeffy Chen Signed-off-by: Yakir Yang --- .../media/platform/rk3288-vpu/rk3288_vpu.c | 30 ++++++++++++++++++- .../platform/rk3288-vpu/rk3288_vpu_common.h | 3 ++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rk3288-vpu/rk3288_vpu.c b/drivers/media/platform/rk3288-vpu/rk3288_vpu.c index c7e5d9918671..c9ea748148a2 100644 --- a/drivers/media/platform/rk3288-vpu/rk3288_vpu.c +++ b/drivers/media/platform/rk3288-vpu/rk3288_vpu.c @@ -102,7 +102,8 @@ static void rk3288_vpu_try_run(struct rk3288_vpu_dev *dev) spin_lock_irqsave(&dev->irqlock, flags); - if (list_empty(&dev->ready_ctxs)) + if (list_empty(&dev->ready_ctxs) || + test_bit(VPU_SUSPENDED, &dev->state)) /* Nothing to do. */ goto out; @@ -716,6 +717,32 @@ static const struct of_device_id of_rk3288_vpu_match[] = { MODULE_DEVICE_TABLE(of, of_rk3288_vpu_match); #endif +#ifdef CONFIG_PM_SLEEP +static int rk3288_vpu_suspend(struct device *dev) +{ + struct rk3288_vpu_dev *vpu = dev_get_drvdata(dev); + + set_bit(VPU_SUSPENDED, &vpu->state); + wait_event(vpu->run_wq, vpu->current_ctx == NULL); + + return 0; +} + +static int rk3288_vpu_resume(struct device *dev) +{ + struct rk3288_vpu_dev *vpu = dev_get_drvdata(dev); + + clear_bit(VPU_SUSPENDED, &vpu->state); + rk3288_vpu_try_run(vpu); + + return 0; +} +#endif + +static const struct dev_pm_ops rk3288_vpu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(rk3288_vpu_suspend, rk3288_vpu_resume) +}; + static struct platform_driver rk3288_vpu_driver = { .probe = rk3288_vpu_probe, .remove = rk3288_vpu_remove, @@ -724,6 +751,7 @@ static struct platform_driver rk3288_vpu_driver = { .name = RK3288_VPU_NAME, .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_rk3288_vpu_match), + .pm = &rk3288_vpu_pm_ops, }, }; module_platform_driver(rk3288_vpu_driver); diff --git a/drivers/media/platform/rk3288-vpu/rk3288_vpu_common.h b/drivers/media/platform/rk3288-vpu/rk3288_vpu_common.h index 34828369875f..a074e2c63d60 100644 --- a/drivers/media/platform/rk3288-vpu/rk3288_vpu_common.h +++ b/drivers/media/platform/rk3288-vpu/rk3288_vpu_common.h @@ -121,9 +121,12 @@ struct rk3288_vpu_buf { * enum rk3288_vpu_state - bitwise flags indicating hardware state. * @VPU_RUNNING: The hardware has been programmed for operation * and is running at the moment. + * @VPU_SUSPENDED: System is entering sleep state and no more runs + * should be executed on hardware. */ enum rk3288_vpu_state { VPU_RUNNING = BIT(0), + VPU_SUSPENDED = BIT(1), }; /** -- 2.34.1