diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c index 084769f792c..9f50f89d25d 100644 --- a/drivers/video/msm/mdss/mhl_sii8334.c +++ b/drivers/video/msm/mdss/mhl_sii8334.c @@ -398,19 +398,22 @@ static int mhl_sii_config(struct mhl_tx_ctrl *mhl_ctrl, bool on) client = mhl_ctrl->i2c_handle; + mutex_lock(&mhl_ctrl->sii_config_lock); if (on && !mhl_ctrl->irq_req_done) { rc = mhl_vreg_config(mhl_ctrl, 1); if (rc) { pr_err("%s: vreg init failed [%d]\n", __func__, rc); - return -ENODEV; + rc = -ENODEV; + goto vreg_config_error; } rc = mhl_gpio_config(mhl_ctrl, 1); if (rc) { pr_err("%s: gpio init failed [%d]\n", __func__, rc); - return -ENODEV; + rc = -ENODEV; + goto vreg_config_error; } rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL, @@ -419,9 +422,12 @@ static int mhl_sii_config(struct mhl_tx_ctrl *mhl_ctrl, bool on) if (rc) { pr_err("%s: request_threaded_irq failed, status: %d\n", __func__, rc); - return -ENODEV; + rc = -ENODEV; + goto vreg_config_error; } else { mhl_ctrl->irq_req_done = true; + /* wait for i2c interrupt line to be activated */ + msleep(100); } } else if (!on && mhl_ctrl->irq_req_done) { free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl); @@ -430,6 +436,8 @@ static int mhl_sii_config(struct mhl_tx_ctrl *mhl_ctrl, bool on) mhl_ctrl->irq_req_done = false; } +vreg_config_error: + mutex_unlock(&mhl_ctrl->sii_config_lock); return rc; } @@ -471,15 +479,10 @@ static int mhl_sii_device_discovery(void *data, int id, flush_work(&mhl_ctrl->mhl_intr_work); - if (!mhl_ctrl->irq_req_done) { - rc = mhl_sii_config(mhl_ctrl, true); - if (rc) { - pr_err("%s: Failed to config vreg/gpio\n", __func__); - return rc; - } - - /* wait for i2c interrupt line to be activated */ - msleep(100); + rc = mhl_sii_config(mhl_ctrl, true); + if (rc) { + pr_err("%s: Failed to config vreg/gpio\n", __func__); + return rc; } if (!mhl_ctrl->disc_enabled) { @@ -1865,6 +1868,7 @@ static int mhl_i2c_probe(struct i2c_client *client, init_completion(&mhl_ctrl->rgnd_done); + mutex_init(&mhl_ctrl->sii_config_lock); mhl_ctrl->mhl_psy.name = "ext-vbus"; diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h index 42ee81e71b4..69cf36dc773 100644 --- a/include/linux/mhl_8334.h +++ b/include/linux/mhl_8334.h @@ -164,6 +164,11 @@ struct mhl_tx_ctrl { int wr_burst_pending; struct completion req_write_done; spinlock_t lock; + /* + * Lock between mhl_sii_config and + * mhl_sii_device_discovery functions + */ + struct mutex sii_config_lock; bool tx_powered_off; uint8_t dwnstream_hpd; bool mhl_det_discon;