mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 02:01:36 +03:00
tegra: platform: dce: Fix race condition on fgpa
Resolve race condition where DCE Firmware could potentially send an IVC signal before even CPU driver starts listening for it. This fix makes sure that the driver need not wait if it has been signalled already by Firmware. Jira TDS-6381 Change-Id: I3d6dd1f93ce36f9e44b7157f70c0aad099f2d561 Signed-off-by: Arun Swain <arswain@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-t23x/+/2394468 Tested-by: Santosh Galma <galmar@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Santosh Galma <galmar@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mahesh Kumar <mahkumar@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Laxman Dewangan
parent
ef3f18c398
commit
ea84c95dbf
@@ -174,7 +174,7 @@ static void dce_ipc_signal_target(struct ivc *ivc)
|
||||
ch->signal.notify(ch->d, &ch->signal.to_d);
|
||||
}
|
||||
|
||||
static int dce_ipc_wait(struct tegra_dce *d, u32 w_type, u32 ch_type)
|
||||
static int _dce_ipc_wait(struct tegra_dce *d, u32 w_type, u32 ch_type)
|
||||
{
|
||||
int ret = 0;
|
||||
struct dce_ipc_channel *ch;
|
||||
@@ -191,8 +191,6 @@ static int dce_ipc_wait(struct tegra_dce *d, u32 w_type, u32 ch_type)
|
||||
goto out;
|
||||
}
|
||||
|
||||
dce_mutex_lock(&ch->lock);
|
||||
|
||||
ch->w_type = w_type;
|
||||
|
||||
dce_mutex_unlock(&ch->lock);
|
||||
@@ -207,7 +205,6 @@ static int dce_ipc_wait(struct tegra_dce *d, u32 w_type, u32 ch_type)
|
||||
ch->w_type = DCE_IPC_WAIT_TYPE_INVALID;
|
||||
|
||||
out:
|
||||
dce_mutex_unlock(&ch->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -429,11 +426,7 @@ void dce_ipc_channel_reset(struct tegra_dce *d, u32 ch_type)
|
||||
|
||||
ch->flags &= ~DCE_IPC_CHANNEL_SYNCED;
|
||||
|
||||
dce_mutex_unlock(&ch->lock);
|
||||
|
||||
dce_ipc_wait(ch->d, DCE_IPC_WAIT_TYPE_SYNC, ch_type);
|
||||
|
||||
dce_mutex_lock(&ch->lock);
|
||||
_dce_ipc_wait(ch->d, DCE_IPC_WAIT_TYPE_SYNC, ch_type);
|
||||
|
||||
ch->flags |= DCE_IPC_CHANNEL_SYNCED;
|
||||
|
||||
@@ -651,7 +644,9 @@ int dce_ipc_send_message_sync(struct tegra_dce *d, u32 ch_type,
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = dce_ipc_wait(ch->d, DCE_IPC_WAIT_TYPE_RPC, ch_type);
|
||||
dce_mutex_lock(&ch->lock);
|
||||
ret = _dce_ipc_wait(ch->d, DCE_IPC_WAIT_TYPE_RPC, ch_type);
|
||||
dce_mutex_unlock(&ch->lock);
|
||||
if (ret) {
|
||||
dce_err(ch->d, "Error in waiting for ack");
|
||||
goto done;
|
||||
|
||||
@@ -53,8 +53,12 @@ void dce_worker_thread_wait(struct tegra_dce *d,
|
||||
enum dce_worker_state new_state;
|
||||
struct dce_worker_info *w = &d->wrk_info;
|
||||
|
||||
dce_mutex_lock(&w->lock);
|
||||
|
||||
if (w->state_changed == true) {
|
||||
w->state_changed = false;
|
||||
dce_warn(d, "Unexpected state_changed value");
|
||||
dce_mutex_unlock(&w->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -81,13 +85,14 @@ void dce_worker_thread_wait(struct tegra_dce *d,
|
||||
return;
|
||||
}
|
||||
|
||||
dce_mutex_lock(&w->lock);
|
||||
w->c_state = new_state;
|
||||
dce_mutex_unlock(&w->lock);
|
||||
|
||||
if (new_state == STATE_DCE_WORKER_BOOT_WAIT)
|
||||
timeout_val_ms = 1000;
|
||||
|
||||
dce_mutex_unlock(&w->lock);
|
||||
|
||||
ret = DCE_COND_WAIT_INTERRUPTIBLE(&w->cond,
|
||||
dce_worker_wakeup_cond(d),
|
||||
timeout_val_ms);
|
||||
@@ -119,18 +124,16 @@ void dce_worker_thread_wakeup(struct tegra_dce *d,
|
||||
struct dce_worker_info *w = &d->wrk_info;
|
||||
enum dce_worker_state new_state = w->c_state;
|
||||
|
||||
if (w->state_changed == true) {
|
||||
dce_mutex_lock(&w->lock);
|
||||
|
||||
if (w->state_changed == true)
|
||||
dce_warn(d, "Unexpected state_changed value");
|
||||
dce_mutex_unlock(&w->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case EVENT_ID_DCE_IPC_SIGNAL_RECEIVED:
|
||||
if (w->c_state != STATE_DCE_WORKER_WFI) {
|
||||
dce_warn(d, "Unexpected wakeup event rcvd: [%d]. Cur State: [%d]",
|
||||
event, w->c_state);
|
||||
return;
|
||||
}
|
||||
new_state = STATE_DCE_WORKER_IDLE;
|
||||
break;
|
||||
@@ -160,7 +163,6 @@ void dce_worker_thread_wakeup(struct tegra_dce *d,
|
||||
return;
|
||||
}
|
||||
|
||||
dce_mutex_lock(&w->lock);
|
||||
w->c_state = new_state;
|
||||
w->state_changed = true;
|
||||
dce_mutex_unlock(&w->lock);
|
||||
|
||||
Reference in New Issue
Block a user