summaryrefslogtreecommitdiffstats
path: root/meta-egvirt/recipes-kernel/linux/linux-yocto/virtio-scmi/0005-firmware-arm_scmi-Add-xfer_init_buffers-transport-op.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-egvirt/recipes-kernel/linux/linux-yocto/virtio-scmi/0005-firmware-arm_scmi-Add-xfer_init_buffers-transport-op.patch')
-rw-r--r--meta-egvirt/recipes-kernel/linux/linux-yocto/virtio-scmi/0005-firmware-arm_scmi-Add-xfer_init_buffers-transport-op.patch79
1 files changed, 79 insertions, 0 deletions
diff --git a/meta-egvirt/recipes-kernel/linux/linux-yocto/virtio-scmi/0005-firmware-arm_scmi-Add-xfer_init_buffers-transport-op.patch b/meta-egvirt/recipes-kernel/linux/linux-yocto/virtio-scmi/0005-firmware-arm_scmi-Add-xfer_init_buffers-transport-op.patch
new file mode 100644
index 00000000..e62e5c50
--- /dev/null
+++ b/meta-egvirt/recipes-kernel/linux/linux-yocto/virtio-scmi/0005-firmware-arm_scmi-Add-xfer_init_buffers-transport-op.patch
@@ -0,0 +1,79 @@
+From fddb9bcd706ed3bb262f4f37707616dd06c7a4cc Mon Sep 17 00:00:00 2001
+From: Igor Skalkin <igor.skalkin@opensynergy.com>
+Date: Thu, 5 Nov 2020 22:21:11 +0100
+Subject: [PATCH] firmware: arm_scmi: Add xfer_init_buffers transport op
+
+The virtio transport in this patch series can be simplified by using the
+scmi_xfer tx/rx buffers for data exchange with the virtio device, and
+for saving the message state. But the virtio transport requires
+prepending a transport-specific header. Also, for data exchange using
+virtqueues, the tx and rx buffers should not overlap.
+
+After the previous patch, this is the second and final step to enable
+the virtio transport to use the scmi_xfer buffers for data exchange.
+
+Add an optional op through which the transport can allocate the tx/rx
+buffers along with room for the prepended transport-specific headers.
+
+Co-developed-by: Peter Hilber <peter.hilber@opensynergy.com>
+Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
+Signed-off-by: Igor Skalkin <igor.skalkin@opensynergy.com>
+Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
+---
+ drivers/firmware/arm_scmi/common.h | 3 +++
+ drivers/firmware/arm_scmi/driver.c | 21 +++++++++++++++------
+ 2 files changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index c998ec29018e..ae5db602e45d 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -208,6 +208,7 @@ struct scmi_chan_info {
+ * @get_max_msg: Optional callback to provide max_msg dynamically
+ * @max_msg: Maximum number of messages for the channel type (tx or rx)
+ * that can be pending simultaneously in the system
++ * @xfer_init_buffers: Callback to initialize buffers for scmi_xfer
+ * @send_message: Callback to send a message
+ * @mark_txdone: Callback to mark tx as done
+ * @fetch_response: Callback to fetch response
+@@ -222,6 +223,8 @@ struct scmi_transport_ops {
+ int (*chan_free)(int id, void *p, void *data);
+ int (*get_max_msg)(bool tx, struct scmi_chan_info *base_cinfo,
+ int *max_msg);
++ int (*xfer_init_buffers)(struct scmi_chan_info *cinfo,
++ struct scmi_xfer *xfer, int max_msg_size);
+ int (*send_message)(struct scmi_chan_info *cinfo,
+ struct scmi_xfer *xfer);
+ void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 5baa23789a49..27dd43dcff5b 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -640,12 +640,21 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
+
+ /* Pre-initialize the buffer pointer to pre-allocated buffers */
+ for (i = 0, xfer = info->xfer_block; i < info->max_msg; i++, xfer++) {
+- xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size,
+- GFP_KERNEL);
+- if (!xfer->rx.buf)
+- return -ENOMEM;
+-
+- xfer->tx.buf = xfer->rx.buf;
++ if (desc->ops->xfer_init_buffers) {
++ int ret = desc->ops->xfer_init_buffers(
++ base_cinfo, xfer, desc->max_msg_size);
++
++ if (ret)
++ return ret;
++ } else {
++ xfer->rx.buf = devm_kcalloc(dev, sizeof(u8),
++ desc->max_msg_size,
++ GFP_KERNEL);
++ if (!xfer->rx.buf)
++ return -ENOMEM;
++
++ xfer->tx.buf = xfer->rx.buf;
++ }
+ init_completion(&xfer->done);
+ }
+