From aaf1944ecf5959abd648c9c788526026cfc0a5d5 Mon Sep 17 00:00:00 2001 From: Sanghwa Park Date: Wed, 13 Feb 2019 15:26:07 +0900 Subject: [PATCH] [RAMEN9610-12132] vipx: add suspend/resume interface Change-Id: I52ce913fbac7ec3ceda1e426e33643eaef88603d Signed-off-by: Sanghwa Park --- drivers/vision/vipx/vipx-core.c | 134 +++----------- drivers/vision/vipx/vipx-core.h | 13 +- drivers/vision/vipx/vipx-device.c | 296 ++++++++++++++++++------------ drivers/vision/vipx/vipx-device.h | 19 +- drivers/vision/vipx/vipx-system.c | 51 +++-- drivers/vision/vipx/vipx-system.h | 2 + 6 files changed, 261 insertions(+), 254 deletions(-) diff --git a/drivers/vision/vipx/vipx-core.c b/drivers/vision/vipx/vipx-core.c index 4af009c41937..e80bf26d5d24 100644 --- a/drivers/vision/vipx/vipx-core.c +++ b/drivers/vision/vipx/vipx-core.c @@ -16,32 +16,6 @@ #include "vipx-context.h" #include "vipx-core.h" -static inline int __vref_get(struct vipx_core_refcount *vref) -{ - int ret; - - vipx_enter(); - ret = (atomic_inc_return(&vref->refcount) == 1) ? - vref->first(vref->core) : 0; - if (ret) - atomic_dec(&vref->refcount); - vipx_leave(); - return ret; -} - -static inline int __vref_put(struct vipx_core_refcount *vref) -{ - int ret; - - vipx_enter(); - ret = (atomic_dec_return(&vref->refcount) == 0) ? - vref->final(vref->core) : 0; - if (ret) - atomic_inc(&vref->refcount); - vipx_leave(); - return ret; -} - static int vipx_core_set_graph(struct vipx_context *vctx, struct vs4l_graph *ginfo) { @@ -238,7 +212,7 @@ p_err_lock: static int vipx_core_streamon(struct vipx_context *vctx) { int ret; - struct vipx_core *core; + struct vipx_device *vdev; vipx_enter(); if (mutex_lock_interruptible(&vctx->lock)) { @@ -255,12 +229,10 @@ static int vipx_core_streamon(struct vipx_context *vctx) goto p_err_state; } - core = vctx->core; - ret = __vref_get(&core->start_cnt); - if (ret) { - vipx_err("vref_get(start) is fail(%d)\n", ret); - goto p_err_vref; - } + vdev = vctx->core->device; + ret = vipx_device_start(vdev); + if (ret) + goto p_err_start; ret = vctx->queue_ops->streamon(&vctx->queue_list); if (ret) @@ -271,7 +243,8 @@ static int vipx_core_streamon(struct vipx_context *vctx) vipx_leave(); return 0; p_err_queue_ops: -p_err_vref: + vipx_device_stop(vdev); +p_err_start: p_err_state: mutex_unlock(&vctx->lock); p_err_lock: @@ -281,7 +254,6 @@ p_err_lock: static int vipx_core_streamoff(struct vipx_context *vctx) { int ret; - struct vipx_core *core; vipx_enter(); if (mutex_lock_interruptible(&vctx->lock)) { @@ -301,18 +273,12 @@ static int vipx_core_streamoff(struct vipx_context *vctx) if (ret) goto p_err_queue_ops; - core = vctx->core; - ret = __vref_put(&core->start_cnt); - if (ret) { - vipx_err("vref_put(start) is fail(%d)\n", ret); - goto p_err_vref; - } + vipx_device_stop(vctx->core->device); vctx->state = BIT(VIPX_CONTEXT_STOP); mutex_unlock(&vctx->lock); vipx_leave(); return 0; -p_err_vref: p_err_queue_ops: p_err_state: mutex_unlock(&vctx->lock); @@ -483,15 +449,15 @@ static int vipx_open(struct inode *inode, struct file *file) { int ret; struct miscdevice *miscdev; - struct vipx_device *device; + struct vipx_device *vdev; struct vipx_core *core; struct vipx_context *vctx; struct vipx_graph *graph; vipx_enter(); miscdev = file->private_data; - device = dev_get_drvdata(miscdev->parent); - core = &device->core; + vdev = dev_get_drvdata(miscdev->parent); + core = &vdev->core; if (mutex_lock_interruptible(&core->lock)) { ret = -ERESTARTSYS; @@ -499,11 +465,9 @@ static int vipx_open(struct inode *inode, struct file *file) goto p_err_lock; } - ret = __vref_get(&core->open_cnt); - if (ret) { - vipx_err("vref_get(open) is fail(%d)", ret); - goto p_err_vref; - } + ret = vipx_device_open(vdev); + if (ret) + goto p_err_device; vctx = vipx_context_create(core); if (IS_ERR(vctx)) { @@ -528,8 +492,8 @@ static int vipx_open(struct inode *inode, struct file *file) return 0; p_err_graph: p_err_vctx: - __vref_put(&core->open_cnt); -p_err_vref: + vipx_device_close(vdev); +p_err_device: mutex_unlock(&core->lock); vipx_err("Failed to open the vipx [%d]\n", ret); p_err_lock: @@ -554,7 +518,7 @@ static int vipx_release(struct inode *inode, struct file *file) vipx_graph_destroy(vctx->graph); vipx_context_destroy(vctx); - __vref_put(&core->open_cnt); + vipx_device_close(core->device); mutex_unlock(&core->lock); vipx_info("The vipx has been closed\n"); @@ -595,73 +559,33 @@ const struct file_operations vipx_file_ops = { .compat_ioctl = vipx_compat_ioctl }; -static int __vref_open(struct vipx_core *core) -{ - vipx_check(); - atomic_set(&core->start_cnt.refcount, 0); - return vipx_device_open(core->device); -} - -static int __vref_close(struct vipx_core *core) -{ - vipx_check(); - return vipx_device_close(core->device); -} - -static int __vref_start(struct vipx_core *core) -{ - vipx_check(); - return vipx_device_start(core->device); -} - -static int __vref_stop(struct vipx_core *core) -{ - vipx_check(); - return vipx_device_stop(core->device); -} - -static inline void __vref_init(struct vipx_core_refcount *vref, - struct vipx_core *core, - int (*first)(struct vipx_core *core), - int (*final)(struct vipx_core *core)) -{ - vipx_enter(); - vref->core = core; - vref->first = first; - vref->final = final; - atomic_set(&vref->refcount, 0); - vipx_leave(); -} - /* Top-level data for debugging */ -static struct vipx_dev *vdev; +static struct vipx_miscdev *misc_vdev; -int vipx_core_probe(struct vipx_device *device) +int vipx_core_probe(struct vipx_device *vdev) { int ret; struct vipx_core *core; vipx_enter(); - core = &device->core; - core->device = device; - core->system = &device->system; - vdev = &core->vdev; + core = &vdev->core; + core->device = vdev; + core->system = &vdev->system; + misc_vdev = &core->misc_vdev; mutex_init(&core->lock); - __vref_init(&core->open_cnt, core, __vref_open, __vref_close); - __vref_init(&core->start_cnt, core, __vref_start, __vref_stop); core->ioc_ops = &vipx_core_ioctl_ops; vipx_util_bitmap_init(core->vctx_map, VIPX_MAX_CONTEXT); INIT_LIST_HEAD(&core->vctx_list); core->vctx_count = 0; - vdev->miscdev.minor = MISC_DYNAMIC_MINOR; - vdev->miscdev.name = VIPX_DEV_NAME; - vdev->miscdev.fops = &vipx_file_ops; - vdev->miscdev.parent = device->dev; + core->misc_vdev.miscdev.minor = MISC_DYNAMIC_MINOR; + core->misc_vdev.miscdev.name = VIPX_DEV_NAME; + core->misc_vdev.miscdev.fops = &vipx_file_ops; + core->misc_vdev.miscdev.parent = vdev->dev; - ret = misc_register(&vdev->miscdev); + ret = misc_register(&core->misc_vdev.miscdev); if (ret) { vipx_err("miscdevice is not registered (%d)\n", ret); goto p_err_misc; @@ -677,7 +601,7 @@ p_err_misc: void vipx_core_remove(struct vipx_core *core) { vipx_enter(); - misc_deregister(&core->vdev.miscdev); + misc_deregister(&core->misc_vdev.miscdev); mutex_destroy(&core->lock); vipx_leave(); } diff --git a/drivers/vision/vipx/vipx-core.h b/drivers/vision/vipx/vipx-core.h index 315b39a80d7e..953aa4d68a7a 100644 --- a/drivers/vision/vipx/vipx-core.h +++ b/drivers/vision/vipx/vipx-core.h @@ -24,24 +24,15 @@ struct vipx_device; struct vipx_core; -struct vipx_core_refcount { - atomic_t refcount; - struct vipx_core *core; - int (*first)(struct vipx_core *core); - int (*final)(struct vipx_core *core); -}; - -struct vipx_dev { +struct vipx_miscdev { int minor; char name[VIPX_DEV_NAME_LEN]; struct miscdevice miscdev; }; struct vipx_core { - struct vipx_dev vdev; + struct vipx_miscdev misc_vdev; struct mutex lock; - struct vipx_core_refcount open_cnt; - struct vipx_core_refcount start_cnt; const struct vipx_ioctl_ops *ioc_ops; DECLARE_BITMAP(vctx_map, VIPX_MAX_CONTEXT); struct list_head vctx_list; diff --git a/drivers/vision/vipx/vipx-device.c b/drivers/vision/vipx/vipx-device.c index 9f66acbed1b7..edfd41227b29 100644 --- a/drivers/vision/vipx/vipx-device.c +++ b/drivers/vision/vipx/vipx-device.c @@ -19,7 +19,7 @@ #include "vipx-graph.h" #include "vipx-device.h" -void __vipx_fault_handler(struct vipx_device *device) +static void __vipx_fault_handler(struct vipx_device *vdev) { vipx_enter(); vipx_leave(); @@ -29,44 +29,122 @@ static int __attribute__((unused)) vipx_fault_handler( struct iommu_domain *domain, struct device *dev, unsigned long fault_addr, int fault_flag, void *token) { - struct vipx_device *device; + struct vipx_device *vdev; pr_err("< VIPX FAULT HANDLER >\n"); pr_err("Device virtual(0x%lX) is invalid access\n", fault_addr); - device = dev_get_drvdata(dev); + vdev = dev_get_drvdata(dev); vipx_debug_dump_debug_regs(); - __vipx_fault_handler(device); + __vipx_fault_handler(vdev); return -EINVAL; } +static int __vipx_device_start(struct vipx_device *vdev) +{ + int ret; + + vipx_enter(); + ret = vipx_system_start(&vdev->system); + if (ret) + goto p_err_system; + + ret = vipx_debug_start(&vdev->debug); + if (ret) + goto p_err_debug; + + vipx_leave(); + return 0; +p_err_debug: + vipx_system_stop(&vdev->system); +p_err_system: + return ret; +} + +static int __vipx_device_stop(struct vipx_device *vdev) +{ + vipx_enter(); + vipx_debug_stop(&vdev->debug); + vipx_system_stop(&vdev->system); + vipx_leave(); + return 0; +} + #if defined(CONFIG_PM_SLEEP) static int vipx_device_suspend(struct device *dev) { + int ret; + struct vipx_device *vdev; + vipx_enter(); + vdev = dev_get_drvdata(dev); + + mutex_lock(&vdev->open_lock); + if (!vdev->open_count) { + vipx_warn("device is already closed\n"); + mutex_unlock(&vdev->open_lock); + return 0; + } + + mutex_lock(&vdev->start_lock); + vdev->suspended = true; + if (vdev->start_count) + __vipx_device_stop(vdev); + mutex_unlock(&vdev->start_lock); + + ret = vipx_system_suspend(&vdev->system); + if (ret) + goto p_err; + vipx_leave(); - return 0; +p_err: + mutex_unlock(&vdev->open_lock); + return ret; } static int vipx_device_resume(struct device *dev) { + int ret; + struct vipx_device *vdev; + vipx_enter(); + vdev = dev_get_drvdata(dev); + + mutex_lock(&vdev->open_lock); + if (!vdev->open_count) { + vipx_warn("device is already closed\n"); + mutex_unlock(&vdev->open_lock); + return 0; + } + + ret = vipx_system_resume(&vdev->system); + if (ret) + goto p_err; + + mutex_lock(&vdev->start_lock); + vdev->suspended = false; + if (vdev->start_count) + __vipx_device_start(vdev); + mutex_unlock(&vdev->start_lock); + vipx_leave(); - return 0; +p_err: + mutex_unlock(&vdev->open_lock); + return ret; } #endif static int vipx_device_runtime_suspend(struct device *dev) { int ret; - struct vipx_device *device; + struct vipx_device *vdev; vipx_enter(); - device = dev_get_drvdata(dev); + vdev = dev_get_drvdata(dev); - ret = vipx_system_runtime_suspend(&device->system); + ret = vipx_system_runtime_suspend(&vdev->system); if (ret) goto p_err; @@ -78,12 +156,12 @@ p_err: static int vipx_device_runtime_resume(struct device *dev) { int ret; - struct vipx_device *device; + struct vipx_device *vdev; vipx_enter(); - device = dev_get_drvdata(dev); + vdev = dev_get_drvdata(dev); - ret = vipx_system_runtime_resume(&device->system); + ret = vipx_system_runtime_resume(&vdev->system); if (ret) goto p_err; @@ -102,66 +180,60 @@ static const struct dev_pm_ops vipx_pm_ops = { NULL) }; -static int __vipx_device_start(struct vipx_device *device) +int vipx_device_start(struct vipx_device *vdev) { int ret; vipx_enter(); - if (!test_bit(VIPX_DEVICE_STATE_OPEN, &device->state)) { - ret = -EINVAL; - vipx_err("device was not opend yet (%lx)\n", device->state); - goto p_err_state; + mutex_lock(&vdev->start_lock); + if (vdev->suspended) { + ret = -ENOSTR; + vipx_err("Failed to start device as it was suspended(%d)\n", + ret); + goto p_err; } - if (test_bit(VIPX_DEVICE_STATE_START, &device->state)) + if (vdev->start_count) { + vdev->start_count++; + mutex_unlock(&vdev->start_lock); return 0; + } - ret = vipx_system_start(&device->system); - if (ret) - goto p_err_system; - - ret = vipx_debug_start(&device->debug); + ret = __vipx_device_start(vdev); if (ret) - goto p_err_debug; - - set_bit(VIPX_DEVICE_STATE_START, &device->state); + goto p_err; + vdev->start_count = 1; vipx_leave(); - return 0; -p_err_debug: - vipx_system_stop(&device->system); -p_err_system: -p_err_state: +p_err: + mutex_unlock(&vdev->start_lock); return ret; } -static int __vipx_device_stop(struct vipx_device *device) +int vipx_device_stop(struct vipx_device *vdev) { vipx_enter(); - if (!test_bit(VIPX_DEVICE_STATE_START, &device->state)) - return 0; - - vipx_debug_stop(&device->debug); - vipx_system_stop(&device->system); - clear_bit(VIPX_DEVICE_STATE_START, &device->state); - + mutex_lock(&vdev->start_lock); + if (!(--vdev->start_count) && !vdev->suspended) + __vipx_device_stop(vdev); + mutex_unlock(&vdev->start_lock); vipx_leave(); return 0; } -static int __vipx_device_power_on(struct vipx_device *device) +static int __vipx_device_power_on(struct vipx_device *vdev) { int ret; vipx_enter(); #if defined(CONFIG_PM) - ret = pm_runtime_get_sync(device->dev); + ret = pm_runtime_get_sync(vdev->dev); if (ret) { vipx_err("Failed to get pm_runtime sync (%d)\n", ret); goto p_err; } #else - ret = vipx_device_runtime_resume(device->dev); + ret = vipx_device_runtime_resume(vdev->dev); if (ret) goto p_err; #endif @@ -171,19 +243,19 @@ p_err: return ret; } -static int __vipx_device_power_off(struct vipx_device *device) +static int __vipx_device_power_off(struct vipx_device *vdev) { int ret; vipx_enter(); #if defined(CONFIG_PM) - ret = pm_runtime_put_sync(device->dev); + ret = pm_runtime_put_sync(vdev->dev); if (ret) { vipx_err("Failed to put pm_runtime sync (%d)\n", ret); goto p_err; } #else - ret = vipx_device_runtime_suspend(device->dev); + ret = vipx_device_runtime_suspend(vdev->dev); if (ret) goto p_err; #endif @@ -193,94 +265,79 @@ p_err: return ret; } -int vipx_device_start(struct vipx_device *device) -{ - int ret; - - vipx_enter(); - ret = __vipx_device_start(device); - if (ret) - goto p_err; - - vipx_leave(); -p_err: - return ret; -} - -int vipx_device_stop(struct vipx_device *device) -{ - int ret; - - vipx_enter(); - ret = __vipx_device_stop(device); - if (ret) - goto p_err; - - vipx_leave(); -p_err: - return ret; -} - -int vipx_device_open(struct vipx_device *device) +int vipx_device_open(struct vipx_device *vdev) { int ret; vipx_enter(); - if (test_bit(VIPX_DEVICE_STATE_OPEN, &device->state)) { - ret = -EINVAL; - vipx_warn("device was already opened\n"); - goto p_err_state; + mutex_lock(&vdev->open_lock); + if (vdev->open_count) { + vdev->open_count++; + mutex_unlock(&vdev->open_lock); + return 0; } - ret = vipx_system_open(&device->system); + ret = vipx_system_open(&vdev->system); if (ret) goto p_err_system; - ret = vipx_debug_open(&device->debug); + ret = vipx_debug_open(&vdev->debug); if (ret) goto p_err_debug; - ret = __vipx_device_power_on(device); + ret = __vipx_device_power_on(vdev); if (ret) goto p_err_power; - ret = vipx_system_fw_bootup(&device->system); + ret = vipx_system_fw_bootup(&vdev->system); if (ret) goto p_err_boot; - set_bit(VIPX_DEVICE_STATE_OPEN, &device->state); + vdev->open_count = 1; + mutex_lock(&vdev->start_lock); + vdev->start_count = 0; + vdev->suspended = false; + mutex_unlock(&vdev->start_lock); + mutex_unlock(&vdev->open_lock); vipx_leave(); return 0; p_err_boot: - __vipx_device_power_off(device); + __vipx_device_power_off(vdev); p_err_power: - vipx_debug_close(&device->debug); + vipx_debug_close(&vdev->debug); p_err_debug: - vipx_system_close(&device->system); + vipx_system_close(&vdev->system); p_err_system: -p_err_state: + mutex_unlock(&vdev->open_lock); return ret; } -int vipx_device_close(struct vipx_device *device) +int vipx_device_close(struct vipx_device *vdev) { vipx_enter(); - if (!test_bit(VIPX_DEVICE_STATE_OPEN, &device->state)) { + mutex_lock(&vdev->open_lock); + if (!vdev->open_count) { vipx_warn("device is already closed\n"); - goto p_err; + goto p_end; } - if (test_bit(VIPX_DEVICE_STATE_START, &device->state)) - __vipx_device_stop(device); - - __vipx_device_power_off(device); - vipx_debug_close(&device->debug); - vipx_system_close(&device->system); - clear_bit(VIPX_DEVICE_STATE_OPEN, &device->state); + if (!(--vdev->open_count)) { + mutex_lock(&vdev->start_lock); + if (vdev->start_count) { + __vipx_device_stop(vdev); + vdev->start_count = 0; + } + mutex_unlock(&vdev->start_lock); + + __vipx_device_power_off(vdev); + vipx_debug_close(&vdev->debug); + vipx_system_close(&vdev->system); + } vipx_leave(); -p_err: +p_end: + mutex_unlock(&vdev->open_lock); return 0; } @@ -288,31 +345,36 @@ static int vipx_device_probe(struct platform_device *pdev) { int ret; struct device *dev; - struct vipx_device *device; + struct vipx_device *vdev; vipx_enter(); dev = &pdev->dev; - device = devm_kzalloc(dev, sizeof(*device), GFP_KERNEL); - if (!device) { + vdev = devm_kzalloc(dev, sizeof(*vdev), GFP_KERNEL); + if (!vdev) { ret = -ENOMEM; vipx_err("Fail to alloc device structure\n"); goto p_err_alloc; } get_device(dev); - device->dev = dev; - dev_set_drvdata(dev, device); + vdev->dev = dev; + dev_set_drvdata(dev, vdev); + + mutex_init(&vdev->open_lock); + vdev->open_count = 0; + mutex_init(&vdev->start_lock); + vdev->start_count = 0; - ret = vipx_system_probe(device); + ret = vipx_system_probe(vdev); if (ret) goto p_err_system; - ret = vipx_core_probe(device); + ret = vipx_core_probe(vdev); if (ret) goto p_err_core; - ret = vipx_debug_probe(device); + ret = vipx_debug_probe(vdev); if (ret) goto p_err_debug; @@ -322,11 +384,11 @@ static int vipx_device_probe(struct platform_device *pdev) vipx_info("vipx device is initilized\n"); return 0; p_err_debug: - vipx_core_remove(&device->core); + vipx_core_remove(&vdev->core); p_err_core: - vipx_system_remove(&device->system); + vipx_system_remove(&vdev->system); p_err_system: - devm_kfree(dev, device); + devm_kfree(dev, vdev); p_err_alloc: vipx_err("vipx device is not registered (%d)\n", ret); return ret; @@ -334,25 +396,25 @@ p_err_alloc: static int vipx_device_remove(struct platform_device *pdev) { - struct vipx_device *device; + struct vipx_device *vdev; vipx_enter(); - device = dev_get_drvdata(&pdev->dev); + vdev = dev_get_drvdata(&pdev->dev); - vipx_debug_remove(&device->debug); - vipx_core_remove(&device->core); - vipx_system_remove(&device->system); - devm_kfree(device->dev, device); + vipx_debug_remove(&vdev->debug); + vipx_core_remove(&vdev->core); + vipx_system_remove(&vdev->system); + devm_kfree(vdev->dev, vdev); vipx_leave(); return 0; } static void vipx_device_shutdown(struct platform_device *pdev) { - struct vipx_device *device; + struct vipx_device *vdev; vipx_enter(); - device = dev_get_drvdata(&pdev->dev); + vdev = dev_get_drvdata(&pdev->dev); vipx_leave(); } diff --git a/drivers/vision/vipx/vipx-device.h b/drivers/vision/vipx/vipx-device.h index dbd0c79005dd..520c11fca36c 100644 --- a/drivers/vision/vipx/vipx-device.h +++ b/drivers/vision/vipx/vipx-device.h @@ -19,23 +19,22 @@ struct vipx_device; -enum vipx_device_state { - VIPX_DEVICE_STATE_OPEN, - VIPX_DEVICE_STATE_START -}; - struct vipx_device { struct device *dev; - unsigned long state; + struct mutex open_lock; + unsigned int open_count; + struct mutex start_lock; + unsigned int start_count; + bool suspended; struct vipx_system system; struct vipx_core core; struct vipx_debug debug; }; -int vipx_device_open(struct vipx_device *device); -int vipx_device_close(struct vipx_device *device); -int vipx_device_start(struct vipx_device *device); -int vipx_device_stop(struct vipx_device *device); +int vipx_device_open(struct vipx_device *vdev); +int vipx_device_close(struct vipx_device *vdev); +int vipx_device_start(struct vipx_device *vdev); +int vipx_device_stop(struct vipx_device *vdev); #endif diff --git a/drivers/vision/vipx/vipx-system.c b/drivers/vision/vipx/vipx-system.c index 1a00a0432755..09592d9adad5 100644 --- a/drivers/vision/vipx/vipx-system.c +++ b/drivers/vision/vipx/vipx-system.c @@ -34,9 +34,7 @@ int vipx_system_fw_bootup(struct vipx_system *sys) mem = &sys->memory; bin = &sys->binary; - ret = sys->ctrl_ops->reset(sys); - if (ret) - goto p_err; + sys->ctrl_ops->reset(sys); ret = vipx_binary_read(bin, NULL, VIPX_FW_DRAM_NAME, mem->fw.kvaddr, mem->fw.size); @@ -61,9 +59,7 @@ int vipx_system_fw_bootup(struct vipx_system *sys) if (ret) goto p_err; - ret = sys->ctrl_ops->start(sys); - if (ret) - goto p_err; + sys->ctrl_ops->start(sys); ret = vipx_hw_wait_bootup(&sys->interface); if (ret) @@ -103,6 +99,43 @@ p_err: return ret; } +int vipx_system_resume(struct vipx_system *sys) +{ + int ret; + struct vipx_pm *pm; + + vipx_enter(); + pm = &sys->pm; + + if (vipx_pm_qos_active(pm)) { + vipx_pm_qos_resume(pm); + ret = vipx_system_fw_bootup(sys); + if (ret) + goto p_err; + } + + vipx_leave(); + return 0; +p_err: + return ret; +} + +int vipx_system_suspend(struct vipx_system *sys) +{ + struct vipx_pm *pm; + + vipx_enter(); + pm = &sys->pm; + + if (vipx_pm_qos_active(pm)) { + sys->ctrl_ops->reset(sys); + vipx_pm_qos_suspend(&sys->pm); + } + + vipx_leave(); + return 0; +} + int vipx_system_runtime_resume(struct vipx_system *sys) { int ret; @@ -134,11 +167,7 @@ p_err_clk_on: int vipx_system_runtime_suspend(struct vipx_system *sys) { vipx_enter(); - //TODO check this - //ret = sys->ctrl_ops->reset(sys); - //if (ret) - // vipx_err("Failed to reset for power down (%d)\n", ret); - + sys->ctrl_ops->reset(sys); iovmm_deactivate(sys->dev); sys->clk_ops->off(sys); vipx_pm_close(&sys->pm); diff --git a/drivers/vision/vipx/vipx-system.h b/drivers/vision/vipx/vipx-system.h index 03ae2055b7ac..edc118e336c1 100644 --- a/drivers/vision/vipx/vipx-system.h +++ b/drivers/vision/vipx/vipx-system.h @@ -44,6 +44,8 @@ struct vipx_system { int vipx_system_fw_bootup(struct vipx_system *sys); +int vipx_system_resume(struct vipx_system *sys); +int vipx_system_suspend(struct vipx_system *sys); int vipx_system_runtime_resume(struct vipx_system *sys); int vipx_system_runtime_suspend(struct vipx_system *sys); -- 2.20.1