forked from rubenslte/android_kernel_samsung_msm8226
msm: mhl: sii8334: Add mutex lock to avoid race condition
Add mutex lock betweeen mhl_sii_config and mhl_sii_device_discovery functions to avoid accesing the variable flag before it is updated. This will avoid accessing the mhl init settings i2c register before turning on the mhl regulator's and gpio's. Change-Id: If3f7fbe3d6ab84f101c407c43ac8b410e6df38fe Signed-off-by: Raghavendra Ambadas <rambad@codeaurora.org>
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user