[RAMEN9610-12132] vipx: add suspend/resume interface
authorSanghwa Park <senius.park@samsung.com>
Wed, 13 Feb 2019 06:26:07 +0000 (15:26 +0900)
committerhskang <hs1218.kang@samsung.com>
Thu, 14 Feb 2019 12:45:39 +0000 (21:45 +0900)
Change-Id: I52ce913fbac7ec3ceda1e426e33643eaef88603d
Signed-off-by: Sanghwa Park <senius.park@samsung.com>
drivers/vision/vipx/vipx-core.c
drivers/vision/vipx/vipx-core.h
drivers/vision/vipx/vipx-device.c
drivers/vision/vipx/vipx-device.h
drivers/vision/vipx/vipx-system.c
drivers/vision/vipx/vipx-system.h

index 4af009c41937e7d855df60de690b6d945e7c09d4..e80bf26d5d2450e502820f6181097c3c87978ca3 100644 (file)
 #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();
 }
index 315b39a80d7e562fbbdb039dc46ecd32e4887a43..953aa4d68a7a684ec4f0d3571ff3da7a89c06374 100644 (file)
 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;
index 9f66acbed1b73524f5693d2c9bdabc6bdb8b7d4a..edfd41227b29e8334ae374bad8ac125ac1ae8be9 100644 (file)
@@ -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();
 }
 
index dbd0c79005dd8c2e92e8f1757285397f4c3a61c6..520c11fca36cfbdd7325f536faf8327982c0f180 100644 (file)
 
 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
index 1a00a04327550692572ea02622736c7ad6fc757f..09592d9adad5a02ebec0eb14a0d35cf64c20a74f 100644 (file)
@@ -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);
index 03ae2055b7ac4dcee9d0874f7592a710767fae75..edc118e336c1b3f90ba20e1ea93003575181d3c5 100644 (file)
@@ -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);