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

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

Merge "rpmsg: glink: Move intent work to private workqueue"

parents 9b4c0567 4ae7b668
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <linux/mailbox_client.h>
#include <linux/ipc_logging.h>

@@ -114,6 +115,8 @@ struct glink_core_rx_intent {
 * @rx_pipe:	pipe object for receive FIFO
 * @tx_pipe:	pipe object for transmit FIFO
 * @irq:	IRQ for signaling incoming events
 * @kworker:	kworker to handle rx_done work
 * @task:	kthread running @kworker
 * @rx_work:	worker for handling received control messages
 * @rx_lock:	protects the @rx_queue
 * @rx_queue:	queue of received control messages to be processed in @rx_work
@@ -136,6 +139,9 @@ struct qcom_glink {

	int irq;

	struct kthread_worker kworker;
	struct task_struct *task;

	struct work_struct rx_work;
	spinlock_t rx_lock;
	struct list_head rx_queue;
@@ -200,7 +206,7 @@ struct glink_channel {
	spinlock_t intent_lock;
	struct idr liids;
	struct idr riids;
	struct work_struct intent_work;
	struct kthread_work intent_work;
	struct list_head done_intents;

	struct glink_core_rx_intent *buf;
@@ -240,7 +246,7 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops;

#define GLINK_FEATURE_INTENTLESS	BIT(1)

static void qcom_glink_rx_done_work(struct work_struct *work);
static void qcom_glink_rx_done_work(struct kthread_work *work);

static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
						      const char *name)
@@ -264,7 +270,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
	init_completion(&channel->intent_req_comp);

	INIT_LIST_HEAD(&channel->done_intents);
	INIT_WORK(&channel->intent_work, qcom_glink_rx_done_work);
	kthread_init_work(&channel->intent_work, qcom_glink_rx_done_work);

	idr_init(&channel->liids);
	idr_init(&channel->riids);
@@ -280,6 +286,8 @@ static void qcom_glink_channel_release(struct kref *ref)
	unsigned long flags;

	CH_INFO(channel, "\n");
	kthread_cancel_work_sync(&channel->intent_work);

	spin_lock_irqsave(&channel->intent_lock, flags);
	idr_destroy(&channel->liids);
	idr_destroy(&channel->riids);
@@ -504,7 +512,7 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink,
	qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true);
}

static void qcom_glink_rx_done_work(struct work_struct *work)
static void qcom_glink_rx_done_work(struct kthread_work *work)
{
	struct glink_channel *channel = container_of(work, struct glink_channel,
						     intent_work);
@@ -566,7 +574,7 @@ static void qcom_glink_rx_done(struct qcom_glink *glink,
	list_add_tail(&intent->node, &channel->done_intents);
	spin_unlock(&channel->intent_lock);

	schedule_work(&channel->intent_work);
	kthread_queue_work(&glink->kworker, &channel->intent_work);
}

/**
@@ -1610,7 +1618,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid)
	CH_INFO(channel, "\n");

	/* cancel pending rx_done work */
	cancel_work_sync(&channel->intent_work);
	kthread_cancel_work_sync(&channel->intent_work);

	if (channel->rpdev) {
		strlcpy(chinfo.name, channel->name, sizeof(chinfo.name));
@@ -1800,6 +1808,15 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
		return ERR_CAST(glink->mbox_chan);
	}

	kthread_init_worker(&glink->kworker);
	glink->task = kthread_run(kthread_worker_fn, &glink->kworker,
				  "glink_%s", glink->name);
	if (IS_ERR(glink->task)) {
		dev_err(dev, "failed to spawn intent kthread %d\n",
			PTR_ERR(glink->task));
		return ERR_CAST(glink->task);
	}

	irq = of_irq_get(dev->of_node, 0);
	ret = devm_request_irq(dev, irq,
			       qcom_glink_native_intr,
@@ -1864,6 +1881,8 @@ void qcom_glink_native_remove(struct qcom_glink *glink)
	idr_destroy(&glink->rcids);
	spin_unlock_irqrestore(&glink->idr_lock, flags);

	kthread_flush_worker(&glink->kworker);
	kthread_stop(glink->task);
	qcom_glink_pipe_reset(glink);
	mbox_free_channel(glink->mbox_chan);
}