Re: [PATCH 04/18] rpmsg: glink: Move the common glink protocol implementation to glink_native.c

2017-08-22 Thread Sricharan R
Hi Arun,
  Thanks for the review.

On 8/22/2017 11:28 AM, Arun Kumar Neelakantam wrote:
> 
> 
> On 8/16/2017 10:48 PM, Sricharan R wrote:
>> +
>> +struct glink_msg {
>> +    __le16 cmd;
>> +    __le16 param1;
>> +    __le32 param2;
>> +    u8 data[];
>> +} __packed;
> 
> why we are using extra u8 data[] member here ?
> 
 Just as a zero-sized placeholder, to read a variable length header if required.

>> +
>> +/**
>> + * struct glink_defer_cmd - deferred incoming control message
>> + * @node:    list node
>> + * @msg:    message header
>> + * data:    payload of the message
>> + *
>> + * Copy of a received control message, to be added to @rx_queue and 
>> processed
>> + * by @rx_work of @glink_rpm.
>> + */
>> +struct glink_defer_cmd {
>> +    struct list_head node;
>> +
>> +    struct glink_msg msg;
>> +    u8 data[];
>> +};
>> +
>> +/**
>> + * struct glink_rpm - driver context, relates to one remote subsystem
> 
> glink_rpm to qcom_glink
> 
 ok, will change.

>> +static int qcom_glink_tx(struct qcom_glink *glink,
>> + const void *hdr, size_t hlen,
>> + const void *data, size_t dlen, bool wait)
>> +{
>> +    unsigned int tlen = hlen + dlen;
>> +    int ret;
>> +
>> +    /* Reject packets that are too big */
>> +    if (tlen >= glink->tx_pipe->length)
>> +    return -EINVAL;
> 
> we need to add support for split packets, in some cases packets may be 
> greater than 16K.

 ok, the plan was to add that in next set of patches and keep this series to a 
minimum.

