diff mbox

[RFC,24/31] xen/arm: Add Xen changes to ARM SMC based mailbox

Message ID 1510247421-24094-25-git-send-email-olekstysh@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Oleksandr Tyshchenko Nov. 9, 2017, 5:10 p.m. UTC
From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>

Modify the direct ported ARM SMC based mailbox to be
functional inside Xen.

Include "wrappers.h" which contains all required things the direct
ported code relies on.

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien.grall@linaro.org>
CC: Andre Przywara <andre.przywara@linaro.org>
---
 xen/arch/arm/cpufreq/arm-smc-mailbox.c | 101 +++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)
diff mbox

Patch

diff --git a/xen/arch/arm/cpufreq/arm-smc-mailbox.c b/xen/arch/arm/cpufreq/arm-smc-mailbox.c
index d7b61a7..65d183e 100644
--- a/xen/arch/arm/cpufreq/arm-smc-mailbox.c
+++ b/xen/arch/arm/cpufreq/arm-smc-mailbox.c
@@ -8,14 +8,73 @@ 
  * This device provides a mechanism for emulating a mailbox by using
  * smc calls, allowing a "mailbox" consumer to sit in firmware running
  * on the same core.
+ *
+ * Based on patch series which hasn't reach upstream yet:
+ * => https://lkml.org/lkml/2017/7/23/129
+ *    [PATCH v2 0/3] mailbox: arm: introduce smc triggered mailbox
+ *
+ * Xen modification:
+ * Oleksandr Tyshchenko <Oleksandr_Tyshchenko@epam.com>
+ * Copyright (C) 2017 EPAM Systems Inc.
  */
 
+#if 0
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/arm-smccc.h>
+#endif
+
+#include <xen/device_tree.h>
+#include <xen/err.h>
+#include <xen/xmalloc.h>
+
+#include "mailbox_controller.h"
+#include "wrappers.h"
+
+/*
+ * TODO:
+ * 1. Add releasing resources since devm.
+ */
+
+struct arm_smccc_res {
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+};
+
+/* This is just to align interfaces. */
+static inline void arm_smccc_smc(unsigned long a0, unsigned long a1,
+		unsigned long a2, unsigned long a3, unsigned long a4,
+		unsigned long a5, unsigned long a6, unsigned long a7,
+		struct arm_smccc_res *res)
+{
+	register_t ret[4] = { 0 };
+
+	call_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, ret);
+
+	res->a0 = ret[0];
+	res->a1 = ret[1];
+	res->a2 = ret[2];
+	res->a3 = ret[3];
+}
+
+static inline void arm_smccc_hvc(unsigned long a0, unsigned long a1,
+		unsigned long a2, unsigned long a3, unsigned long a4,
+		unsigned long a5, unsigned long a6, unsigned long a7,
+		struct arm_smccc_res *res)
+{
+	/*
+	 * We should never get here since the "use_hvc" flag is always false
+	 * (smc is only allowed method).
+	*/
+	BUG();
+}
+
+/***** Start of Linux code *****/
 
 #define ARM_SMC_MBOX_USE_HVC	BIT(0)
 
@@ -69,6 +128,9 @@  static int arm_smc_mbox_probe(struct platform_device *pdev)
 	if (!of_property_read_string(dev->of_node, "method", &method)) {
 		if (!strcmp("hvc", method)) {
 			use_hvc = true;
+
+			dev_warn(dev,"method must be smc\n");
+			return -EINVAL;
 		} else if (!strcmp("smc", method)) {
 			use_hvc = false;
 		} else {
@@ -112,6 +174,11 @@  static int arm_smc_mbox_probe(struct platform_device *pdev)
 	mbox->txdone_poll = true;
 	mbox->txdone_irq = false;
 	mbox->txpoll_period = 1;
+	/*
+	 * We don't have RX-done irq, but always have received data in hand since
+	 * mailbox is synchronous.
+	 */
+	mbox->rxdone_auto = true;
 	mbox->ops = &arm_smc_mbox_chan_ops;
 	mbox->dev = dev;
 
@@ -126,6 +193,7 @@  static int arm_smc_mbox_probe(struct platform_device *pdev)
 	return ret;
 }
 
+#if 0
 static int arm_smc_mbox_remove(struct platform_device *pdev)
 {
 	struct mbox_controller *mbox = platform_get_drvdata(pdev);
@@ -133,6 +201,7 @@  static int arm_smc_mbox_remove(struct platform_device *pdev)
 	mbox_controller_unregister(mbox);
 	return 0;
 }
+#endif
 
 static const struct of_device_id arm_smc_mbox_of_match[] = {
 	{ .compatible = "arm,smc-mbox", },
@@ -140,6 +209,7 @@  static const struct of_device_id arm_smc_mbox_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smc_mbox_of_match);
 
+#if 0
 static struct platform_driver arm_smc_mbox_driver = {
 	.driver = {
 		.name = "arm-smc-mbox",
@@ -153,3 +223,34 @@  module_platform_driver(arm_smc_mbox_driver);
 MODULE_AUTHOR("Andre Przywara <andre.przywara@arm.com>");
 MODULE_DESCRIPTION("Generic ARM smc mailbox driver");
 MODULE_LICENSE("GPL v2");
+#endif
+
+/***** End of Linux code *****/
+
+static int __init arm_smc_mbox_init(struct dt_device_node *dev,
+		const void *data)
+{
+	int ret;
+
+	ret = arm_smc_mbox_probe(dev);
+	if (ret) {
+		dev_err(&dev->dev, "failed to init ARM SMC mailbox (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+DT_DEVICE_START(arm_smc_mbox, "ARM SMC mailbox", DEVICE_MAILBOX)
+	.dt_match = arm_smc_mbox_of_match,
+	.init = arm_smc_mbox_init,
+DT_DEVICE_END
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 8
+ * indent-tabs-mode: t
+ * End:
+ */