public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arun Kumar Neelakantam <aneela@codeaurora.org>
To: Sricharan R <sricharan@codeaurora.org>,
	ohad@wizery.com, bjorn.andersson@linaro.org,
	linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-msm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v2 08/20] rpmsg: glink: Introduce glink smem based transport
Date: Mon, 28 Aug 2017 17:18:06 +0530	[thread overview]
Message-ID: <2d4e12fd-4803-eadb-ea9d-6a5aa1faaa6d@codeaurora.org> (raw)
In-Reply-To: <1503559302-3744-9-git-send-email-sricharan@codeaurora.org>



On 8/24/2017 12:51 PM, Sricharan R wrote:
> From: Bjorn Andersson <bjorn.andersson@linaro.org>
>
> The glink protocol supports different types of
> transports (shared memory). With the core protocol
> remaining the same, the way the transport's memory is
> probed and accessed is different. So add support for
> glink's smem based transports.
>
> Adding a new smem transport register function and the
> fifo accessors for the same.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Acked-by: Arun Kumar Neelakantam <aneela@codeaurora.org>

Regards,
Arun N
> ---
>   drivers/rpmsg/Kconfig             |  10 ++
>   drivers/rpmsg/Makefile            |   1 +
>   drivers/rpmsg/qcom_glink_native.c |   5 +
>   drivers/rpmsg/qcom_glink_native.h |   1 +
>   drivers/rpmsg/qcom_glink_smem.c   | 311 ++++++++++++++++++++++++++++++++++++++
>   include/linux/rpmsg/qcom_glink.h  |  27 ++++
>   6 files changed, 355 insertions(+)
>   create mode 100644 drivers/rpmsg/qcom_glink_smem.c
>   create mode 100644 include/linux/rpmsg/qcom_glink.h
>
> diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
> index ac33688..4bd9ba3 100644
> --- a/drivers/rpmsg/Kconfig
> +++ b/drivers/rpmsg/Kconfig
> @@ -27,6 +27,16 @@ config RPMSG_QCOM_GLINK_RPM
>   	  which serves as a channel for communication with the RPM in GLINK
>   	  enabled systems.
>   
> +config RPMSG_QCOM_GLINK_SMEM
> +	tristate "Qualcomm SMEM Glink driver"
> +	select RPMSG_QCOM_GLINK_NATIVE
> +	depends on HAS_IOMEM
> +	depends on MAILBOX
> +	help
> +	  Say y here to enable support for the GLINK SMEM communication driver,
> +	  which provides support for using the GLINK communication protocol
> +	  over SMEM.
> +
>   config RPMSG_QCOM_SMD
>   	tristate "Qualcomm Shared Memory Driver (SMD)"
>   	depends on QCOM_SMEM
> diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
> index 09a756c..c71f4ab 100644
> --- a/drivers/rpmsg/Makefile
> +++ b/drivers/rpmsg/Makefile
> @@ -2,5 +2,6 @@ obj-$(CONFIG_RPMSG)		+= rpmsg_core.o
>   obj-$(CONFIG_RPMSG_CHAR)	+= rpmsg_char.o
>   obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
>   obj-$(CONFIG_RPMSG_QCOM_GLINK_NATIVE) += qcom_glink_native.o
> +obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
>   obj-$(CONFIG_RPMSG_QCOM_SMD)	+= qcom_smd.o
>   obj-$(CONFIG_RPMSG_VIRTIO)	+= virtio_rpmsg_bus.o
> diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
> index 21adde3..50a8008 100644
> --- a/drivers/rpmsg/qcom_glink_native.c
> +++ b/drivers/rpmsg/qcom_glink_native.c
> @@ -1010,3 +1010,8 @@ void qcom_glink_native_remove(struct qcom_glink *glink)
>   	idr_destroy(&glink->rcids);
>   	mbox_free_channel(glink->mbox_chan);
>   }
> +
> +void qcom_glink_native_unregister(struct qcom_glink *glink)
> +{
> +	device_unregister(glink->dev);
> +}
> diff --git a/drivers/rpmsg/qcom_glink_native.h b/drivers/rpmsg/qcom_glink_native.h
> index d5627a4..197bb9d 100644
> --- a/drivers/rpmsg/qcom_glink_native.h
> +++ b/drivers/rpmsg/qcom_glink_native.h
> @@ -35,4 +35,5 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
>   					   struct qcom_glink_pipe *tx);
>   void qcom_glink_native_remove(struct qcom_glink *glink);
>   
> +void qcom_glink_native_unregister(struct qcom_glink *glink);
>   #endif
> diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c
> new file mode 100644
> index 0000000..19179a1
> --- /dev/null
> +++ b/drivers/rpmsg/qcom_glink_smem.c
> @@ -0,0 +1,311 @@
> +/*
> + * Copyright (c) 2016, Linaro Ltd
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/slab.h>
> +#include <linux/rpmsg.h>
> +#include <linux/idr.h>
> +#include <linux/circ_buf.h>
> +#include <linux/soc/qcom/smem.h>
> +#include <linux/sizes.h>
> +#include <linux/delay.h>
> +#include <linux/regmap.h>
> +#include <linux/workqueue.h>
> +#include <linux/list.h>
> +
> +#include <linux/delay.h>
> +#include <linux/rpmsg.h>
> +#include <linux/rpmsg/qcom_glink.h>
> +
> +#include "qcom_glink_native.h"
> +
> +#define FIFO_FULL_RESERVE 8
> +#define FIFO_ALIGNMENT 8
> +#define TX_BLOCKED_CMD_RESERVE 8 /* size of struct read_notif_request */
> +
> +#define SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR	478
> +#define SMEM_GLINK_NATIVE_XPRT_FIFO_0		479
> +#define SMEM_GLINK_NATIVE_XPRT_FIFO_1		480
> +
> +struct glink_smem_pipe {
> +	struct qcom_glink_pipe native;
> +
> +	__le32 *tail;
> +	__le32 *head;
> +
> +	void *fifo;
> +
> +	int remote_pid;
> +};
> +
> +#define to_smem_pipe(p) container_of(p, struct glink_smem_pipe, native)
> +
> +static size_t glink_smem_rx_avail(struct qcom_glink_pipe *np)
> +{
> +	struct glink_smem_pipe *pipe = to_smem_pipe(np);
> +	size_t len;
> +	void *fifo;
> +	u32 head;
> +	u32 tail;
> +
> +	if (!pipe->fifo) {
> +		fifo = qcom_smem_get(pipe->remote_pid,
> +				     SMEM_GLINK_NATIVE_XPRT_FIFO_1, &len);
> +		if (IS_ERR(fifo)) {
> +			pr_err("failed to acquire RX fifo handle: %ld\n",
> +			       PTR_ERR(fifo));
> +			return 0;
> +		}
> +
> +		pipe->fifo = fifo;
> +		pipe->native.length = len;
> +	}
> +
> +	head = le32_to_cpu(*pipe->head);
> +	tail = le32_to_cpu(*pipe->tail);
> +
> +	if (head < tail)
> +		return pipe->native.length - tail + head;
> +	else
> +		return head - tail;
> +}
> +
> +static void glink_smem_rx_peak(struct qcom_glink_pipe *np,
> +			       void *data, size_t count)
> +{
> +	struct glink_smem_pipe *pipe = to_smem_pipe(np);
> +	size_t len;
> +	u32 tail;
> +
> +	tail = le32_to_cpu(*pipe->tail);
> +
> +	len = min_t(size_t, count, pipe->native.length - tail);
> +	if (len) {
> +		__ioread32_copy(data, pipe->fifo + tail,
> +				len / sizeof(u32));
> +	}
> +
> +	if (len != count) {
> +		__ioread32_copy(data + len, pipe->fifo,
> +				(count - len) / sizeof(u32));
> +	}
> +}
> +
> +static void glink_smem_rx_advance(struct qcom_glink_pipe *np,
> +				  size_t count)
> +{
> +	struct glink_smem_pipe *pipe = to_smem_pipe(np);
> +	u32 tail;
> +
> +	tail = le32_to_cpu(*pipe->tail);
> +
> +	tail += count;
> +	if (tail > pipe->native.length)
> +		tail -= pipe->native.length;
> +
> +	*pipe->tail = cpu_to_le32(tail);
> +}
> +
> +static size_t glink_smem_tx_avail(struct qcom_glink_pipe *np)
> +{
> +	struct glink_smem_pipe *pipe = to_smem_pipe(np);
> +	u32 head;
> +	u32 tail;
> +	u32 avail;
> +
> +	head = le32_to_cpu(*pipe->head);
> +	tail = le32_to_cpu(*pipe->tail);
> +
> +	if (tail <= head)
> +		avail = pipe->native.length - head + tail;
> +	else
> +		avail = tail - head;
> +
> +	if (avail < (FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE))
> +		avail = 0;
> +	else
> +		avail -= FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE;
> +
> +	return avail;
> +}
> +
> +static unsigned int glink_smem_tx_write_one(struct glink_smem_pipe *pipe,
> +					    unsigned int head,
> +					    const void *data, size_t count)
> +{
> +	size_t len;
> +
> +	len = min_t(size_t, count, pipe->native.length - head);
> +	if (len)
> +		memcpy(pipe->fifo + head, data, len);
> +
> +	if (len != count)
> +		memcpy(pipe->fifo, data + len, count - len);
> +
> +	head += count;
> +	if (head >= pipe->native.length)
> +		head -= pipe->native.length;
> +
> +	return head;
> +}
> +
> +static void glink_smem_tx_write(struct qcom_glink_pipe *glink_pipe,
> +				const void *hdr, size_t hlen,
> +				const void *data, size_t dlen)
> +{
> +	struct glink_smem_pipe *pipe = to_smem_pipe(glink_pipe);
> +	unsigned int head;
> +
> +	head = le32_to_cpu(*pipe->head);
> +
> +	head = glink_smem_tx_write_one(pipe, head, hdr, hlen);
> +	head = glink_smem_tx_write_one(pipe, head, data, dlen);
> +
> +	/* Ensure head is always aligned to 8 bytes */
> +	head = ALIGN(head, 8);
> +	if (head >= pipe->native.length)
> +		head -= pipe->native.length;
> +
> +	*pipe->head = cpu_to_le32(head);
> +}
> +
> +static void qcom_glink_smem_release(struct device *dev)
> +{
> +	kfree(dev);
> +}
> +
> +struct qcom_glink *qcom_glink_smem_register(struct device *parent,
> +					    struct device_node *node)
> +{
> +	struct glink_smem_pipe *rx_pipe;
> +	struct glink_smem_pipe *tx_pipe;
> +	struct qcom_glink *glink;
> +	struct device *dev;
> +	u32 remote_pid;
> +	__le32 *descs;
> +	size_t size;
> +	int ret;
> +
> +	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> +	if (!dev)
> +		return ERR_PTR(-ENOMEM);
> +
> +	dev->parent = parent;
> +	dev->of_node = node;
> +	dev->release = qcom_glink_smem_release;
> +	dev_set_name(dev, "%s:%s", node->parent->name, node->name);
> +	ret = device_register(dev);
> +	if (ret) {
> +		pr_err("failed to register glink edge\n");
> +		return ERR_PTR(ret);
> +	}
> +
> +	ret = of_property_read_u32(dev->of_node, "qcom,remote-pid",
> +				   &remote_pid);
> +	if (ret) {
> +		dev_err(dev, "failed to parse qcom,remote-pid\n");
> +		goto err_put_dev;
> +	}
> +
> +	rx_pipe = devm_kzalloc(dev, sizeof(*rx_pipe), GFP_KERNEL);
> +	tx_pipe = devm_kzalloc(dev, sizeof(*tx_pipe), GFP_KERNEL);
> +	if (!rx_pipe || !tx_pipe) {
> +		ret = -ENOMEM;
> +		goto err_put_dev;
> +	}
> +
> +	ret = qcom_smem_alloc(remote_pid,
> +			      SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32);
> +	if (ret && ret != -EEXIST) {
> +		dev_err(dev, "failed to allocate glink descriptors\n");
> +		goto err_put_dev;
> +	}
> +
> +	descs = qcom_smem_get(remote_pid,
> +			      SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, &size);
> +	if (IS_ERR(descs)) {
> +		dev_err(dev, "failed to acquire xprt descriptor\n");
> +		ret = PTR_ERR(descs);
> +		goto err_put_dev;
> +	}
> +
> +	if (size != 32) {
> +		dev_err(dev, "glink descriptor of invalid size\n");
> +		ret = -EINVAL;
> +		goto err_put_dev;
> +	}
> +
> +	tx_pipe->tail = &descs[0];
> +	tx_pipe->head = &descs[1];
> +	rx_pipe->tail = &descs[2];
> +	rx_pipe->head = &descs[3];
> +
> +	ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0,
> +			      SZ_16K);
> +	if (ret && ret != -EEXIST) {
> +		dev_err(dev, "failed to allocate TX fifo\n");
> +		goto err_put_dev;
> +	}
> +
> +	tx_pipe->fifo = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0,
> +				      &tx_pipe->native.length);
> +	if (IS_ERR(tx_pipe->fifo)) {
> +		dev_err(dev, "failed to acquire TX fifo\n");
> +		ret = PTR_ERR(tx_pipe->fifo);
> +		goto err_put_dev;
> +	}
> +
> +	rx_pipe->native.avail = glink_smem_rx_avail;
> +	rx_pipe->native.peak = glink_smem_rx_peak;
> +	rx_pipe->native.advance = glink_smem_rx_advance;
> +	rx_pipe->remote_pid = remote_pid;
> +
> +	tx_pipe->native.avail = glink_smem_tx_avail;
> +	tx_pipe->native.write = glink_smem_tx_write;
> +	tx_pipe->remote_pid = remote_pid;
> +
> +	*rx_pipe->tail = 0;
> +	*tx_pipe->head = 0;
> +
> +	glink = qcom_glink_native_probe(dev,
> +					&rx_pipe->native, &tx_pipe->native);
> +	if (IS_ERR(glink)) {
> +		ret = PTR_ERR(glink);
> +		goto err_put_dev;
> +	}
> +
> +	return glink;
> +
> +err_put_dev:
> +	put_device(dev);
> +
> +	return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(qcom_glink_smem_register);
> +
> +void qcom_glink_smem_unregister(struct qcom_glink *glink)
> +{
> +	qcom_glink_native_remove(glink);
> +	qcom_glink_native_unregister(glink);
> +}
> +EXPORT_SYMBOL_GPL(qcom_glink_smem_unregister);
> +
> +MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>");
> +MODULE_DESCRIPTION("Qualcomm GLINK SMEM driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/rpmsg/qcom_glink.h b/include/linux/rpmsg/qcom_glink.h
> new file mode 100644
> index 0000000..a622f02
> --- /dev/null
> +++ b/include/linux/rpmsg/qcom_glink.h
> @@ -0,0 +1,27 @@
> +#ifndef _LINUX_RPMSG_QCOM_GLINK_H
> +#define _LINUX_RPMSG_QCOM_GLINK_H
> +
> +#include <linux/device.h>
> +
> +struct qcom_glink;
> +
> +#if IS_ENABLED(CONFIG_RPMSG_QCOM_GLINK_SMEM)
> +
> +struct qcom_glink *qcom_glink_smem_register(struct device *parent,
> +					    struct device_node *node);
> +void qcom_glink_smem_unregister(struct qcom_glink *glink);
> +
> +#else
> +
> +static inline struct qcom_glink *
> +qcom_glink_smem_register(struct device *parent,
> +			 struct device_node *node)
> +{
> +	return NULL;
> +}
> +
> +static inline void qcom_glink_smem_unregister(struct qcom_glink *glink) {}
> +
> +#endif
> +
> +#endif

  reply	other threads:[~2017-08-28 11:48 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-24  7:21 [PATCH v2 00/20] rpmsg: glink: Add glink smem based transport Sricharan R
2017-08-24  7:21 ` [PATCH v2 01/20] rpmsg: glink: Rename glink_rpm_xx functions to qcom_glink_xx Sricharan R
2017-08-28 11:42   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 02/20] rpmsg: glink: Associate indirections for pipe fifo accessor's Sricharan R
2017-08-28 11:44   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 03/20] rpmsg: glink: Split rpm_probe to reuse the common code Sricharan R
2017-08-28 11:44   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 04/20] rpmsg: glink: Move the common glink protocol implementation to glink_native.c Sricharan R
2017-08-28 11:45   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 05/20] rpmsg: glink: Allow unaligned data access Sricharan R
2017-08-28 11:46   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 06/20] rpmsg: glink: Return -EAGAIN when there is no FIFO space Sricharan R
2017-08-28 11:47   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 07/20] rpmsg: glink: Do a mbox_free_channel in remove Sricharan R
2017-08-28 11:47   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 08/20] rpmsg: glink: Introduce glink smem based transport Sricharan R
2017-08-28 11:48   ` Arun Kumar Neelakantam [this message]
2017-08-24  7:21 ` [PATCH v2 09/20] rpmsg: glink: Fix default case while handling received commands Sricharan R
2017-08-28 11:48   ` Arun Kumar Neelakantam
2017-08-29 20:57   ` Bjorn Andersson
2017-08-24  7:21 ` [PATCH v2 10/20] rpmsg: glink: Add support for transport version negotiation Sricharan R
2017-08-28 11:48   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 11/20] rpmsg: glink: Fix idr_lock from mutex to spinlock Sricharan R
2017-08-28 11:49   ` Arun Kumar Neelakantam
2017-08-28 21:51   ` Chris Lew
2017-08-28 23:13     ` Sricharan R
2017-08-24  7:21 ` [PATCH v2 12/20] rpmsg: glink: Add support for TX intents Sricharan R
2017-08-28 11:49   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 13/20] rpmsg: glink: Use the local intents when receiving data Sricharan R
2017-08-28 11:49   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 14/20] rpmsg: glink: Make RX FIFO peak accessor to take an offset Sricharan R
2017-08-28 11:50   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 15/20] rpmsg: glink: Add rx done command Sricharan R
2017-08-28 11:50   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 16/20] rpmsg: glink: Add announce_create ops and preallocate intents Sricharan R
2017-08-28 11:50   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 17/20] rpmsg: glink: Receive and store the remote intent buffers Sricharan R
2017-08-28 11:51   ` Arun Kumar Neelakantam
2017-08-24  7:21 ` [PATCH v2 18/20] rpmsg: glink: Use the intents passed by remote Sricharan R
2017-08-24  7:21 ` [PATCH v2 19/20] rpmsg: glink: Request for intents when unavailable Sricharan R
2017-08-24  7:21 ` [PATCH v2 20/20] rpmsg: glink: Handle remote rx done command Sricharan R

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2d4e12fd-4803-eadb-ea9d-6a5aa1faaa6d@codeaurora.org \
    --to=aneela@codeaurora.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=ohad@wizery.com \
    --cc=sricharan@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox