lkml.org 
[lkml]   [2018]   [Jul]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
SubjectFwd: [linux-sunxi] Re: [PATCH v2 2/3] mailbox: introduce ARM SMC based mailbox
<div dir="ltr"><br><div class="gmail_quote"><div>Added missing maintainers from the previous reply</div><div><br></div><div dir="ltr">On Sunday, 23 July 2017 16:26:55 UTC-7, Andre Przywara  wrote:<blockquote class="gmail_quote" style="margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">This mailbox driver implements a mailbox which signals transmitted data
<br>via an ARM smc (secure monitor call) instruction. The mailbox receiver
<br>is implemented in firmware and can synchronously return data when it
<br>returns execution to the non-secure world again.
<br>An asynchronous receive path is not implemented.
<br>This allows the usage of a mailbox to trigger firmware actions on SoCs
<br>which either don&#39;t have a separate management processor or on which such
<br>a core is not available. A user of this mailbox could be the SCP
<br>interface.
<br>
<br>Signed-off-by: Andre Przywara &lt;<a rel="nofollow">andre.p...@arm.com</a>&gt;
<br>---
<br> drivers/mailbox/Kconfig           |   8 ++
<br> drivers/mailbox/Makefile          |   2 +
<br> drivers/mailbox/arm-smc-mailb<wbr>ox.c | 155 ++++++++++++++++++++++++++++++<wbr>++++++++
<br> 3 files changed, 165 insertions(+)
<br> create mode 100644 drivers/mailbox/arm-smc-mailbo<wbr>x.c
<br>
<br>diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
<br>index c5731e5..5664b7f 100644
<br>--- a/drivers/mailbox/Kconfig
<br>+++ b/drivers/mailbox/Kconfig
<br>@@ -170,4 +170,12 @@ config BCM_FLEXRM_MBOX
<br>           Mailbox implementation of the Broadcom FlexRM ring manager,
<br>           which provides access to various offload engines on Broadcom
<br>           SoCs. Say Y here if you want to use the Broadcom FlexRM.
<br>+
<br>+config ARM_SMC_MBOX
<br>+        tristate &quot;Generic ARM smc mailbox&quot;
<br>+        depends on OF &amp;&amp; HAVE_ARM_SMCCC
<br>+        help
<br>+          Generic mailbox driver which uses ARM smc calls to call into
<br>+          firmware for triggering mailboxes.
<br>+
<br> endif
<br>diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
<br>index d54e412..8ec6869 100644
<br>--- a/drivers/mailbox/Makefile
<br>+++ b/drivers/mailbox/Makefile
<br>@@ -35,3 +35,5 @@ obj-$(CONFIG_BCM_FLEXRM_MBOX) <wbr>       += bcm-flexrm-mailbox.o
<br> obj-$(CONFIG_QCOM_APCS_IPC)  <wbr>      += qcom-apcs-ipc-mailbox.o
<br> 
<br> obj-$(CONFIG_TEGRA_HSP_MBOX) <wbr>       += tegra-hsp.o
<br>+
<br>+obj-$(CONFIG_ARM_SMC_MBOX)   <wbr>     += arm-smc-mailbox.o
<br>diff --git a/drivers/mailbox/arm-smc-mail<wbr>box.c b/drivers/mailbox/arm-smc-mail<wbr>box.c
<br>new file mode 100644
<br>index 0000000..d7b61a7
<br>--- /dev/null
<br>+++ b/drivers/mailbox/arm-smc-mail<wbr>box.c
<br>@@ -0,0 +1,155 @@
<br>+/*
<br>+ *  Copyright (C) 2016,2017 ARM Ltd.
<br>+ *
<br>+ * This program is free software; you can redistribute it and/or modify
<br>+ * it under the terms of the GNU General Public License version 2 as
<br>+ * published by the Free Software Foundation.
<br>+ *
<br>+ * This device provides a mechanism for emulating a mailbox by using
<br>+ * smc calls, allowing a &quot;mailbox&quot; consumer to sit in firmware running
<br>+ * on the same core.
<br>+ */
<br>+
<br>+#include &lt;linux/device.h&gt;
<br>+#include &lt;linux/kernel.h&gt;
<br>+#include &lt;linux/mailbox_controller.h&gt;
<br>+#include &lt;linux/module.h&gt;
<br>+#include &lt;linux/platform_device.h&gt;
<br>+#include &lt;linux/arm-smccc.h&gt;
<br>+
<br>+#define ARM_SMC_MBOX_USE_HVC        BI<wbr>T(0)
<br>+
<br>+struct arm_smc_chan_data {
<br>+        u32 function_id;
<br>+        u32 flags;
<br>+};
<br>+
<br>+static int arm_smc_send_data(struct mbox_chan *link, void *data)
<br>+{
<br>+        struct arm_smc_chan_data *chan_data = link-&gt;con_priv;
<br>+        u32 function_id = chan_data-&gt;function_id;
<br>+        struct arm_smccc_res res;
<br>+        u32 msg = *(u32 *)data;
<br>+
<br>+        if (chan_data-&gt;flags &amp; ARM_SMC_MBOX_USE_HVC)
<br>+                arm_smccc_hvc<wbr>(function_id, msg, 0, 0, 0, 0, 0, 0, &amp;res);
<br>+        else
<br>+                arm_smccc_smc<wbr>(function_id, msg, 0, 0, 0, 0, 0, 0, &amp;res);
<br>+
<br>+        mbox_chan_received_da<wbr>ta(link, (void *)res.a0);
<br>+
<br>+        return 0;
<br>+}
<br></blockquote><div><div>We have a use case that the message to post to the mailbox is larger</div><div>than 32bit. Can we change the SMC request to take the pointer as the</div><div>message argument instead of the the value?</div><div>But in this case, I am not clear on how the ATF to validate if the pointer</div><div>is valid. Any suggestions?</div><div><br></div><div>Furthermore, the received response can be larger that smc response</div><div>a0, any suggestion to solve this issue? reuse the input data pointer for</div><div>ATF to write copy the response data?<br></div><div><br></div><div>In case of asynchronous request, the request can be from remote first.</div><div>How to solve this issue to use a generic SMC mailbox driver?</div><div>Use mailbox mbox_send_message() for a separate rx request channel?<br></div><div><br></div><div>Thanks,</div><div>Wendy<br></div><br></div><blockquote class="gmail_quote" style="margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">+
<br>+/* This mailbox is synchronous, so we are always done. */
<br>+static bool arm_smc_last_tx_done(struct mbox_chan *link)
<br>+{
<br>+        return true;
<br>+}
<br>+
<br>+static const struct mbox_chan_ops arm_smc_mbox_chan_ops = {
<br>+        .send_data        = arm_smc_send_data,
<br>+        .last_tx_done        <wbr>= arm_smc_last_tx_done
<br>+};
<br>+
<br>+static int arm_smc_mbox_probe(struct platform_device *pdev)
<br>+{
<br>+        struct device *dev = &amp;pdev-&gt;dev;
<br>+        struct mbox_controller *mbox;
<br>+        struct arm_smc_chan_data *chan_data;
<br>+        const char *method;
<br>+        bool use_hvc = false;
<br>+        int ret, i;
<br>+
<br>+        ret = of_property_count_elems_of_siz<wbr>e(dev-&gt;of_node, &quot;arm,func-ids&quot;,
<br>+                             <wbr>                 sizeof(u32));
<br>+        if (ret &lt; 0)
<br>+                return ret;
<br>+
<br>+        if (!of_property_read_string(dev-<wbr>&gt;of_node, &quot;method&quot;, &amp;method)) {
<br>+                if (!strcmp(&quot;hvc&quot;, method)) {
<br>+                        use_h<wbr>vc = true;
<br>+                } else if (!strcmp(&quot;smc&quot;, method)) {
<br>+                        use_h<wbr>vc = false;
<br>+                } else {
<br>+                        dev_w<wbr>arn(dev, &quot;invalid \&quot;method\&quot; property: %s\n&quot;,
<br>+                             <wbr>    method);
<br>+
<br>+                        retur<wbr>n -EINVAL;
<br>+                }
<br>+        }
<br>+
<br>+        mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
<br>+        if (!mbox)
<br>+                return -ENOMEM;
<br>+
<br>+        mbox-&gt;num_chans = ret;
<br>+        mbox-&gt;chans = devm_kcalloc(dev, mbox-&gt;num_chans, sizeof(*mbox-&gt;chans),
<br>+                             <wbr>      GFP_KERNEL);
<br>+        if (!mbox-&gt;chans)
<br>+                return -ENOMEM;
<br>+
<br>+        chan_data = devm_kcalloc(dev, mbox-&gt;num_chans, sizeof(*chan_data),
<br>+                             <wbr>    GFP_KERNEL);
<br>+        if (!chan_data)
<br>+                return -ENOMEM;
<br>+
<br>+        for (i = 0; i &lt; mbox-&gt;num_chans; i++) {
<br>+                u32 function_id;
<br>+
<br>+                ret = of_property_read_u32_index(dev<wbr>-&gt;of_node,
<br>+                             <wbr>                    &quot;arm,func-ids&quot;, i,
<br>+                             <wbr>                    &amp;function_id);
<br>+                if (ret)
<br>+                        retur<wbr>n ret;
<br>+
<br>+                chan_data[i].<wbr>function_id = function_id;
<br>+                if (use_hvc)
<br>+                        chan_<wbr>data[i].flags |= ARM_SMC_MBOX_USE_HVC;
<br>+                mbox-&gt;chans[i<wbr>].con_priv = &amp;chan_data[i];
<br>+        }
<br>+
<br>+        mbox-&gt;txdone_poll = true;
<br>+        mbox-&gt;txdone_irq = false;
<br>+        mbox-&gt;txpoll_period = 1;
<br>+        mbox-&gt;ops = &amp;arm_smc_mbox_chan_ops;
<br>+        mbox-&gt;dev = dev;
<br>+
<br>+        ret = mbox_controller_register(mbox)<wbr>;
<br>+        if (ret)
<br>+                return ret;
<br>+
<br>+        platform_set_drvdata(<wbr>pdev, mbox);
<br>+        dev_info(dev, &quot;ARM SMC mailbox enabled with %d chan%s.\n&quot;,
<br>+                 mbox-&gt;num_chans, mbox-&gt;num_chans == 1 ? &quot;&quot; : &quot;s&quot;);
<br>+
<br>+        return ret;
<br>+}
<br>+
<br>+static int arm_smc_mbox_remove(struct platform_device *pdev)
<br>+{
<br>+        struct mbox_controller *mbox = platform_get_drvdata(pdev);
<br>+
<br>+        mbox_controller_unreg<wbr>ister(mbox);
<br>+        return 0;
<br>+}
<br>+
<br>+static const struct of_device_id arm_smc_mbox_of_match[] = {
<br>+        { .compatible = &quot;arm,smc-mbox&quot;, },
<br>+        {},
<br>+};
<br>+MODULE_DEVICE_TABLE(of, arm_smc_mbox_of_match);
<br>+
<br>+static struct platform_driver arm_smc_mbox_driver = {
<br>+        .driver = {
<br>+                .name = &quot;arm-smc-mbox&quot;,
<br>+                .of_match_tab<wbr>le = arm_smc_mbox_of_match,
<br>+        },
<br>+        .probe               <wbr> = arm_smc_mbox_probe,
<br>+        .remove              <wbr>  = arm_smc_mbox_remove,
<br>+};
<br>+module_platform_driver(arm_sm<wbr>c_mbox_driver);
<br>+
<br>+MODULE_AUTHOR(&quot;Andre Przywara &lt;<a rel="nofollow">andre.p...@arm.com</a>&gt;&quot;);
<br>+MODULE_DESCRIPTION(&quot;Generic ARM smc mailbox driver&quot;);
<br>+MODULE_LICENSE(&quot;GPL v2&quot;);
<br><span class="HOEnZb"><font color="#888888">--
<br>2.8.2
<br>
<br></font></span></blockquote></div><span class="HOEnZb"><font color="#888888">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &quot;linux-sunxi&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:linux-sunxi+unsubscribe@googlegroups.com" target="_blank">linux-sunxi+unsubscribe@<wbr>googlegroups.com</a>.<br>
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank">https://groups.google.com/d/<wbr>optout</a>.<br>
</font></span></div><br></div>
\
 
 \ /
  Last update: 2018-08-01 01:44    [W:0.141 / U:0.840 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site