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

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

Merge "rpmsg: glink: spi: Rework glink spi bus voting logic"

parents 71d1f80c be9e06a7
Loading
Loading
Loading
Loading
+23 −47
Original line number Original line Diff line number Diff line
@@ -200,8 +200,7 @@ struct glink_spi {


	struct wcd_spi_ops spi_ops;
	struct wcd_spi_ops spi_ops;
	struct glink_cmpnt cmpnt;
	struct glink_cmpnt cmpnt;
	u32 activity_flag;
	atomic_t activity_cnt;
	spinlock_t activity_lock;
	atomic_t in_reset;
	atomic_t in_reset;


	void *ilc;
	void *ilc;
@@ -297,21 +296,6 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops;
static void glink_spi_rx_done_work(struct work_struct *work);
static void glink_spi_rx_done_work(struct work_struct *work);
static void glink_spi_remove(struct glink_spi *glink);
static void glink_spi_remove(struct glink_spi *glink);


/**
 * spi_suspend() - Vote for the spi device suspend
 * @cmpnt:	Component to identify the spi device.
 *
 * Return: 0 on success, standard Linux error codes on failure.
 */
static int spi_suspend(struct glink_cmpnt *cmpnt)
{
	if (!cmpnt || !cmpnt->master_dev || !cmpnt->master_ops ||
	    !cmpnt->master_ops->suspend)
		return 0;

	return cmpnt->master_ops->suspend(cmpnt->master_dev);
}

/**
/**
 * spi_resume() - Vote for the spi device resume
 * spi_resume() - Vote for the spi device resume
 * @cmpnt:	Component to identify the spi device.
 * @cmpnt:	Component to identify the spi device.
@@ -337,12 +321,7 @@ static int spi_resume(struct glink_cmpnt *cmpnt)
 */
 */
static void glink_spi_xprt_set_poll_mode(struct glink_spi *glink)
static void glink_spi_xprt_set_poll_mode(struct glink_spi *glink)
{
{
	unsigned long flags;
	atomic_inc(&glink->activity_cnt);

	spin_lock_irqsave(&glink->activity_lock, flags);
	glink->activity_flag |= ACTIVE_RX;
	spin_unlock_irqrestore(&glink->activity_lock, flags);

	spi_resume(&glink->cmpnt);
	spi_resume(&glink->cmpnt);
}
}


@@ -355,13 +334,7 @@ static void glink_spi_xprt_set_poll_mode(struct glink_spi *glink)
 */
 */
static void glink_spi_xprt_set_irq_mode(struct glink_spi *glink)
static void glink_spi_xprt_set_irq_mode(struct glink_spi *glink)
{
{
	unsigned long flags;
	atomic_dec(&glink->activity_cnt);

	spin_lock_irqsave(&glink->activity_lock, flags);
	glink->activity_flag &= ~ACTIVE_RX;
	spin_unlock_irqrestore(&glink->activity_lock, flags);

	spi_suspend(&glink->cmpnt);
}
}


static struct glink_channel *glink_spi_alloc_channel(struct glink_spi *glink,
static struct glink_channel *glink_spi_alloc_channel(struct glink_spi *glink,
@@ -1259,11 +1232,8 @@ static int __glink_spi_send(struct glink_channel *channel,


	CH_INFO(channel, "size:%d, wait:%d\n", len, wait);
	CH_INFO(channel, "size:%d, wait:%d\n", len, wait);


	spin_lock_irqsave(&glink->activity_lock, flags);
	atomic_inc(&glink->activity_cnt);
	glink->activity_flag |= ACTIVE_TX;
	spi_resume(&glink->cmpnt);
	spin_unlock_irqrestore(&glink->activity_lock, flags);

	kref_get(&channel->refcount);
	while (!intent) {
	while (!intent) {
		spin_lock_irqsave(&channel->intent_lock, flags);
		spin_lock_irqsave(&channel->intent_lock, flags);
		idr_for_each_entry(&channel->riids, tmp, iid) {
		idr_for_each_entry(&channel->riids, tmp, iid) {
@@ -1315,11 +1285,8 @@ static int __glink_spi_send(struct glink_channel *channel,
	/* Mark intent available if we failed */
	/* Mark intent available if we failed */
	if (ret && intent)
	if (ret && intent)
		intent->in_use = false;
		intent->in_use = false;
	kref_put(&channel->refcount, glink_spi_channel_release);


	spin_lock_irqsave(&glink->activity_lock, flags);
	atomic_dec(&glink->activity_cnt);
	glink->activity_flag &= ~ACTIVE_TX;
	spin_unlock_irqrestore(&glink->activity_lock, flags);


	return ret;
	return ret;
}
}
@@ -1402,6 +1369,9 @@ static void glink_spi_rx_done_work(struct work_struct *work)
	struct glink_core_rx_intent *intent, *tmp;
	struct glink_core_rx_intent *intent, *tmp;
	unsigned long flags;
	unsigned long flags;


	atomic_inc(&glink->activity_cnt);
	spi_resume(&glink->cmpnt);

	spin_lock_irqsave(&channel->intent_lock, flags);
	spin_lock_irqsave(&channel->intent_lock, flags);
	list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) {
	list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) {
		list_del(&intent->node);
		list_del(&intent->node);
@@ -1412,6 +1382,8 @@ static void glink_spi_rx_done_work(struct work_struct *work)
		spin_lock_irqsave(&channel->intent_lock, flags);
		spin_lock_irqsave(&channel->intent_lock, flags);
	}
	}
	spin_unlock_irqrestore(&channel->intent_lock, flags);
	spin_unlock_irqrestore(&channel->intent_lock, flags);

	atomic_dec(&glink->activity_cnt);
}
}


static void glink_spi_rx_done(struct glink_spi *glink,
static void glink_spi_rx_done(struct glink_spi *glink,
@@ -1955,7 +1927,7 @@ static int glink_spi_rx_data(struct glink_spi *glink,


	/* Handle message when no fragments remain to be received */
	/* Handle message when no fragments remain to be received */
	if (!left_size) {
	if (!left_size) {
		spin_lock(&channel->recv_lock);
		spin_lock_irqsave(&channel->recv_lock, flags);
		if (channel->ept.cb) {
		if (channel->ept.cb) {
			channel->ept.cb(channel->ept.rpdev,
			channel->ept.cb(channel->ept.rpdev,
					intent->data,
					intent->data,
@@ -1963,7 +1935,7 @@ static int glink_spi_rx_data(struct glink_spi *glink,
					channel->ept.priv,
					channel->ept.priv,
					RPMSG_ADDR_ANY);
					RPMSG_ADDR_ANY);
		}
		}
		spin_unlock(&channel->recv_lock);
		spin_unlock_irqrestore(&channel->recv_lock, flags);


		intent->offset = 0;
		intent->offset = 0;
		channel->buf = NULL;
		channel->buf = NULL;
@@ -2021,7 +1993,7 @@ static int glink_spi_rx_short_data(struct glink_spi *glink,


	/* Handle message when no fragments remain to be received */
	/* Handle message when no fragments remain to be received */
	if (!left_size) {
	if (!left_size) {
		spin_lock(&channel->recv_lock);
		spin_lock_irqsave(&channel->recv_lock, flags);
		if (channel->ept.cb) {
		if (channel->ept.cb) {
			channel->ept.cb(channel->ept.rpdev,
			channel->ept.cb(channel->ept.rpdev,
					intent->data,
					intent->data,
@@ -2029,7 +2001,7 @@ static int glink_spi_rx_short_data(struct glink_spi *glink,
					channel->ept.priv,
					channel->ept.priv,
					RPMSG_ADDR_ANY);
					RPMSG_ADDR_ANY);
		}
		}
		spin_unlock(&channel->recv_lock);
		spin_unlock_irqrestore(&channel->recv_lock, flags);


		intent->offset = 0;
		intent->offset = 0;
		channel->buf = NULL;
		channel->buf = NULL;
@@ -2053,6 +2025,8 @@ static void glink_spi_defer_work(struct work_struct *work)
	unsigned int param4;
	unsigned int param4;
	unsigned int cmd;
	unsigned int cmd;


	atomic_inc(&glink->activity_cnt);
	spi_resume(&glink->cmpnt);
	for (;;) {
	for (;;) {
		spin_lock_irqsave(&glink->rx_lock, flags);
		spin_lock_irqsave(&glink->rx_lock, flags);
		if (list_empty(&glink->rx_queue)) {
		if (list_empty(&glink->rx_queue)) {
@@ -2088,6 +2062,7 @@ static void glink_spi_defer_work(struct work_struct *work)


		kfree(dcmd);
		kfree(dcmd);
	}
	}
	atomic_dec(&glink->activity_cnt);
}
}


static int glink_spi_rx_defer(struct glink_spi *glink,
static int glink_spi_rx_defer(struct glink_spi *glink,
@@ -2267,7 +2242,7 @@ static int glink_spi_cmpnt_event_handler(struct device *dev, void *priv,
{
{
	struct glink_spi *glink = dev_get_drvdata(dev);
	struct glink_spi *glink = dev_get_drvdata(dev);
	struct glink_cmpnt *cmpnt = &glink->cmpnt;
	struct glink_cmpnt *cmpnt = &glink->cmpnt;
	int ret;
	int ret = 0;


	switch (event) {
	switch (event) {
	case WDSP_EVENT_PRE_BOOTUP:
	case WDSP_EVENT_PRE_BOOTUP:
@@ -2296,13 +2271,15 @@ static int glink_spi_cmpnt_event_handler(struct device *dev, void *priv,
	case WDSP_EVENT_RESUME:
	case WDSP_EVENT_RESUME:
		break;
		break;
	case WDSP_EVENT_SUSPEND:
	case WDSP_EVENT_SUSPEND:
		if (atomic_read(&glink->activity_cnt))
			ret = -EBUSY;
		break;
		break;
	default:
	default:
		GLINK_INFO(glink, "unhandled event %d", event);
		GLINK_INFO(glink, "unhandled event %d", event);
		break;
		break;
	}
	}


	return 0;
	return ret;
}
}


/* glink_spi_cmpnt_ops - Callback operations registered wtih wdsp framework */
/* glink_spi_cmpnt_ops - Callback operations registered wtih wdsp framework */
@@ -2424,8 +2401,7 @@ struct glink_spi *qcom_glink_spi_register(struct device *parent,
	idr_init(&glink->rcids);
	idr_init(&glink->rcids);


	atomic_set(&glink->in_reset, 1);
	atomic_set(&glink->in_reset, 1);
	glink->activity_flag = 0;
	atomic_set(&glink->activity_cnt, 0);
	spin_lock_init(&glink->activity_lock);


	ret = glink_spi_init_pipe("tx-descriptors", node, &glink->tx_pipe);
	ret = glink_spi_init_pipe("tx-descriptors", node, &glink->tx_pipe);
	if (ret)
	if (ret)