Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f2ce8ab authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mhi_dev: Update release function in MHI"

parents 1cc55a86 6772e50d
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -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);
+10 −21
Original line number Diff line number Diff line
@@ -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);

+60 −38
Original line number Diff line number Diff line
@@ -389,6 +389,43 @@ static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait);
static unsigned int mhi_uci_ctrl_poll(struct file *file, poll_table *wait);
static struct mhi_uci_ctxt_t uci_ctxt;

static bool mhi_uci_are_channels_connected(struct uci_client *uci_client)
{
	uint32_t info_ch_in, info_ch_out;
	int rc;

	/*
	 * Check channel states and return true only if channel
	 * information is available and in connected state.
	 * For all other failure conditions return false.
	 */
	rc = mhi_ctrl_state_info(uci_client->in_chan, &info_ch_in);
	if (rc) {
		uci_log(UCI_DBG_DBG,
			"Channels %d is not available with %d\n",
			uci_client->out_chan, rc);
		return false;
	}

	rc = mhi_ctrl_state_info(uci_client->out_chan, &info_ch_out);
	if (rc) {
		uci_log(UCI_DBG_DBG,
			"Channels %d is not available with %d\n",
			uci_client->out_chan, rc);
		return false;
	}

	if ((info_ch_in != MHI_STATE_CONNECTED) ||
		(info_ch_out != MHI_STATE_CONNECTED)) {
		uci_log(UCI_DBG_DBG,
			"Channels %d or %d are not connected\n",
			uci_client->in_chan, uci_client->out_chan);
		return false;
	}

	return true;
}

static int mhi_init_read_chan(struct uci_client *client_handle,
		enum mhi_client_channel chan)
{
@@ -640,6 +677,15 @@ static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait)

	poll_wait(file, &uci_handle->read_wq, wait);
	poll_wait(file, &uci_handle->write_wq, wait);
	/*
	 * Check if the channels on which the clients are trying
	 * to poll are in connected state and return with the
	 * appropriate mask if channels are disconnected.
	 */
	if (!mhi_uci_are_channels_connected(uci_handle)) {
		mask = POLLHUP;
		return mask;
	}
	mask = uci_handle->at_ctrl_mask;
	if (!atomic_read(&uci_ctxt.mhi_disabled) &&
		!mhi_dev_channel_isempty(uci_handle->in_handle)) {
@@ -782,31 +828,9 @@ static int mhi_uci_read_sync(struct uci_client *uci_handle,
static int open_client_mhi_channels(struct uci_client *uci_client)
{
	int rc = 0;
	uint32_t info_ch_in, info_ch_out;

	rc = mhi_ctrl_state_info(uci_client->in_chan, &info_ch_in);
	if (rc) {
		uci_log(UCI_DBG_DBG,
			"Channels %d is not connected with %d\n",
			uci_client->out_chan, rc);
		return -EINVAL;
	}

	rc = mhi_ctrl_state_info(uci_client->out_chan, &info_ch_out);
	if (rc) {
		uci_log(UCI_DBG_DBG,
			"Channels %d is not connected with %d\n",
			uci_client->out_chan, rc);
		return -EINVAL;
	}

	if ((info_ch_in != MHI_STATE_CONNECTED) ||
		(info_ch_out != MHI_STATE_CONNECTED)) {
		uci_log(UCI_DBG_DBG,
			"Channels %d or %d are not connected\n",
			uci_client->in_chan, uci_client->out_chan);
		return -EINVAL;
	}
	if (!mhi_uci_are_channels_connected(uci_client))
		return -ENODEV;

	uci_log(UCI_DBG_DBG,
			"Starting channels %d %d.\n",
@@ -936,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;
@@ -951,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);

@@ -970,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)
@@ -1335,6 +1358,13 @@ void mhi_uci_chan_state_notify(struct mhi_dev *mhi,
		uci_log(UCI_DBG_ERROR,
				"Sending uevent failed for chan %d\n", ch_id);

	if (ch_state == MHI_STATE_DISCONNECTED &&
			!atomic_read(&uci_handle->ref_count)) {
		/* Issue wake only if there is an active client */
		wake_up(&uci_handle->read_wq);
		wake_up(&uci_handle->write_wq);
	}

	kfree(buf[0]);
}
EXPORT_SYMBOL(mhi_uci_chan_state_notify);
@@ -1765,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);
	}
}

+1 −1
Original line number Diff line number Diff line
@@ -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
+2 −8
Original line number Diff line number Diff line
@@ -159,15 +159,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)