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

Commit f4f242f5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mhi_dev: Handle multiple RS232 control signals"

parents 7476324c 7f4000f1
Loading
Loading
Loading
Loading
+77 −35
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@

#define MHI_UCI_ASYNC_READ_TIMEOUT	msecs_to_jiffies(100)
#define MHI_UCI_ASYNC_WRITE_TIMEOUT	msecs_to_jiffies(100)
#define MHI_UCI_AT_CTRL_READ_TIMEOUT	msecs_to_jiffies(1000)

enum uci_dbg_level {
	UCI_DBG_VERBOSE = 0x0,
@@ -306,6 +307,7 @@ struct uci_client {
	struct mhi_req *wreqs;
	struct list_head wr_req_list;
	struct completion read_done;
	struct completion at_ctrl_read_done;
	struct completion *write_done;
	int (*send)(struct uci_client*, void*, u32);
	int (*read)(struct uci_client*, struct mhi_req*, int*);
@@ -1270,6 +1272,8 @@ static int mhi_register_client(struct uci_client *mhi_client, int index)
	mutex_init(&mhi_client->in_chan_lock);
	mutex_init(&mhi_client->out_chan_lock);
	spin_lock_init(&mhi_client->wr_req_lock);
	/* Init the completion event for AT ctrl read */
	init_completion(&mhi_client->at_ctrl_read_done);

	uci_log(UCI_DBG_DBG, "Registering chan %d.\n", mhi_client->out_chan);
	return 0;
@@ -1285,9 +1289,18 @@ static int mhi_uci_ctrl_set_tiocm(struct uci_client *client,
	struct uci_client *ctrl_client =
		&uci_ctxt.client_handles[CHAN_TO_CLIENT
					(MHI_CLIENT_IP_CTRL_1_OUT)];
	unsigned int info = 0;

	uci_log(UCI_DBG_VERBOSE, "Rcvd ser_state = 0x%x\n", ser_state);

	/* Check if the IP_CTRL channels were started by host */
	mhi_ctrl_state_info(MHI_CLIENT_IP_CTRL_1_IN, &info);
	if (info != MHI_STATE_CONNECTED) {
		uci_log(UCI_DBG_VERBOSE,
			"IP_CTRL channels not started by host yet\n");
		return -EAGAIN;
	}

	cur_ser_state = client->tiocm & ~(TIOCM_DTR | TIOCM_RTS);
	ser_state &= (TIOCM_CD | TIOCM_DSR | TIOCM_RI);

@@ -1345,6 +1358,9 @@ static void mhi_uci_at_ctrl_read(struct work_struct *work)
	struct uci_client *tgt_client;
	struct mhi_uci_ctrl_msg *ctrl_msg;
	unsigned int chan;
	unsigned long compl_ret;

	while (!mhi_dev_channel_isempty(ctrl_client->in_handle)) {

		ctrl_client->pkt_loc = NULL;
		ctrl_client->pkt_size = 0;
@@ -1352,26 +1368,34 @@ static void mhi_uci_at_ctrl_read(struct work_struct *work)
		ret_val = __mhi_uci_client_read(ctrl_client, &msg_size);
		if (ret_val) {
			uci_log(UCI_DBG_ERROR,
			"Ctrl msg read failed, ret_val is %d!\n",
				"Ctrl msg read failed, ret_val is %d\n",
				ret_val);
			return;
		}
		if (msg_size != sizeof(*ctrl_msg)) {
		uci_log(UCI_DBG_ERROR, "Invalid ctrl msg size!\n");
			uci_log(UCI_DBG_ERROR, "Invalid ctrl msg size\n");
			return;
		}
		if (!ctrl_client->pkt_loc) {
		uci_log(UCI_DBG_ERROR, "ctrl msg pkt_loc null!\n");
			uci_log(UCI_DBG_ERROR, "ctrl msg pkt_loc null\n");
			return;
		}
		ctrl_msg = ctrl_client->pkt_loc;

		chan = ctrl_msg->dest_id;

		if (chan >= MHI_MAX_SOFTWARE_CHANNELS) {
			uci_log(UCI_DBG_ERROR,
			"Invalid channel number in ctrl msg!\n");
				"Invalid channel number in ctrl msg\n");
			return;
		}

		uci_log(UCI_DBG_VERBOSE, "preamble: 0x%x\n",
				ctrl_msg->preamble);
		uci_log(UCI_DBG_VERBOSE, "msg_id: 0x%x\n", ctrl_msg->msg_id);
		uci_log(UCI_DBG_VERBOSE, "dest_id: 0x%x\n", ctrl_msg->dest_id);
		uci_log(UCI_DBG_VERBOSE, "size: 0x%x\n", ctrl_msg->size);
		uci_log(UCI_DBG_VERBOSE, "msg: 0x%x\n", ctrl_msg->msg);

		tgt_client = &uci_ctxt.client_handles[CHAN_TO_CLIENT(chan)];
		tgt_client->tiocm &= (TIOCM_CD | TIOCM_DSR | TIOCM_RI);

@@ -1384,8 +1408,24 @@ static void mhi_uci_at_ctrl_read(struct work_struct *work)

		uci_log(UCI_DBG_VERBOSE, "Rcvd tiocm %d\n", tgt_client->tiocm);

		/* Wait till client reads the new state */
		reinit_completion(&tgt_client->at_ctrl_read_done);

		tgt_client->at_ctrl_mask = POLLPRI;
		wake_up(&tgt_client->read_wq);

		uci_log(UCI_DBG_VERBOSE, "Waiting for at_ctrl_read_done");
		compl_ret = wait_for_completion_interruptible_timeout(
					&tgt_client->at_ctrl_read_done,
					MHI_UCI_AT_CTRL_READ_TIMEOUT);
		if (compl_ret == -ERESTARTSYS) {
			uci_log(UCI_DBG_ERROR, "Exit signal caught\n");
			return;
		} else if (compl_ret == 0) {
			uci_log(UCI_DBG_ERROR,
			"Timed out waiting for client to read ctrl state\n");
		}
	}
}

static long mhi_uci_client_ioctl(struct file *file, unsigned int cmd,
@@ -1436,6 +1476,8 @@ static long mhi_uci_client_ioctl(struct file *file, unsigned int cmd,
			rc = -EFAULT;
		}
		uci_handle->at_ctrl_mask = 0;
		uci_log(UCI_DBG_VERBOSE, "Completing at_ctrl_read_done");
		complete(&uci_handle->at_ctrl_read_done);
	} else if (cmd == MHI_UCI_TIOCM_SET) {
		rc = get_user(tiocm, (unsigned int __user *)arg);
		if (rc)