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;
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,
.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);
* 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),
};
/**