>> +
>> +    if (WARN(tlen % 8, "Unaligned TX request"))
>> +    return -EINVAL;
>> +
>> +    ret = mutex_lock_interruptible(>tx_lock);
>> +    if (ret)
>> +    return ret;
>> +
>> +    while (qcom_glink_tx_avail(glink) < tlen) {
>> +    if (!wait) {
>> +    ret = -ENOMEM;
> 
> This condition is either reader is slow or not reading data, should we return 
> -EAGAIN here instead of -ENOMEM?

 ok, will change.

>> +    goto out;
>> +    }
>> +
>> +    msleep(10);
>> +    }
>> +
>> +    qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
>> +
>> +    mbox_send_message(glink->mbox_chan, NULL);
>> +    mbox_client_txdone(glink->mbox_chan, 0);
>> +
>> +out:
>> +    mutex_unlock(>tx_lock);
>> +
>> +    return ret;
>> +}
>> +
> 
> 
>> +/**
>> + * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote
>> + * @glink:
>> + * @channel:
> 
> Missed information for @ glink and @channel

 ok, will add.

>> + *
>> + * Allocates a local channel id and sends a RPM_CMD_OPEN message to the 
>> remote.
>> + * Will return with refcount held, regardless of outcome.
>> + *
>> + * Returns 0 on success, negative errno otherwise.
>> + */
>> +static int qcom_glink_send_open_req(struct qcom_glink *glink,
>> +    struct glink_channel *channel)
> 
> 
>> +static irqreturn_t qcom_glink_native_intr(int irq, void *data)
>> +{
>> +    struct qcom_glink *glink = data;
>> +    struct glink_msg msg;
>> +    unsigned int param1;
>> +    unsigned int param2;
>> +    unsigned int avail;
>> +    unsigned int cmd;
>> +    int ret;
>> +
>> +    for (;;) {
>> +    avail = qcom_glink_rx_avail(glink);
>> +    if (avail < sizeof(msg))
>> +    break;
>> +
>> +    qcom_glink_rx_peak(glink, , sizeof(msg));
>> +
>> +    cmd = le16_to_cpu(msg.cmd);
>> +    param1 = le16_to_cpu(msg.param1);
>> +    param2 = le32_to_cpu(msg.param2);
>> +
>> +    switch (cmd) {
>> +    case RPM_CMD_VERSION:
>> +    case RPM_CMD_VERSION_ACK:
>> +    case RPM_CMD_CLOSE:
>> +    case RPM_CMD_CLOSE_ACK:
>> +    ret = qcom_glink_rx_defer(glink, 0);
>> +    break;
>> +    case RPM_CMD_OPEN_ACK:
>> +    ret = qcom_glink_rx_open_ack(glink, param1);
>> +    qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
>> +    break;
>> +    case RPM_CMD_OPEN:
>> +    ret = qcom_glink_rx_defer(glink, param2);
>> +    break;
>> +    case RPM_CMD_TX_DATA:
>> +    case RPM_CMD_TX_DATA_CONT:
>> +    ret = qcom_glink_rx_data(glink, avail);
>> +    break;
>> +    case RPM_CMD_READ_NOTIF:
>> +    qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
>> +
>> +    mbox_send_message(glink->mbox_chan, NULL);
>> +    mbox_client_txdone(glink->mbox_chan, 0);
>> +
>> +    ret = 0;
>> +    break;
>> +    default:
>> +    dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
> 
> please add more information in error log to find the remote peripheral also 
> other wise after adding SMEM transport it will be difficult to find for which 
> peripheral the error came.

 ok, you refer to logging the "edge" name, that should be taken care by the 
dev_err print ?
 That said, i think the dev name in glink smem can be modified to reflect the 
edge name
 instead of simply printing the remoteproc name. Will change that.

>> +    ret = -EINVAL;
>> +    break;
>> +    }

Re: [PATCH 04/18] rpmsg: glink: Move the common glink protocol implementation to glink_native.c

2017-08-22 Thread Sricharan R
Hi Arun,
  Thanks for the review.

On 8/22/2017 11:28 AM, Arun Kumar Neelakantam wrote:
> 
> 
> On 8/16/2017 10:48 PM, Sricharan R wrote:
>> +
>> +struct glink_msg {
>> +    __le16 cmd;
>> +    __le16 param1;
>> +    __le32 param2;
>> +    u8 data[];
>> +} __packed;
> 
> why we are using extra u8 data[] member here ?
> 
 Just as a zero-sized placeholder, to read a variable length header if required.

>> +
>> +/**
>> + * struct glink_defer_cmd - deferred incoming control message
>> + * @node:    list node
>> + * @msg:    message header
>> + * data:    payload of the message
>> + *
>> + * Copy of a received control message, to be added to @rx_queue and 
>> processed
>> + * by @rx_work of @glink_rpm.
>> + */
>> +struct glink_defer_cmd {
>> +    struct list_head node;
>> +
>> +    struct glink_msg msg;
>> +    u8 data[];
>> +};
>> +
>> +/**
>> + * struct glink_rpm - driver context, relates to one remote subsystem
> 
> glink_rpm to qcom_glink
> 
 ok, will change.

>> +static int qcom_glink_tx(struct qcom_glink *glink,
>> + const void *hdr, size_t hlen,
>> + const void *data, size_t dlen, bool wait)
>> +{
>> +    unsigned int tlen = hlen + dlen;
>> +    int ret;
>> +
>> +    /* Reject packets that are too big */
>> +    if (tlen >= glink->tx_pipe->length)
>> +    return -EINVAL;
> 
> we need to add support for split packets, in some cases packets may be 
> greater than 16K.

 ok, the plan was to add that in next set of patches and keep this series to a 
minimum.

>> +
>> +    if (WARN(tlen % 8, "Unaligned TX request"))
>> +    return -EINVAL;
>> +
>> +    ret = mutex_lock_interruptible(>tx_lock);
>> +    if (ret)
>> +    return ret;
>> +
>> +    while (qcom_glink_tx_avail(glink) < tlen) {
>> +    if (!wait) {
>> +    ret = -ENOMEM;
> 
> This condition is either reader is slow or not reading data, should we return 
> -EAGAIN here instead of -ENOMEM?

 ok, will change.

>> +    goto out;
>> +    }
>> +
>> +    msleep(10);
>> +    }
>> +
>> +    qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
>> +
>> +    mbox_send_message(glink->mbox_chan, NULL);
>> +    mbox_client_txdone(glink->mbox_chan, 0);
>> +
>> +out:
>> +    mutex_unlock(>tx_lock);
>> +
>> +    return ret;
>> +}
>> +
> 
> 
>> +/**
>> + * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote
>> + * @glink:
>> + * @channel:
> 
> Missed information for @ glink and @channel

 ok, will add.

>> + *
>> + * Allocates a local channel id and sends a RPM_CMD_OPEN message to the 
>> remote.
>> + * Will return with refcount held, regardless of outcome.
>> + *
>> + * Returns 0 on success, negative errno otherwise.
>> + */
>> +static int qcom_glink_send_open_req(struct qcom_glink *glink,
>> +    struct glink_channel *channel)
> 
> 
>> +static irqreturn_t qcom_glink_native_intr(int irq, void *data)
>> +{
>> +    struct qcom_glink *glink = data;
>> +    struct glink_msg msg;
>> +    unsigned int param1;
>> +    unsigned int param2;
>> +    unsigned int avail;
>> +    unsigned int cmd;
>> +    int ret;
>> +
>> +    for (;;) {
>> +    avail = qcom_glink_rx_avail(glink);
>> +    if (avail < sizeof(msg))
>> +    break;
>> +
>> +    qcom_glink_rx_peak(glink, , sizeof(msg));
>> +
>> +    cmd = le16_to_cpu(msg.cmd);
>> +    param1 = le16_to_cpu(msg.param1);
>> +    param2 = le32_to_cpu(msg.param2);
>> +
>> +    switch (cmd) {
>> +    case RPM_CMD_VERSION:
>> +    case RPM_CMD_VERSION_ACK:
>> +    case RPM_CMD_CLOSE:
>> +    case RPM_CMD_CLOSE_ACK:
>> +    ret = qcom_glink_rx_defer(glink, 0);
>> +    break;
>> +    case RPM_CMD_OPEN_ACK:
>> +    ret = qcom_glink_rx_open_ack(glink, param1);
>> +    qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
>> +    break;
>> +    case RPM_CMD_OPEN:
>> +    ret = qcom_glink_rx_defer(glink, param2);
>> +    break;
>> +    case RPM_CMD_TX_DATA:
>> +    case RPM_CMD_TX_DATA_CONT:
>> +    ret = qcom_glink_rx_data(glink, avail);
>> +    break;
>> +    case RPM_CMD_READ_NOTIF:
>> +    qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
>> +
>> +    mbox_send_message(glink->mbox_chan, NULL);
>> +    mbox_client_txdone(glink->mbox_chan, 0);
>> +
>> +    ret = 0;
>> +    break;
>> +    default:
>> +    dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
> 
> please add more information in error log to find the remote peripheral also 
> other wise after adding SMEM transport it will be difficult to find for which 
> peripheral the error came.

 ok, you refer to logging the "edge" name, that should be taken care by the 
dev_err print ?
 That said, i think the dev name in glink smem can be modified to reflect the 
edge name
 instead of simply printing the remoteproc name. Will change that.

>> +    ret = -EINVAL;
>> +    break;
>> +    }

Re: [PATCH 04/18] rpmsg: glink: Move the common glink protocol implementation to glink_native.c

2017-08-21 Thread Arun Kumar Neelakantam



On 8/16/2017 10:48 PM, Sricharan R wrote:

+
+struct glink_msg {
+   __le16 cmd;
+   __le16 param1;
+   __le32 param2;
+   u8 data[];
+} __packed;


why we are using extra u8 data[] member here ?


+
+/**
+ * struct glink_defer_cmd - deferred incoming control message
+ * @node:  list node
+ * @msg:   message header
+ * data:   payload of the message
+ *
+ * Copy of a received control message, to be added to @rx_queue and processed
+ * by @rx_work of @glink_rpm.
+ */
+struct glink_defer_cmd {
+   struct list_head node;
+
+   struct glink_msg msg;
+   u8 data[];
+};
+
+/**
+ * struct glink_rpm - driver context, relates to one remote subsystem


glink_rpm to qcom_glink


+static int qcom_glink_tx(struct qcom_glink *glink,
+const void *hdr, size_t hlen,
+const void *data, size_t dlen, bool wait)
+{
+   unsigned int tlen = hlen + dlen;
+   int ret;
+
+   /* Reject packets that are too big */
+   if (tlen >= glink->tx_pipe->length)
+   return -EINVAL;


we need to add support for split packets, in some cases packets may be 
greater than 16K.

+
+   if (WARN(tlen % 8, "Unaligned TX request"))
+   return -EINVAL;
+
+   ret = mutex_lock_interruptible(>tx_lock);
+   if (ret)
+   return ret;
+
+   while (qcom_glink_tx_avail(glink) < tlen) {
+   if (!wait) {
+   ret = -ENOMEM;


This condition is either reader is slow or not reading data, should we 
return -EAGAIN here instead of -ENOMEM?

+   goto out;
+   }
+
+   msleep(10);
+   }
+
+   qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
+
+   mbox_send_message(glink->mbox_chan, NULL);
+   mbox_client_txdone(glink->mbox_chan, 0);
+
+out:
+   mutex_unlock(>tx_lock);
+
+   return ret;
+}
+




+/**
+ * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote
+ * @glink:
+ * @channel:


Missed information for @ glink and @channel

+ *
+ * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote.
+ * Will return with refcount held, regardless of outcome.
+ *
+ * Returns 0 on success, negative errno otherwise.
+ */
+static int qcom_glink_send_open_req(struct qcom_glink *glink,
+   struct glink_channel *channel)




+static irqreturn_t qcom_glink_native_intr(int irq, void *data)
+{
+   struct qcom_glink *glink = data;
+   struct glink_msg msg;
+   unsigned int param1;
+   unsigned int param2;
+   unsigned int avail;
+   unsigned int cmd;
+   int ret;
+
+   for (;;) {
+   avail = qcom_glink_rx_avail(glink);
+   if (avail < sizeof(msg))
+   break;
+
+   qcom_glink_rx_peak(glink, , sizeof(msg));
+
+   cmd = le16_to_cpu(msg.cmd);
+   param1 = le16_to_cpu(msg.param1);
+   param2 = le32_to_cpu(msg.param2);
+
+   switch (cmd) {
+   case RPM_CMD_VERSION:
+   case RPM_CMD_VERSION_ACK:
+   case RPM_CMD_CLOSE:
+   case RPM_CMD_CLOSE_ACK:
+   ret = qcom_glink_rx_defer(glink, 0);
+   break;
+   case RPM_CMD_OPEN_ACK:
+   ret = qcom_glink_rx_open_ack(glink, param1);
+   qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+   break;
+   case RPM_CMD_OPEN:
+   ret = qcom_glink_rx_defer(glink, param2);
+   break;
+   case RPM_CMD_TX_DATA:
+   case RPM_CMD_TX_DATA_CONT:
+   ret = qcom_glink_rx_data(glink, avail);
+   break;
+   case RPM_CMD_READ_NOTIF:
+   qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+
+   mbox_send_message(glink->mbox_chan, NULL);
+   mbox_client_txdone(glink->mbox_chan, 0);
+
+   ret = 0;
+   break;
+   default:
+   dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);


please add more information in error log to find the remote peripheral 
also other wise after adding SMEM transport it will be difficult to find 
for which peripheral the error came.

+   ret = -EINVAL;
+   break;
+   }
+
+   if (ret)
+   break;
+   }
+
+   return IRQ_HANDLED;
+}
+



+struct qcom_glink *qcom_glink_native_probe(struct device *dev,
+  struct qcom_glink_pipe *rx,
+  struct qcom_glink_pipe *tx)
+{
+   int irq;
+   int ret;
+   struct qcom_glink *glink;
+
+   glink = devm_kzalloc(dev, sizeof(*glink), GFP_KERNEL);
+   if (!glink)
+

Re: [PATCH 04/18] rpmsg: glink: Move the common glink protocol implementation to glink_native.c

2017-08-21 Thread Arun Kumar Neelakantam



On 8/16/2017 10:48 PM, Sricharan R wrote:

+
+struct glink_msg {
+   __le16 cmd;
+   __le16 param1;
+   __le32 param2;
+   u8 data[];
+} __packed;


why we are using extra u8 data[] member here ?


+
+/**
+ * struct glink_defer_cmd - deferred incoming control message
+ * @node:  list node
+ * @msg:   message header
+ * data:   payload of the message
+ *
+ * Copy of a received control message, to be added to @rx_queue and processed
+ * by @rx_work of @glink_rpm.
+ */
+struct glink_defer_cmd {
+   struct list_head node;
+
+   struct glink_msg msg;
+   u8 data[];
+};
+
+/**
+ * struct glink_rpm - driver context, relates to one remote subsystem


glink_rpm to qcom_glink


+static int qcom_glink_tx(struct qcom_glink *glink,
+const void *hdr, size_t hlen,
+const void *data, size_t dlen, bool wait)
+{
+   unsigned int tlen = hlen + dlen;
+   int ret;
+
+   /* Reject packets that are too big */
+   if (tlen >= glink->tx_pipe->length)
+   return -EINVAL;


we need to add support for split packets, in some cases packets may be 
greater than 16K.

+
+   if (WARN(tlen % 8, "Unaligned TX request"))
+   return -EINVAL;
+
+   ret = mutex_lock_interruptible(>tx_lock);
+   if (ret)
+   return ret;
+
+   while (qcom_glink_tx_avail(glink) < tlen) {
+   if (!wait) {
+   ret = -ENOMEM;


This condition is either reader is slow or not reading data, should we 
return -EAGAIN here instead of -ENOMEM?

+   goto out;
+   }
+
+   msleep(10);
+   }
+
+   qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
+
+   mbox_send_message(glink->mbox_chan, NULL);
+   mbox_client_txdone(glink->mbox_chan, 0);
+
+out:
+   mutex_unlock(>tx_lock);
+
+   return ret;
+}
+




+/**
+ * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote
+ * @glink:
+ * @channel:


Missed information for @ glink and @channel

+ *
+ * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote.
+ * Will return with refcount held, regardless of outcome.
+ *
+ * Returns 0 on success, negative errno otherwise.
+ */
+static int qcom_glink_send_open_req(struct qcom_glink *glink,
+   struct glink_channel *channel)




+static irqreturn_t qcom_glink_native_intr(int irq, void *data)
+{
+   struct qcom_glink *glink = data;
+   struct glink_msg msg;
+   unsigned int param1;
+   unsigned int param2;
+   unsigned int avail;
+   unsigned int cmd;
+   int ret;
+
+   for (;;) {
+   avail = qcom_glink_rx_avail(glink);
+   if (avail < sizeof(msg))
+   break;
+
+   qcom_glink_rx_peak(glink, , sizeof(msg));
+
+   cmd = le16_to_cpu(msg.cmd);
+   param1 = le16_to_cpu(msg.param1);
+   param2 = le32_to_cpu(msg.param2);
+
+   switch (cmd) {
+   case RPM_CMD_VERSION:
+   case RPM_CMD_VERSION_ACK:
+   case RPM_CMD_CLOSE:
+   case RPM_CMD_CLOSE_ACK:
+   ret = qcom_glink_rx_defer(glink, 0);
+   break;
+   case RPM_CMD_OPEN_ACK:
+   ret = qcom_glink_rx_open_ack(glink, param1);
+   qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+   break;
+   case RPM_CMD_OPEN:
+   ret = qcom_glink_rx_defer(glink, param2);
+   break;
+   case RPM_CMD_TX_DATA:
+   case RPM_CMD_TX_DATA_CONT:
+   ret = qcom_glink_rx_data(glink, avail);
+   break;
+   case RPM_CMD_READ_NOTIF:
+   qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+
+   mbox_send_message(glink->mbox_chan, NULL);
+   mbox_client_txdone(glink->mbox_chan, 0);
+
+   ret = 0;
+   break;
+   default:
+   dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);


please add more information in error log to find the remote peripheral 
also other wise after adding SMEM transport it will be difficult to find 
for which peripheral the error came.

+   ret = -EINVAL;
+   break;
+   }
+
+   if (ret)
+   break;
+   }
+
+   return IRQ_HANDLED;
+}
+



