summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorDavid Pu <dpu@nvidia.com>2013-07-17 10:03:07 +0800
committerHarshada Kale <hkale@nvidia.com>2013-07-30 04:48:23 -0700
commit48dbf16c280f7846c3360c50a4f4cfc824d0f5fc (patch)
tree9733c99975968031e3603dae3b412f9043d5fff4 /drivers/media
parent33cf78ad018222f764a536f8e668053626d5c857 (diff)
media: video: fix deadlock in edp client driver
don't call edp api in throttle callback or deadlock will happen since the edp lock is held from caller. Bug 1327193 Change-Id: I6b90630d0a37d53521c1db4e95f5945f184a70f5 Signed-off-by: David Pu <dpu@nvidia.com> Reviewed-on: http://git-master/r/247173 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Rick Song <ricks@nvidia.com> Reviewed-by: Charlie Huang <chahuang@nvidia.com> Reviewed-by: Sivaram Nair <sivaramn@nvidia.com> Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tegra/max77387.c37
-rw-r--r--drivers/media/video/tegra/max77665-flash.c37
2 files changed, 54 insertions, 20 deletions
diff --git a/drivers/media/video/tegra/max77387.c b/drivers/media/video/tegra/max77387.c
index 5f871a3a5b92..1ec138f30f68 100644
--- a/drivers/media/video/tegra/max77387.c
+++ b/drivers/media/video/tegra/max77387.c
@@ -509,6 +509,7 @@ static int max77387_edp_req(struct max77387_info *info,
return 0;
}
+
static int max77387_set_leds(struct max77387_info *info,
u8 mask, u8 curr1, u8 curr2)
{
@@ -533,15 +534,10 @@ static int max77387_set_leds(struct max77387_info *info,
info->regs.led2_tcurr = 0;
info->regs.leds_en = 0;
info->regs.regs_stale = false;
- max77387_edp_lowest(info);
}
goto set_leds_end;
}
- err = max77387_edp_req(info, mask, &curr1, &curr2);
- if (err)
- goto set_leds_end;
-
if (mask & 1) {
if (info->op_mode == MAXFLASH_MODE_FLASH) {
if (curr1 > f_levels1)
@@ -620,6 +616,25 @@ set_leds_end:
return err;
}
+static int max77387_edp_set_leds(struct max77387_info *info,
+ u8 mask, u8 curr1, u8 curr2)
+{
+ int err;
+
+ err = max77387_edp_req(info, mask, &curr1, &curr2);
+ if (err)
+ goto edp_set_leds_end;
+
+ err = max77387_set_leds(info, mask, curr1, curr2);
+ if (!err && info->op_mode == MAXFLASH_MODE_NONE)
+ max77387_edp_lowest(info);
+
+edp_set_leds_end:
+ if (err)
+ dev_err(info->dev, "%s ERROR: %d\n", __func__, err);
+ return err;
+}
+
static void max77387_update_config(struct max77387_info *info)
{
struct max77387_settings *pst = &info->settings;
@@ -888,10 +903,10 @@ static int max77387_update_settings(struct max77387_info *info)
err = max77387_reg_raw_wr(info, MAX77387_RW_NTC, regs, 5);
if (info->op_mode == MAXFLASH_MODE_FLASH)
- err |= max77387_set_leds(info, info->config.led_mask,
+ err |= max77387_edp_set_leds(info, info->config.led_mask,
info->regs.led1_fcurr, info->regs.led2_fcurr);
else
- err |= max77387_set_leds(info, info->config.led_mask,
+ err |= max77387_edp_set_leds(info, info->config.led_mask,
info->regs.led1_tcurr, info->regs.led2_tcurr);
info->regs.regs_stale = false;
@@ -1133,6 +1148,7 @@ static void max77387_shutdown(struct i2c_client *client)
dev_info(info->dev, "Shutting down\n");
max77387_enter_offmode(info, true);
+ max77387_edp_lowest(info);
info->regs.regs_stale = true;
}
#endif
@@ -1242,6 +1258,7 @@ static int max77387_power_set(struct max77387_info *info, int pwr)
switch (pwr) {
case NVC_PWR_OFF:
max77387_enter_offmode(info, true);
+ max77387_edp_lowest(info);
if ((info->pdata->cfg & NVC_CFG_OFF2STDBY) ||
(info->pdata->cfg & NVC_CFG_BOOT_INIT))
pwr = NVC_PWR_STDBY;
@@ -1514,7 +1531,7 @@ static int max77387_set_param(struct max77387_info *info, long arg)
info->new_timer = led_levels.timeout;
curr1 = led_levels.levels[0];
curr2 = led_levels.levels[1];
- err = max77387_set_leds(info,
+ err = max77387_edp_set_leds(info,
led_levels.ledmask, curr1, curr2);
break;
case NVC_PARAM_TORCH_LEVEL:
@@ -1522,7 +1539,7 @@ static int max77387_set_param(struct max77387_info *info, long arg)
info->new_timer = led_levels.timeout;
curr1 = led_levels.levels[0];
curr2 = led_levels.levels[1];
- err = max77387_set_leds(info,
+ err = max77387_edp_set_leds(info,
led_levels.ledmask, curr1, curr2);
break;
case NVC_PARAM_FLASH_PIN_STATE:
@@ -1883,7 +1900,7 @@ set_attr:
break;
/* change led 1/2 current settings */
case 'c':
- max77387_set_leds(info, info->config.led_mask,
+ max77387_edp_set_leds(info, info->config.led_mask,
val & 0xff, (val >> 8) & 0xff);
break;
/* modify flash timeout reg */
diff --git a/drivers/media/video/tegra/max77665-flash.c b/drivers/media/video/tegra/max77665-flash.c
index 2feee300eb42..2d41f2ab787f 100644
--- a/drivers/media/video/tegra/max77665-flash.c
+++ b/drivers/media/video/tegra/max77665-flash.c
@@ -506,15 +506,10 @@ static int max77665_f_set_leds(struct max77665_f_info *info,
info, MAX77665_F_RW_FLED_ENABLE, 0, true);
if (!err) {
info->regs.leds_en = 0;
- max77665_f_edp_lowest(info);
}
goto set_leds_end;
}
- err = max77665_f_edp_req(info, mask, &curr1, &curr2);
- if (err)
- goto set_leds_end;
-
if (mask & 1) {
if (info->op_mode == MAXFLASH_MODE_FLASH) {
if (curr1 > f_levels1)
@@ -590,6 +585,26 @@ set_leds_end:
return err;
}
+static int max77665_f_edp_set_leds(struct max77665_f_info *info,
+ u8 mask, u8 curr1, u8 curr2)
+{
+ int err;
+
+ err = max77665_f_edp_req(info, mask, &curr1, &curr2);
+ if (err)
+ goto edp_set_leds_end;
+
+ err = max77665_f_set_leds(info, mask, curr1, curr2);
+ if (!err && info->op_mode == MAXFLASH_MODE_NONE)
+ max77665_f_edp_lowest(info);
+
+
+edp_set_leds_end:
+ if (err)
+ dev_err(info->dev, "%s ERROR: %d\n", __func__, err);
+ return err;
+}
+
static inline int max77665_f_get_boost_volt(u16 mV)
{
if (mV <= BOOST_VOLT_FLOOR)
@@ -795,7 +810,7 @@ static int max77665_f_update_settings(struct max77665_f_info *info)
err |= max77665_f_reg_wr(info, MAX77665_F_RW_MAXFLASH_TIMER,
info->regs.m_timing, false);
- err |= max77665_f_set_leds(info, info->config.led_mask,
+ err |= max77665_f_edp_set_leds(info, info->config.led_mask,
info->regs.led1_curr, info->regs.led2_curr);
info->regs.regs_stale = false;
@@ -988,6 +1003,7 @@ static void max77665_f_shutdown(struct platform_device *pdev)
dev_info(&pdev->dev, "Shutting down\n");
max77665_f_enter_offmode(info, true);
+ max77665_f_edp_lowest(info);
info->regs.regs_stale = true;
}
#endif
@@ -1105,6 +1121,7 @@ static int max77665_f_power_set(struct max77665_f_info *info, int pwr)
switch (pwr) {
case NVC_PWR_OFF:
max77665_f_enter_offmode(info, true);
+ max77665_f_edp_lowest(info);
if ((info->pdata->cfg & NVC_CFG_OFF2STDBY) ||
(info->pdata->cfg & NVC_CFG_BOOT_INIT))
pwr = NVC_PWR_STDBY;
@@ -1347,7 +1364,7 @@ static int max77665_f_set_param(struct max77665_f_info *info, long arg)
info->new_ftimer = led_levels.timeout & 0X0F;
curr1 = led_levels.levels[0];
curr2 = led_levels.levels[1];
- err = max77665_f_set_leds(info,
+ err = max77665_f_edp_set_leds(info,
led_levels.ledmask, curr1, curr2);
return err;
case NVC_PARAM_TORCH_LEVEL:
@@ -1355,7 +1372,7 @@ static int max77665_f_set_param(struct max77665_f_info *info, long arg)
info->new_ftimer = led_levels.timeout & 0X0F;
curr1 = led_levels.levels[0];
curr2 = led_levels.levels[1];
- err = max77665_f_set_leds(info,
+ err = max77665_f_edp_set_leds(info,
led_levels.ledmask, curr1, curr2);
return err;
case NVC_PARAM_FLASH_PIN_STATE:
@@ -1683,7 +1700,7 @@ set_attr:
dev_info(info->dev, "new data = %x\n", val);
switch (buf[0]) {
case 'c': /* change led 1/2 current settings */
- max77665_f_set_leds(info, info->config.led_mask,
+ max77665_f_edp_set_leds(info, info->config.led_mask,
val & 0xff, (val >> 8) & 0xff);
break;
case 'l': /* enable/disable led 1/2 */
@@ -1696,7 +1713,7 @@ set_attr:
break;
case 'f': /* modify flash timeout reg */
info->new_ftimer = val & 0X0F;
- max77665_f_set_leds(info, info->config.led_mask,
+ max77665_f_edp_set_leds(info, info->config.led_mask,
info->regs.led1_curr, info->regs.led2_curr);
break;
case 'p':