msm: mhi_dev: Update release function in MHI

After MHI device receives a reset command the internal
state machine suspends all activity on the channel and
processes the device reset. Clients are notified on
the channel close. Existing close function checks if
there are pending data to be read but since the device
is in the process of cleaning the transfer buffers
and the channels are suspended this check is not required.

Change-Id: Iafc5249762b1468ee2cca4ac141522ce0356d403
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
tirimbino
Siddartha Mohanadoss 5 years ago
parent d34ac24764
commit 6772e50d7b
  1. 5
      drivers/char/diag/diag_pcie.c
  2. 31
      drivers/platform/msm/mhi_dev/mhi.c
  3. 19
      drivers/platform/msm/mhi_dev/mhi_uci.c
  4. 2
      include/linux/msm_mhi_dev.h
  5. 10
      net/qrtr/mhi_dev.c

@ -615,7 +615,6 @@ void diag_pcie_disconnect_device(int id)
void diag_pcie_close_work_fn(struct work_struct *work)
{
int rc = 0;
struct diag_pcie_info *pcie_info = container_of(work,
struct diag_pcie_info,
open_work);
@ -624,10 +623,10 @@ void diag_pcie_close_work_fn(struct work_struct *work)
return;
mutex_lock(&pcie_info->out_chan_lock);
mutex_lock(&pcie_info->in_chan_lock);
rc = mhi_dev_close_channel(pcie_info->in_handle);
mhi_dev_close_channel(pcie_info->in_handle);
DIAG_LOG(DIAG_DEBUG_MUX, " closed in bound channel %d",
pcie_info->in_chan);
rc = mhi_dev_close_channel(pcie_info->out_handle);
mhi_dev_close_channel(pcie_info->out_handle);
DIAG_LOG(DIAG_DEBUG_MUX, " closed out bound channel %d",
pcie_info->out_chan);
mutex_unlock(&pcie_info->in_chan_lock);

@ -2306,35 +2306,24 @@ int mhi_dev_channel_isempty(struct mhi_dev_client *handle)
}
EXPORT_SYMBOL(mhi_dev_channel_isempty);
int mhi_dev_close_channel(struct mhi_dev_client *handle)
void mhi_dev_close_channel(struct mhi_dev_client *handle)
{
struct mhi_dev_channel *ch;
int rc = 0;
if (!handle) {
mhi_log(MHI_MSG_ERROR, "Invalid channel access\n");
return -EINVAL;
mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV);
return;
}
ch = handle->channel;
mutex_lock(&ch->ch_lock);
if (ch->state != MHI_DEV_CH_PENDING_START) {
if (ch->ch_type == MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL &&
!mhi_dev_channel_isempty(handle)) {
mhi_log(MHI_MSG_ERROR,
if (ch->state != MHI_DEV_CH_PENDING_START)
if ((ch->ch_type == MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL &&
!mhi_dev_channel_isempty(handle)) || ch->tre_loc)
mhi_log(MHI_MSG_DBG,
"Trying to close an active channel (%d)\n",
ch->ch_id);
rc = -EAGAIN;
goto exit;
} else if (ch->tre_loc) {
mhi_log(MHI_MSG_ERROR,
"Trying to close channel (%d) when a TRE is active",
ch->ch_id);
rc = -EAGAIN;
goto exit;
}
}
ch->state = MHI_DEV_CH_CLOSED;
ch->active_client = NULL;
@ -2343,9 +2332,9 @@ int mhi_dev_close_channel(struct mhi_dev_client *handle)
ch->ereqs = NULL;
ch->tr_events = NULL;
kfree(handle);
exit:
mutex_unlock(&ch->ch_lock);
return rc;
return;
}
EXPORT_SYMBOL(mhi_dev_close_channel);

@ -960,7 +960,6 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
struct file *file_handle)
{
struct uci_client *uci_handle = file_handle->private_data;
int rc = 0;
if (!uci_handle)
return -EINVAL;
@ -975,12 +974,12 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
if (!(uci_handle->f_flags & O_SYNC))
kfree(uci_handle->wreqs);
mutex_lock(&uci_handle->out_chan_lock);
rc = mhi_dev_close_channel(uci_handle->out_handle);
mhi_dev_close_channel(uci_handle->out_handle);
wake_up(&uci_handle->write_wq);
mutex_unlock(&uci_handle->out_chan_lock);
mutex_lock(&uci_handle->in_chan_lock);
rc = mhi_dev_close_channel(uci_handle->in_handle);
mhi_dev_close_channel(uci_handle->in_handle);
wake_up(&uci_handle->read_wq);
mutex_unlock(&uci_handle->in_chan_lock);
@ -994,7 +993,7 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
iminor(mhi_inode),
atomic_read(&uci_handle->ref_count));
}
return rc;
return 0;
}
static void mhi_parse_state(char *buf, int *nbytes, uint32_t info)
@ -1796,16 +1795,8 @@ static void mhi_uci_at_ctrl_client_cb(struct mhi_dev_client_cb_data *cb_data)
uci_ctxt.at_ctrl_wq = NULL;
if (!(client->f_flags & O_SYNC))
kfree(client->wreqs);
rc = mhi_dev_close_channel(client->out_handle);
if (rc)
uci_log(UCI_DBG_INFO,
"Failed to close channel %d ret %d\n",
client->out_chan, rc);
rc = mhi_dev_close_channel(client->in_handle);
if (rc)
uci_log(UCI_DBG_INFO,
"Failed to close channel %d ret %d\n",
client->in_chan, rc);
mhi_dev_close_channel(client->out_handle);
mhi_dev_close_channel(client->in_handle);
}
}

@ -168,7 +168,7 @@ int mhi_dev_open_channel(uint32_t chan_id,
/**
* mhi_dev_close_channel() - Channel close for a given client.
*/
int mhi_dev_close_channel(struct mhi_dev_client *handle_client);
void mhi_dev_close_channel(struct mhi_dev_client *handle_client);
/**
* mhi_dev_read_channel() - Channel read for a given client

@ -157,15 +157,9 @@ static int qrtr_mhi_dev_open_channels(struct qrtr_mhi_dev_ep *qep)
static void qrtr_mhi_dev_close_channels(struct qrtr_mhi_dev_ep *qep)
{
int rc;
rc = mhi_dev_close_channel(qep->in);
if (rc < 0)
dev_err(qep->dev, "failed to close in channel %d\n", rc);
rc = mhi_dev_close_channel(qep->out);
if (rc < 0)
dev_err(qep->dev, "failed to close out channel %d\n", rc);
mhi_dev_close_channel(qep->in);
mhi_dev_close_channel(qep->out);
}
static void qrtr_mhi_dev_state_cb(struct mhi_dev_client_cb_data *cb_data)

Loading…
Cancel
Save