summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorFrank Chen <frankc@nvidia.com>2013-06-11 12:33:13 -0700
committerMrutyunjay Sawant <msawant@nvidia.com>2013-09-16 22:47:43 -0700
commit36dd739c294e67357cf1be371306a16158d85331 (patch)
treeea2dd01e8a4d3a1a71dc7da15560a98b9588015a /drivers/media
parent2322ffa96ca067c582b95853b999252bda08453b (diff)
media: video: tegra: Fix kernel warning for DW9718
Fix unbalanced reference count for power regulator to prevent kernel from generating warning messages. bug 1342770 Change-Id: Ie2505ea399ecd7865b69c00f7f51752fdc03c4f7 Signed-off-by: Frank Chen <frankc@nvidia.com> Reviewed-on: http://git-master/r/258905 Reviewed-by: Charlie Huang <chahuang@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tegra/dw9718.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/drivers/media/video/tegra/dw9718.c b/drivers/media/video/tegra/dw9718.c
index 4b4b444e9597..a4176da8018b 100644
--- a/drivers/media/video/tegra/dw9718.c
+++ b/drivers/media/video/tegra/dw9718.c
@@ -123,6 +123,7 @@ struct dw9718_info {
struct nv_focuser_config nv_config;
atomic_t in_use;
bool reset_flag;
+ int pwr_api;
int pwr_dev;
int status;
u32 cur_pos;
@@ -353,16 +354,35 @@ static int dw9718_power_get(struct dw9718_info *info)
return 0;
}
+static int dw9718_pm_api_wr(struct dw9718_info *info, int pwr)
+{
+ int err = 0;
+
+ if (!pwr || (pwr > NVC_PWR_ON))
+ return 0;
+
+ if (pwr > info->pwr_dev)
+ err = dw9718_pm_wr(info, pwr);
+ if (!err)
+ info->pwr_api = pwr;
+ else
+ info->pwr_api = NVC_PWR_ERR;
+ if (info->pdata->cfg & NVC_CFG_NOERR)
+ return 0;
+
+ return err;
+}
+
static int dw9718_pm_dev_wr(struct dw9718_info *info, int pwr)
{
- if (pwr < info->pwr_dev)
- pwr = info->pwr_dev;
+ if (pwr < info->pwr_api)
+ pwr = info->pwr_api;
return dw9718_pm_wr(info, pwr);
}
static void dw9718_pm_exit(struct dw9718_info *info)
{
- dw9718_pm_wr(info, NVC_PWR_OFF_FORCE);
+ dw9718_pm_dev_wr(info, NVC_PWR_OFF_FORCE);
dw9718_power_put(&info->power);
}
@@ -376,8 +396,8 @@ static int dw9718_reset(struct dw9718_info *info, u32 level)
err |= dw9718_i2c_wr8(info, DW9718_POWER_DN, 0x00);
usleep_range(100, 120);
} else
- err = dw9718_pm_wr(info, NVC_PWR_OFF_FORCE);
-
+ err = dw9718_pm_dev_wr(info, NVC_PWR_OFF_FORCE);
+ err |= dw9718_pm_wr(info, info->pwr_api);
return err;
}
@@ -607,7 +627,7 @@ static int dw9718_param_wr(struct dw9718_info *info, unsigned long arg)
case NVC_SYNC_STEREO:
if (info->s_info != NULL) {
/* sync power */
- info->s_info->pwr_dev = info->pwr_dev;
+ info->s_info->pwr_api = info->pwr_api;
/* move slave lens to master position */
err = dw9718_position_wr(info->s_info,
(s32)info->cur_pos);
@@ -685,13 +705,13 @@ static long dw9718_ioctl(struct file *file,
pwr = (int)arg * 2;
dev_dbg(&info->i2c_client->dev, "%s PWR_WR: %d\n",
__func__, pwr);
- err = dw9718_pm_dev_wr(info, pwr);
+ err = dw9718_pm_api_wr(info, pwr);
return err;
case NVC_IOCTL_PWR_RD:
if (info->s_mode == NVC_SYNC_SLAVE)
- pwr = info->s_info->pwr_dev;
+ pwr = info->s_info->pwr_api / 2;
else
- pwr = info->pwr_dev;
+ pwr = info->pwr_api / 2;
dev_dbg(&info->i2c_client->dev, "%s PWR_RD: %d\n",
__func__, pwr);
if (copy_to_user((void __user *)arg,
@@ -904,6 +924,7 @@ static int dw9718_probe(
spin_unlock(&dw9718_spinlock);
dw9718_power_get(info);
dw9718_sdata_init(info);
+ info->pwr_api = NVC_PWR_OFF;
if (info->pdata->cfg & (NVC_CFG_NODEV | NVC_CFG_BOOT_INIT)) {
err = dw9718_detect(info);
if (err < 0) {