diff options
author | Frank Chen <frankc@nvidia.com> | 2013-06-11 12:33:13 -0700 |
---|---|---|
committer | Mrutyunjay Sawant <msawant@nvidia.com> | 2013-09-16 22:47:43 -0700 |
commit | 36dd739c294e67357cf1be371306a16158d85331 (patch) | |
tree | ea2dd01e8a4d3a1a71dc7da15560a98b9588015a /drivers/media | |
parent | 2322ffa96ca067c582b95853b999252bda08453b (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.c | 39 |
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) { |