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

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

Merge "spcom: ignore CONNECTED notification while closing the channel"

parents b29acd8d 09174e50
Loading
Loading
Loading
Loading
+50 −31
Original line number Diff line number Diff line
@@ -93,8 +93,6 @@
/* SPCOM driver name */
#define DEVICE_NAME	"spcom"

#define SPCOM_MAX_CHANNELS	0x20

/* maximum ION buffers should be >= SPCOM_MAX_CHANNELS  */
#define SPCOM_MAX_ION_BUF_PER_CH (SPCOM_MAX_CHANNELS + 4)

@@ -195,6 +193,7 @@ struct spcom_channel {
	 * glink state: CONNECTED / LOCAL_DISCONNECTED, REMOTE_DISCONNECTED
	 */
	unsigned int glink_state;
	bool is_closing;

	/* Events notification */
	struct completion connect;
@@ -244,7 +243,7 @@ struct spcom_device {
	int channel_count;

	/* private */
	struct mutex lock;
	struct mutex cmd_lock;

	/* Link state */
	struct completion link_state_changed;
@@ -483,7 +482,17 @@ static void spcom_notify_state(void *handle, const void *priv,
	switch (event) {
	case GLINK_CONNECTED:
		pr_debug("GLINK_CONNECTED, ch name [%s].\n", ch->name);
		mutex_lock(&ch->lock);

		if (ch->is_closing) {
			pr_err("Unexpected CONNECTED while closing [%s].\n",
				ch->name);
			mutex_unlock(&ch->lock);
			return;
		}

		ch->glink_state = event;

		/*
		 * if spcom_notify_state() is called within glink_open()
		 * then ch->glink_handle is not updated yet.
@@ -493,17 +502,28 @@ static void spcom_notify_state(void *handle, const void *priv,
			ch->glink_handle = handle;
		}

		/* prepare default rx buffer after connected */
		/* signal before unlock mutex & before calling glink */
		complete_all(&ch->connect);

		/*
		 * Prepare default rx buffer.
		 * glink_queue_rx_intent() can be called only AFTER connected.
		 * We do it here, ASAP, to allow rx data.
		 */

		pr_debug("call glink_queue_rx_intent() ch [%s].\n", ch->name);
		ret = glink_queue_rx_intent(ch->glink_handle,
					    ch, ch->rx_buf_size);
		if (ret) {
			pr_err("glink_queue_rx_intent() err [%d]\n", ret);
		} else {
			pr_debug("rx buf is ready, size [%zu].\n",
			pr_debug("rx buf is ready, size [%zu]\n",
				 ch->rx_buf_size);
			ch->rx_buf_ready = true;
		}
		complete_all(&ch->connect);

		pr_debug("GLINK_CONNECTED, ch name [%s] done.\n", ch->name);
		mutex_unlock(&ch->lock);
		break;
	case GLINK_LOCAL_DISCONNECTED:
		/*
@@ -556,9 +576,7 @@ static void spcom_notify_state(void *handle, const void *priv,
static bool spcom_notify_rx_intent_req(void *handle, const void *priv,
				       size_t req_size)
{
	struct spcom_channel *ch = (struct spcom_channel *) priv;

	pr_err("Unexpected intent request for ch [%s].\n", ch->name);
	pr_err("Unexpected intent request\n");

	return false;
}
@@ -670,6 +688,13 @@ static int spcom_init_channel(struct spcom_channel *ch, const char *name)
	ch->glink_state = GLINK_LOCAL_DISCONNECTED;
	ch->actual_rx_size = 0;
	ch->rx_buf_size = SPCOM_RX_BUF_SIZE;
	ch->is_closing = false;
	ch->glink_handle = NULL;
	ch->ref_count = 0;
	ch->rx_abort = false;
	ch->tx_abort = false;
	ch->txn_id = INITIAL_TXN_ID; /* use non-zero nonce for debug */
	ch->pid = 0;

	return 0;
}
@@ -739,6 +764,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec)
	/* init completion before calling glink_open() */
	reinit_completion(&ch->connect);

	ch->is_closing = false;

	handle = glink_open(&cfg);
	if (IS_ERR_OR_NULL(handle)) {
		pr_err("glink_open failed.\n");
@@ -753,6 +780,8 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec)
	ch->pid = current_pid();
	ch->txn_id = INITIAL_TXN_ID;

	mutex_unlock(&ch->lock);

	pr_debug("Wait for connection on channel [%s] timeout_msec [%d].\n",
		 name, timeout_msec);

@@ -769,8 +798,6 @@ static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec)
		pr_debug("Channel [%s] opened, no timeout.\n", name);
	}

	mutex_unlock(&ch->lock);

	return 0;
exit_err:
	mutex_unlock(&ch->lock);
@@ -797,6 +824,8 @@ static int spcom_close(struct spcom_channel *ch)
		return 0;
	}

	ch->is_closing = true;

	ret = glink_close(ch->glink_handle);
	if (ret)
		pr_err("glink_close() fail, ret [%d].\n", ret);
@@ -812,6 +841,7 @@ static int spcom_close(struct spcom_channel *ch)
	ch->pid = 0;

	pr_debug("Channel closed [%s].\n", ch->name);

	mutex_unlock(&ch->lock);

	return 0;
@@ -1923,18 +1953,6 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
	return ret;
}

/**
 * spcom_handle_fake_ssr_command() - Handle fake ssr command from user space.
 */
static int spcom_handle_fake_ssr_command(struct spcom_channel *ch, int arg)
{
	pr_debug("Start Fake glink SSR subsystem [%s].\n", spcom_edge);
	glink_ssr(spcom_edge);
	pr_debug("Fake glink SSR subsystem [%s] done.\n", spcom_edge);

	return 0;
}

/**
 * spcom_handle_write() - Handle user space write commands.
 *
@@ -1964,6 +1982,8 @@ static int spcom_handle_write(struct spcom_channel *ch,
	swap_id = htonl(cmd->cmd_id);
	memcpy(cmd_name, &swap_id, sizeof(int));

	mutex_lock(&spcom_dev->cmd_lock);

	pr_debug("cmd_id [0x%x] cmd_name [%s].\n", cmd_id, cmd_name);

	switch (cmd_id) {
@@ -1979,17 +1999,16 @@ static int spcom_handle_write(struct spcom_channel *ch,
	case SPCOM_CMD_UNLOCK_ION_BUF:
		ret = spcom_handle_unlock_ion_buf_command(ch, buf, buf_size);
		break;
	case SPCOM_CMD_FSSR:
		ret = spcom_handle_fake_ssr_command(ch, cmd->arg);
		break;
	case SPCOM_CMD_CREATE_CHANNEL:
		ret = spcom_handle_create_channel_command(buf, buf_size);
		break;
	default:
		pr_err("Invalid Command Id [0x%x].\n", (int) cmd->cmd_id);
		return -EINVAL;
		ret = -EINVAL;
	}

	mutex_unlock(&spcom_dev->cmd_lock);

	return ret;
}

@@ -2690,7 +2709,7 @@ static int spcom_probe(struct platform_device *pdev)
		return -ENOMEM;

	spcom_dev = dev;
	mutex_init(&dev->lock);
	mutex_init(&spcom_dev->cmd_lock);
	init_completion(&dev->link_state_changed);
	spcom_dev->link_state = GLINK_LINK_STATE_DOWN;

@@ -2763,7 +2782,7 @@ static int __init spcom_init(void)
{
	int ret;

	pr_info("spcom driver Ver 1.0 23-Nov-2015.\n");
	pr_info("spcom driver version 1.1 17-July-2017.\n");

	ret = platform_driver_register(&spcom_driver);
	if (ret)
+6 −0
Original line number Diff line number Diff line
@@ -30,6 +30,12 @@
 * with special size SPCOM_GET_NEXT_REQUEST_SIZE.
 */

/*
 * Maximum number of channel between Secure Processor and HLOS.
 * including predefined channels, like "sp_kernel".
 */
#define SPCOM_MAX_CHANNELS	0x20

/* Maximum size (including null) for channel names */
#define SPCOM_CHANNEL_NAME_SIZE		32