CHROMIUM: [media] rk3288-vpu: Add suspend/resume handlers
authorTomasz Figa <tfiga@chromium.org>
Thu, 2 Apr 2015 05:03:26 +0000 (14:03 +0900)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 30 Jun 2016 11:54:22 +0000 (19:54 +0800)
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 <tfiga@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/263662
Reviewed-by: Pawel Osciak <posciak@chromium.org>
Change-Id: Id07b7d681ef78655879ce77c9705b1c25231df9d
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Signed-off-by: Yakir Yang <ykk@rock-chips.com>
drivers/media/platform/rk3288-vpu/rk3288_vpu.c
drivers/media/platform/rk3288-vpu/rk3288_vpu_common.h

index c7e5d9918671046ff88c17ad40fceefa48918d57..c9ea748148a22e6d1a1184ff4aea1de470d90653 100644 (file)
@@ -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);
index 34828369875f5678cd2a22dbd08ae6e032db3ecf..a074e2c63d60a650e706d08bac712c9e379adfce 100644 (file)
@@ -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),
 };
 
 /**