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

Commit 90f8f682 authored by Chris Lew's avatar Chris Lew Committed by Elliot Berman
Browse files

neuron: ch_haven: Move msgq init to sync thread



The neuron channels may init and probe before the secondary vm is
loaded and the resources queried from resource manager. This results
in either a blocking call or EAGAIN returned when sending a doorbell.

Move the msgq_init call from the probe to the channel sync thread. This
will ensure the init thread can continue if the doorbell send api needs
to block or busywait loop.

Change-Id: I0f5562968d59a3dc0a361aca9e4e60ffebcb70be
Signed-off-by: default avatarChris Lew <clew@codeaurora.org>
parent d5e23615
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -251,6 +251,11 @@ static int channel_sync_thread(void *data)
	struct neuron_shmem_channel_header *hdr;
	struct neuron_mq_data_priv *priv = (struct neuron_mq_data_priv *)data;

	/* Init the shared memory header and local message queue. */
	if (msgq_init(priv)) {
		pr_err("%s: msgq_init failed\n", __func__);
		return 0;
	}
	hdr = (struct neuron_shmem_channel_header *)priv->base;

	/* Waiting for head being updated by the sender. */
@@ -380,12 +385,7 @@ static int channel_hh_probe(struct neuron_channel *cdev)
		goto fail_rx_dbl;
	}

	/* Init the shared memory header and local message queue. */
	ret = msgq_init(priv);
	if (ret)
		goto fail_mask;
	init_waitqueue_head(&priv->wait_q);

	/* Start the thread for syncing with the sender. */
	priv->sync_thread = kthread_run(channel_sync_thread, priv,
					"recv_sync_thread");
@@ -394,8 +394,6 @@ static int channel_hh_probe(struct neuron_channel *cdev)

	return 0;

fail_mask:
	hh_dbl_rx_unregister(priv->rx_dbl);
fail_rx_dbl:
	hh_dbl_tx_unregister(priv->tx_dbl);
fail_tx_dbl:
+14 −14
Original line number Diff line number Diff line
@@ -217,6 +217,19 @@ static int read_config(struct neuron_mq_data_priv *priv)
	return 0;
}

static void msgq_init(struct neuron_mq_data_priv *priv)
{
	struct neuron_shmem_channel_header *hdr = priv->base;
	struct neuron_msg_queue *msgq = &priv->msgq;

	msgq->headp = &hdr->head;
	msgq->space_for_next_p = &hdr->space_for_next;
	msgq->offset = (u32)-1;

	/* Set it to -1 as UNINITIALIZED */
	smp_store_release(msgq->headp, (u32)-1);
}

/* Thread to sync with the receiver. Note: this thread might never finishes if
 * it fails to sync with the peer.
 */
@@ -225,6 +238,7 @@ static int channel_sync_thread(void *data)
	struct neuron_mq_data_priv *priv = (struct neuron_mq_data_priv *)data;
	struct neuron_shmem_channel_header *hdr;

	msgq_init(priv);
	hdr = (struct neuron_shmem_channel_header *)priv->base;
	hdr->version = CHANNEL_VERSION;
	hdr->tail_offset = -1;
@@ -265,19 +279,6 @@ static int channel_sync_thread(void *data)
	return 0;
}

static void msgq_init(struct neuron_mq_data_priv *priv)
{
	struct neuron_shmem_channel_header *hdr = priv->base;
	struct neuron_msg_queue *msgq = &priv->msgq;

	msgq->headp = &hdr->head;
	msgq->space_for_next_p = &hdr->space_for_next;
	msgq->offset = (u32)-1;

	/* Set it to -1 as UNINITIALIZED */
	smp_store_release(msgq->headp, (u32)-1);
}

static int channel_hh_map_memory(struct neuron_mq_data_priv *priv,
				 struct device *dev)
{
@@ -367,7 +368,6 @@ static int channel_hh_probe(struct neuron_channel *cdev)
		goto fail_rx_dbl;
	}

	msgq_init(priv);
	init_waitqueue_head(&priv->wait_q);
	/* Start the thread for syncing with the receiver. */
	priv->sync_thread = kthread_run(channel_sync_thread, priv,