+struct qcom_glink *qcom_glink_native_probe(struct device *dev,
+  struct qcom_glink_pipe *rx,
+  struct qcom_glink_pipe *tx)
+{
+   int irq;
+   int ret;
+   struct qcom_glink *glink;
+
+   glink = devm_kzalloc(dev, sizeof(*glink), GFP_KERNEL);
+   if (!glink)
+

[PATCH 04/18] rpmsg: glink: Move the common glink protocol implementation to glink_native.c

2017-08-16 Thread Sricharan R
From: Bjorn Andersson 

Move the common part of glink core protocol implementation to
glink_native.c that can be shared with the smem based glink
transport in the later patches.

Signed-off-by: Bjorn Andersson 
Signed-off-by: Sricharan R 
---
 drivers/rpmsg/Kconfig |6 +-
 drivers/rpmsg/Makefile|1 +
 drivers/rpmsg/qcom_glink_native.c | 1014 +
 drivers/rpmsg/qcom_glink_native.h |   38 ++
 drivers/rpmsg/qcom_glink_rpm.c|  995 +---
 5 files changed, 1061 insertions(+), 993 deletions(-)
 create mode 100644 drivers/rpmsg/qcom_glink_native.c
 create mode 100644 drivers/rpmsg/qcom_glink_native.h

diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 2a5d2b4..ac33688 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -13,9 +13,13 @@ config RPMSG_CHAR
  in /dev. They make it possible for user-space programs to send and
  receive rpmsg packets.
 
+config RPMSG_QCOM_GLINK_NATIVE
+   tristate
+   select RPMSG
+
 config RPMSG_QCOM_GLINK_RPM
tristate "Qualcomm RPM Glink driver"
-   select RPMSG
+select RPMSG_QCOM_GLINK_NATIVE
depends on HAS_IOMEM
depends on MAILBOX
help
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 28cc190..09a756c 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -1,5 +1,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_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
new file mode 100644
index 000..04afbb2
--- /dev/null
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -0,0 +1,1014 @@
+/*
+ * Copyright (c) 2016-2017, 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "rpmsg_internal.h"
+#include "qcom_glink_native.h"
+
+#define GLINK_NAME_SIZE32
+
+#define RPM_GLINK_CID_MIN  1
+#define RPM_GLINK_CID_MAX  65536
+
+struct glink_msg {
+   __le16 cmd;
+   __le16 param1;
+   __le32 param2;
+   u8 data[];
+} __packed;
+
+/**
+ * struct glink_defer_cmd - deferred incoming control message
+ * @node:  list node
+ * @msg:   message header
+ * data:   payload of the message
+ *
+ * Copy of a received control message, to be added to @rx_queue and processed
+ * by @rx_work of @glink_rpm.
+ */
+struct glink_defer_cmd {
+   struct list_head node;
+
+   struct glink_msg msg;
+   u8 data[];
+};
+
+/**
+ * struct glink_rpm - driver context, relates to one remote subsystem
+ * @dev:   reference to the associated struct device
+ * @doorbell:  "rpm_hlos" ipc doorbell
+ * @rx_pipe:   pipe object for receive FIFO
+ * @tx_pipe:   pipe object for transmit FIFO
+ * @irq:   IRQ for signaling incoming events
+ * @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
+ * @tx_lock:   synchronizes operations on the tx fifo
+ * @idr_lock:  synchronizes @lcids and @rcids modifications
+ * @lcids: idr of all channels with a known local channel id
+ * @rcids: idr of all channels with a known remote channel id
+ */
+struct qcom_glink {
+   struct device *dev;
+
+   struct mbox_client mbox_client;
+   struct mbox_chan *mbox_chan;
+
+   struct qcom_glink_pipe *rx_pipe;
+   struct qcom_glink_pipe *tx_pipe;
+
+   int irq;
+
+   struct work_struct rx_work;
+   spinlock_t rx_lock;
+   struct list_head rx_queue;
+
+   struct mutex tx_lock;
+
+   struct mutex idr_lock;
+   struct idr lcids;
+   struct idr rcids;
+};
+
+enum {
+   GLINK_STATE_CLOSED,
+   GLINK_STATE_OPENING,
+   GLINK_STATE_OPEN,
+   GLINK_STATE_CLOSING,
+};
+
+/**
+ * struct glink_channel - internal representation of a channel
+ * @rpdev: rpdev reference, only used for primary endpoints
+ * @ept:   rpmsg endpoint this channel is associated with
+ * @glink: qcom_glink context handle
+ * 

[PATCH 04/18] rpmsg: glink: Move the common glink protocol implementation to glink_native.c

2017-08-16 Thread Sricharan R
From: Bjorn Andersson 

Move the common part of glink core protocol implementation to
glink_native.c that can be shared with the smem based glink
transport in the later patches.

Signed-off-by: Bjorn Andersson 
Signed-off-by: Sricharan R 
---
 drivers/rpmsg/Kconfig |6 +-
 drivers/rpmsg/Makefile|1 +
 drivers/rpmsg/qcom_glink_native.c | 1014 +
 drivers/rpmsg/qcom_glink_native.h |   38 ++
 drivers/rpmsg/qcom_glink_rpm.c|  995 +---
 5 files changed, 1061 insertions(+), 993 deletions(-)
 create mode 100644 drivers/rpmsg/qcom_glink_native.c
 create mode 100644 drivers/rpmsg/qcom_glink_native.h

diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 2a5d2b4..ac33688 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -13,9 +13,13 @@ config RPMSG_CHAR
  in /dev. They make it possible for user-space programs to send and
  receive rpmsg packets.
 
+config RPMSG_QCOM_GLINK_NATIVE
+   tristate
+   select RPMSG
+
 config RPMSG_QCOM_GLINK_RPM
tristate "Qualcomm RPM Glink driver"
-   select RPMSG
+select RPMSG_QCOM_GLINK_NATIVE
depends on HAS_IOMEM
depends on MAILBOX
help
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index 28cc190..09a756c 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -1,5 +1,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_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
new file mode 100644
index 000..04afbb2
--- /dev/null
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -0,0 +1,1014 @@
+/*
+ * Copyright (c) 2016-2017, 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "rpmsg_internal.h"
+#include "qcom_glink_native.h"
+
+#define GLINK_NAME_SIZE32
+
+#define RPM_GLINK_CID_MIN  1
+#define RPM_GLINK_CID_MAX  65536
+
+struct glink_msg {
+   __le16 cmd;
+   __le16 param1;
+   __le32 param2;
+   u8 data[];
+} __packed;
+
+/**
+ * struct glink_defer_cmd - deferred incoming control message
+ * @node:  list node
+ * @msg:   message header
+ * data:   payload of the message
+ *
+ * Copy of a received control message, to be added to @rx_queue and processed
+ * by @rx_work of @glink_rpm.
+ */
+struct glink_defer_cmd {
+   struct list_head node;
+
+   struct glink_msg msg;
+   u8 data[];
+};
+
+/**
+ * struct glink_rpm - driver context, relates to one remote subsystem
+ * @dev:   reference to the associated struct device
+ * @doorbell:  "rpm_hlos" ipc doorbell
+ * @rx_pipe:   pipe object for receive FIFO
+ * @tx_pipe:   pipe object for transmit FIFO
+ * @irq:   IRQ for signaling incoming events
+ * @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
+ * @tx_lock:   synchronizes operations on the tx fifo
+ * @idr_lock:  synchronizes @lcids and @rcids modifications
+ * @lcids: idr of all channels with a known local channel id
+ * @rcids: idr of all channels with a known remote channel id
+ */
+struct qcom_glink {
+   struct device *dev;
+
+   struct mbox_client mbox_client;
+   struct mbox_chan *mbox_chan;
+
+   struct qcom_glink_pipe *rx_pipe;
+   struct qcom_glink_pipe *tx_pipe;
+
+   int irq;
+
+   struct work_struct rx_work;
+   spinlock_t rx_lock;
+   struct list_head rx_queue;
+
+   struct mutex tx_lock;
+
+   struct mutex idr_lock;
+   struct idr lcids;
+   struct idr rcids;
+};
+
+enum {
+   GLINK_STATE_CLOSED,
+   GLINK_STATE_OPENING,
+   GLINK_STATE_OPEN,
+   GLINK_STATE_CLOSING,
+};
+
+/**
+ * struct glink_channel - internal representation of a channel
+ * @rpdev: rpdev reference, only used for primary endpoints
+ * @ept:   rpmsg endpoint this channel is associated with
+ * @glink: qcom_glink context handle
+ * @refcount:  refcount for the channel object
+ * @recv_lock: guard for @ept.cb
+ * @name: