media: video: tegra: Fix LP0 error while playing WV
Hyungwoo Yang [Sat, 16 Jun 2012 03:55:36 +0000 (20:55 -0700)]
Original change(commit dfa3daebbc8dbe3ccc8e72400359dfce29053222) to fix
LP0 error is already merged but the error is still there
due to porting issue to main branch.

This change fixes LP0 problem caused by porting to main.

Change-Id: I925407dc6c7fe0caca5ea33e3830a857b26e151c
Signed-off-by: Hyungwoo Yang <hyungwooy@nvidia.com>
Reviewed-on: http://git-master/r/109376
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>

drivers/media/video/tegra/nvavp/nvavp_dev.c

index c593a0a..cfe0332 100644 (file)
@@ -144,7 +144,6 @@ struct nvavp_info {
 #if defined(CONFIG_TEGRA_NVAVP_AUDIO)
        struct miscdevice               audio_misc_dev;
 #endif
-       atomic_t                        clock_stay_on_refcount;
 };
 
 struct nvavp_clientctx {
@@ -154,7 +153,7 @@ struct nvavp_clientctx {
        struct nvmap_handle_ref *gather_mem;
        int num_relocs;
        struct nvavp_info *nvavp;
-       int clock_stay_on;
+       u32 clk_reqs;
        int channel_id;
 };
 
@@ -273,8 +272,8 @@ static u32 nvavp_check_idle(struct nvavp_info *nvavp)
 {
        struct nvavp_channel *channel_info = nvavp_get_channel_info(nvavp, NVAVP_VIDEO_CHANNEL);
        struct nv_e276_control *control = channel_info->os_control;
-       return ((control->put == control->get)
-               && (!atomic_read(&nvavp->clock_stay_on_refcount))) ? 1 : 0;
+
+       return (control->put == control->get) ? 1 : 0;
 }
 
 static void clock_disable_handler(struct work_struct *work)
@@ -1246,16 +1245,15 @@ static int nvavp_force_clock_stay_on_ioctl(struct file *filp, unsigned int cmd,
                return -EINVAL;
        }
 
-       if (clientctx->clock_stay_on == clock.state)
-               return 0;
-
-       clientctx->clock_stay_on = clock.state;
-
-       if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_ENABLED)
-               atomic_inc(&nvavp->clock_stay_on_refcount);
-       else if (clientctx->clock_stay_on == NVAVP_CLOCK_STAY_ON_DISABLED)
-               atomic_dec(&nvavp->clock_stay_on_refcount);
-
+       mutex_lock(&nvavp->open_lock);
+       if (clock.state) {
+               if (clientctx->clk_reqs++ == 0)
+                       nvavp_clks_enable(nvavp);
+       } else {
+               if (--clientctx->clk_reqs == 0)
+                       nvavp_clks_disable(nvavp);
+       }
+       mutex_unlock(&nvavp->open_lock);
        return 0;
 }
 
@@ -1287,7 +1285,6 @@ static int tegra_nvavp_open(struct inode *inode, struct file *filp, int channel_
 
        clientctx->nvmap = nvavp->nvmap;
        clientctx->nvavp = nvavp;
-       clientctx->clock_stay_on = NVAVP_CLOCK_STAY_ON_DISABLED;
 
        filp->private_data = clientctx;
 
@@ -1329,8 +1326,10 @@ static int tegra_nvavp_release(struct inode *inode, struct file *filp)
                goto out;
        }
 
-       if (clientctx->clock_stay_on ==  NVAVP_CLOCK_STAY_ON_ENABLED)
-               atomic_dec(&nvavp->clock_stay_on_refcount);
+       /* if this client had any requests, drop our clk ref */
+       if (clientctx->clk_reqs)
+               nvavp_clks_disable(nvavp);
+
        if (nvavp->refcount > 0)
                nvavp->refcount--;
        if (!nvavp->refcount)