All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sudeep Holla <sudeep.holla@arm.com>
To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
Cc: Sudeep Holla <sudeep.holla@arm.com>,
	kernel-team@android.com, Will Deacon <will@kernel.org>,
	tsoni@quicinc.com, pratikp@quicinc.com
Subject: [PATCH 5/9] firmware: arm_ffa: Add initial FFA bus support for device enumeration
Date: Sat, 29 Aug 2020 18:09:19 +0100	[thread overview]
Message-ID: <20200829170923.29949-6-sudeep.holla@arm.com> (raw)
In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com>

The Arm FF for Armv8-A specification has concept of endpoints or
partitions. In the Normal world, a partition could be a VM when
the Virtualization extension is enabled or the kernel itself.

In order to handle multiple partitions, we can create a FFA device for
each partition on a dedicated FFA bus. Similarly, different drivers
requiring FFA transport can be registered on the same bus. We can match
the device and drivers using UUID. This is mostly for the in-kernel
users with FFA drivers.

However, to support usage of FFA transport from user-space, there is also
a provision to create character device interface for the same.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/firmware/Kconfig          |   1 +
 drivers/firmware/Makefile         |   1 +
 drivers/firmware/arm_ffa/Kconfig  |  16 +++
 drivers/firmware/arm_ffa/Makefile |   3 +
 drivers/firmware/arm_ffa/bus.c    | 193 ++++++++++++++++++++++++++++++
 include/linux/arm_ffa.h           |  81 +++++++++++++
 6 files changed, 295 insertions(+)
 create mode 100644 drivers/firmware/arm_ffa/Kconfig
 create mode 100644 drivers/firmware/arm_ffa/Makefile
 create mode 100644 drivers/firmware/arm_ffa/bus.c
 create mode 100644 include/linux/arm_ffa.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index fbd785dd0513..8660014e9ec7 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -296,6 +296,7 @@ config TURRIS_MOX_RWTM
 	  other manufacturing data and also utilize the Entropy Bit Generator
 	  for hardware random number generation.
 
+source "drivers/firmware/arm_ffa/Kconfig"
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 99510be9f5ed..cd990d411f89 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TI_SCI_PROTOCOL)	+= ti_sci.o
 obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
 obj-$(CONFIG_TURRIS_MOX_RWTM)	+= turris-mox-rwtm.o
 
+obj-y				+= arm_ffa/
 obj-$(CONFIG_ARM_SCMI_PROTOCOL)	+= arm_scmi/
 obj-y				+= broadcom/
 obj-y				+= meson/
diff --git a/drivers/firmware/arm_ffa/Kconfig b/drivers/firmware/arm_ffa/Kconfig
new file mode 100644
index 000000000000..261a3660650a
--- /dev/null
+++ b/drivers/firmware/arm_ffa/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config ARM_FFA_TRANSPORT
+	tristate "Arm Firmware Framework for Armv8-A"
+	depends on OF
+	depends on ARM64
+	default n
+	help
+	  This Firmware Framework(FF) for Arm A-profile processors describes
+	  interfaces that standardize communication between the various
+	  software images which includes communication between images in
+	  the Secure world and Normal world. It also leverages the
+	  virtualization extension to isolate software images provided
+	  by an ecosystem of vendors from each other.
+
+	  This driver provides interface for all the client drivers making
+	  use of the features offered by ARM FF-A.
diff --git a/drivers/firmware/arm_ffa/Makefile b/drivers/firmware/arm_ffa/Makefile
new file mode 100644
index 000000000000..fadb325ee888
--- /dev/null
+++ b/drivers/firmware/arm_ffa/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-bus.o
+ffa-bus-y = bus.o
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
new file mode 100644
index 000000000000..b5789bd4dfcd
--- /dev/null
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm_ffa.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define DEVICE_NAME "arm_ffa"
+#define FFA_MAX_CDEVS	32
+
+static DEFINE_IDA(ffa_dev_id);
+static dev_t ffa_devt;
+
+static int ffa_device_match(struct device *dev, struct device_driver *drv)
+{
+	const struct ffa_device_id *id_table;
+	struct ffa_device *ffa_dev;
+
+	id_table = to_ffa_driver(drv)->id_table;
+	ffa_dev = to_ffa_dev(dev);
+
+	while (!uuid_is_null(&id_table->uuid)) {
+		if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
+			return 1;
+		id_table++;
+	}
+
+	return 0;
+}
+
+static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	uuid_t *dev_id = &to_ffa_dev(dev)->uuid;
+
+	return add_uevent_var(env, "MODALIAS=arm_ffa:%pUb", dev_id);
+}
+
+struct bus_type ffa_bus_type = {
+	.name		= "arm_ffa",
+	.match		= ffa_device_match,
+	.uevent		= ffa_device_uevent,
+};
+EXPORT_SYMBOL_GPL(ffa_bus_type);
+
+int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+			const char *mod_name)
+{
+	int ret;
+
+	driver->driver.bus = &ffa_bus_type;
+	driver->driver.name = driver->name;
+	driver->driver.owner = owner;
+	driver->driver.mod_name = mod_name;
+
+	ret = driver_register(&driver->driver);
+	if (!ret)
+		pr_debug("registered new ffa driver %s\n", driver->name);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ffa_driver_register);
+
+void ffa_driver_unregister(struct ffa_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(ffa_driver_unregister);
+
+static void ffa_release_device(struct device *dev)
+{
+	struct ffa_device *ffa_dev = to_ffa_dev(dev);
+
+	kfree(ffa_dev);
+}
+
+static int __ffa_devices_unregister(struct device *dev, void *data)
+{
+	ffa_release_device(dev);
+
+	return 0;
+}
+
+static void ffa_devices_unregister(void)
+{
+	bus_for_each_dev(&ffa_bus_type, NULL, NULL,
+			 __ffa_devices_unregister);
+}
+
+static char *
+ffa_devnode(struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid)
+{
+	return kasprintf(GFP_KERNEL, DEVICE_NAME "/%s", dev_name(dev));
+}
+
+static struct device_type ffa_dev_type = {
+	.devnode = ffa_devnode,
+};
+
+int ffa_device_register(struct ffa_device *ffa_dev)
+{
+	int ret;
+	struct cdev *cdev;
+	struct device *dev;
+
+	if (!ffa_dev)
+		return -EINVAL;
+
+	dev = &ffa_dev->dev;
+	cdev = &ffa_dev->cdev;
+
+	dev->bus = &ffa_bus_type;
+	dev->type = &ffa_dev_type;
+	dev->release = ffa_release_device;
+
+	device_initialize(dev);
+
+	if (cdev->ops) {
+		ret = ida_simple_get(&ffa_dev_id, 0, FFA_MAX_CDEVS, GFP_KERNEL);
+		if (ret < 0) {
+			put_device(dev);
+			return ret;
+		}
+
+		dev->devt = MKDEV(MAJOR(ffa_devt), ret);
+
+		cdev->owner = cdev->ops->owner;
+	}
+
+	ret = cdev_device_add(cdev, dev);
+	if (ret) {
+		dev_err(dev, "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
+			dev_name(dev), MAJOR(dev->devt), MINOR(dev->devt),
+			ret);
+		put_device(dev);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ffa_device_register);
+
+void ffa_device_unregister(struct ffa_device *ffa_dev)
+{
+	if (!ffa_dev)
+		return;
+
+	cdev_device_del(&ffa_dev->cdev, &ffa_dev->dev);
+
+	put_device(&ffa_dev->dev);
+}
+EXPORT_SYMBOL_GPL(ffa_device_unregister);
+
+static int __init arm_ffa_bus_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&ffa_devt, 0, FFA_MAX_CDEVS, DEVICE_NAME);
+	if (ret) {
+		pr_err("failed to allocate char dev region\n");
+		return ret;
+	}
+
+	ret = bus_register(&ffa_bus_type);
+	if (ret) {
+		pr_err("ffa bus register failed (%d)\n", ret);
+		unregister_chrdev_region(ffa_devt, FFA_MAX_CDEVS);
+	}
+
+	return ret;
+}
+subsys_initcall(arm_ffa_bus_init);
+
+static void __exit arm_ffa_bus_exit(void)
+{
+	ffa_devices_unregister();
+	bus_unregister(&ffa_bus_type);
+	unregister_chrdev_region(ffa_devt, FFA_MAX_CDEVS);
+}
+
+module_exit(arm_ffa_bus_exit);
+
+MODULE_ALIAS("arm-ffa-bus");
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("Arm FF-A bus driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
new file mode 100644
index 000000000000..2fe16176149f
--- /dev/null
+++ b/include/linux/arm_ffa.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+
+#ifndef _LINUX_ARM_FFA_H
+#define _LINUX_ARM_FFA_H
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+struct ffa_device {
+	u32 vm_id;
+	uuid_t uuid;
+	struct device dev;
+	struct cdev cdev;
+};
+
+#define to_ffa_dev(d) container_of(d, struct ffa_device, dev)
+
+struct ffa_device_id {
+	uuid_t uuid;
+};
+
+struct ffa_driver {
+	const char *name;
+	int (*probe)(struct ffa_device *sdev);
+	void (*remove)(struct ffa_device *sdev);
+	const struct ffa_device_id *id_table;
+
+	struct device_driver driver;
+};
+
+#define to_ffa_driver(d) container_of(d, struct ffa_driver, driver)
+
+#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
+int ffa_device_register(struct ffa_device *ffa_dev);
+void ffa_device_unregister(struct ffa_device *ffa_dev);
+int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+			const char *mod_name);
+void ffa_driver_unregister(struct ffa_driver *driver);
+
+#else
+static inline int ffa_device_register(struct ffa_device *ffa_dev)
+{
+	return -EINVAL;
+}
+
+static inline void ffa_device_unregister(struct ffa_device *dev) {}
+
+static inline int
+ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+		    const char *mod_name)
+{
+	return -EINVAL;
+}
+
+static inline void ffa_driver_unregister(struct ffa_driver *driver) {}
+
+#endif /* CONFIG_ARM_FFA_TRANSPORT */
+
+#define ffa_register(driver) \
+	ffa_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+#define ffa_unregister(driver) \
+	ffa_driver_unregister(driver)
+
+/**
+ * module_ffa_driver() - Helper macro for registering a psa_ffa driver
+ * @__ffa_driver: ffa_driver structure
+ *
+ * Helper macro for psa_ffa drivers to set up proper module init / exit
+ * functions.  Replaces module_init() and module_exit() and keeps people from
+ * printing pointless things to the kernel log when their driver is loaded.
+ */
+#define module_ffa_driver(__ffa_driver)	\
+	module_driver(__ffa_driver, ffa_register, ffa_unregister)
+
+#endif /* _LINUX_ARM_FFA_H */
-- 
2.17.1


WARNING: multiple messages have this Message-ID (diff)
From: Sudeep Holla <sudeep.holla@arm.com>
To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
Cc: Will Deacon <will@kernel.org>,
	pratikp@quicinc.com, tsoni@quicinc.com, kernel-team@android.com,
	Sudeep Holla <sudeep.holla@arm.com>
Subject: [PATCH 5/9] firmware: arm_ffa: Add initial FFA bus support for device enumeration
Date: Sat, 29 Aug 2020 18:09:19 +0100	[thread overview]
Message-ID: <20200829170923.29949-6-sudeep.holla@arm.com> (raw)
In-Reply-To: <20200829170923.29949-1-sudeep.holla@arm.com>

The Arm FF for Armv8-A specification has concept of endpoints or
partitions. In the Normal world, a partition could be a VM when
the Virtualization extension is enabled or the kernel itself.

In order to handle multiple partitions, we can create a FFA device for
each partition on a dedicated FFA bus. Similarly, different drivers
requiring FFA transport can be registered on the same bus. We can match
the device and drivers using UUID. This is mostly for the in-kernel
users with FFA drivers.

However, to support usage of FFA transport from user-space, there is also
a provision to create character device interface for the same.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/firmware/Kconfig          |   1 +
 drivers/firmware/Makefile         |   1 +
 drivers/firmware/arm_ffa/Kconfig  |  16 +++
 drivers/firmware/arm_ffa/Makefile |   3 +
 drivers/firmware/arm_ffa/bus.c    | 193 ++++++++++++++++++++++++++++++
 include/linux/arm_ffa.h           |  81 +++++++++++++
 6 files changed, 295 insertions(+)
 create mode 100644 drivers/firmware/arm_ffa/Kconfig
 create mode 100644 drivers/firmware/arm_ffa/Makefile
 create mode 100644 drivers/firmware/arm_ffa/bus.c
 create mode 100644 include/linux/arm_ffa.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index fbd785dd0513..8660014e9ec7 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -296,6 +296,7 @@ config TURRIS_MOX_RWTM
 	  other manufacturing data and also utilize the Entropy Bit Generator
 	  for hardware random number generation.
 
+source "drivers/firmware/arm_ffa/Kconfig"
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 99510be9f5ed..cd990d411f89 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TI_SCI_PROTOCOL)	+= ti_sci.o
 obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
 obj-$(CONFIG_TURRIS_MOX_RWTM)	+= turris-mox-rwtm.o
 
+obj-y				+= arm_ffa/
 obj-$(CONFIG_ARM_SCMI_PROTOCOL)	+= arm_scmi/
 obj-y				+= broadcom/
 obj-y				+= meson/
diff --git a/drivers/firmware/arm_ffa/Kconfig b/drivers/firmware/arm_ffa/Kconfig
new file mode 100644
index 000000000000..261a3660650a
--- /dev/null
+++ b/drivers/firmware/arm_ffa/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config ARM_FFA_TRANSPORT
+	tristate "Arm Firmware Framework for Armv8-A"
+	depends on OF
+	depends on ARM64
+	default n
+	help
+	  This Firmware Framework(FF) for Arm A-profile processors describes
+	  interfaces that standardize communication between the various
+	  software images which includes communication between images in
+	  the Secure world and Normal world. It also leverages the
+	  virtualization extension to isolate software images provided
+	  by an ecosystem of vendors from each other.
+
+	  This driver provides interface for all the client drivers making
+	  use of the features offered by ARM FF-A.
diff --git a/drivers/firmware/arm_ffa/Makefile b/drivers/firmware/arm_ffa/Makefile
new file mode 100644
index 000000000000..fadb325ee888
--- /dev/null
+++ b/drivers/firmware/arm_ffa/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-bus.o
+ffa-bus-y = bus.o
diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
new file mode 100644
index 000000000000..b5789bd4dfcd
--- /dev/null
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm_ffa.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define DEVICE_NAME "arm_ffa"
+#define FFA_MAX_CDEVS	32
+
+static DEFINE_IDA(ffa_dev_id);
+static dev_t ffa_devt;
+
+static int ffa_device_match(struct device *dev, struct device_driver *drv)
+{
+	const struct ffa_device_id *id_table;
+	struct ffa_device *ffa_dev;
+
+	id_table = to_ffa_driver(drv)->id_table;
+	ffa_dev = to_ffa_dev(dev);
+
+	while (!uuid_is_null(&id_table->uuid)) {
+		if (uuid_equal(&ffa_dev->uuid, &id_table->uuid))
+			return 1;
+		id_table++;
+	}
+
+	return 0;
+}
+
+static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	uuid_t *dev_id = &to_ffa_dev(dev)->uuid;
+
+	return add_uevent_var(env, "MODALIAS=arm_ffa:%pUb", dev_id);
+}
+
+struct bus_type ffa_bus_type = {
+	.name		= "arm_ffa",
+	.match		= ffa_device_match,
+	.uevent		= ffa_device_uevent,
+};
+EXPORT_SYMBOL_GPL(ffa_bus_type);
+
+int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+			const char *mod_name)
+{
+	int ret;
+
+	driver->driver.bus = &ffa_bus_type;
+	driver->driver.name = driver->name;
+	driver->driver.owner = owner;
+	driver->driver.mod_name = mod_name;
+
+	ret = driver_register(&driver->driver);
+	if (!ret)
+		pr_debug("registered new ffa driver %s\n", driver->name);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ffa_driver_register);
+
+void ffa_driver_unregister(struct ffa_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(ffa_driver_unregister);
+
+static void ffa_release_device(struct device *dev)
+{
+	struct ffa_device *ffa_dev = to_ffa_dev(dev);
+
+	kfree(ffa_dev);
+}
+
+static int __ffa_devices_unregister(struct device *dev, void *data)
+{
+	ffa_release_device(dev);
+
+	return 0;
+}
+
+static void ffa_devices_unregister(void)
+{
+	bus_for_each_dev(&ffa_bus_type, NULL, NULL,
+			 __ffa_devices_unregister);
+}
+
+static char *
+ffa_devnode(struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid)
+{
+	return kasprintf(GFP_KERNEL, DEVICE_NAME "/%s", dev_name(dev));
+}
+
+static struct device_type ffa_dev_type = {
+	.devnode = ffa_devnode,
+};
+
+int ffa_device_register(struct ffa_device *ffa_dev)
+{
+	int ret;
+	struct cdev *cdev;
+	struct device *dev;
+
+	if (!ffa_dev)
+		return -EINVAL;
+
+	dev = &ffa_dev->dev;
+	cdev = &ffa_dev->cdev;
+
+	dev->bus = &ffa_bus_type;
+	dev->type = &ffa_dev_type;
+	dev->release = ffa_release_device;
+
+	device_initialize(dev);
+
+	if (cdev->ops) {
+		ret = ida_simple_get(&ffa_dev_id, 0, FFA_MAX_CDEVS, GFP_KERNEL);
+		if (ret < 0) {
+			put_device(dev);
+			return ret;
+		}
+
+		dev->devt = MKDEV(MAJOR(ffa_devt), ret);
+
+		cdev->owner = cdev->ops->owner;
+	}
+
+	ret = cdev_device_add(cdev, dev);
+	if (ret) {
+		dev_err(dev, "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
+			dev_name(dev), MAJOR(dev->devt), MINOR(dev->devt),
+			ret);
+		put_device(dev);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ffa_device_register);
+
+void ffa_device_unregister(struct ffa_device *ffa_dev)
+{
+	if (!ffa_dev)
+		return;
+
+	cdev_device_del(&ffa_dev->cdev, &ffa_dev->dev);
+
+	put_device(&ffa_dev->dev);
+}
+EXPORT_SYMBOL_GPL(ffa_device_unregister);
+
+static int __init arm_ffa_bus_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&ffa_devt, 0, FFA_MAX_CDEVS, DEVICE_NAME);
+	if (ret) {
+		pr_err("failed to allocate char dev region\n");
+		return ret;
+	}
+
+	ret = bus_register(&ffa_bus_type);
+	if (ret) {
+		pr_err("ffa bus register failed (%d)\n", ret);
+		unregister_chrdev_region(ffa_devt, FFA_MAX_CDEVS);
+	}
+
+	return ret;
+}
+subsys_initcall(arm_ffa_bus_init);
+
+static void __exit arm_ffa_bus_exit(void)
+{
+	ffa_devices_unregister();
+	bus_unregister(&ffa_bus_type);
+	unregister_chrdev_region(ffa_devt, FFA_MAX_CDEVS);
+}
+
+module_exit(arm_ffa_bus_exit);
+
+MODULE_ALIAS("arm-ffa-bus");
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("Arm FF-A bus driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
new file mode 100644
index 000000000000..2fe16176149f
--- /dev/null
+++ b/include/linux/arm_ffa.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+
+#ifndef _LINUX_ARM_FFA_H
+#define _LINUX_ARM_FFA_H
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+struct ffa_device {
+	u32 vm_id;
+	uuid_t uuid;
+	struct device dev;
+	struct cdev cdev;
+};
+
+#define to_ffa_dev(d) container_of(d, struct ffa_device, dev)
+
+struct ffa_device_id {
+	uuid_t uuid;
+};
+
+struct ffa_driver {
+	const char *name;
+	int (*probe)(struct ffa_device *sdev);
+	void (*remove)(struct ffa_device *sdev);
+	const struct ffa_device_id *id_table;
+
+	struct device_driver driver;
+};
+
+#define to_ffa_driver(d) container_of(d, struct ffa_driver, driver)
+
+#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
+int ffa_device_register(struct ffa_device *ffa_dev);
+void ffa_device_unregister(struct ffa_device *ffa_dev);
+int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+			const char *mod_name);
+void ffa_driver_unregister(struct ffa_driver *driver);
+
+#else
+static inline int ffa_device_register(struct ffa_device *ffa_dev)
+{
+	return -EINVAL;
+}
+
+static inline void ffa_device_unregister(struct ffa_device *dev) {}
+
+static inline int
+ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+		    const char *mod_name)
+{
+	return -EINVAL;
+}
+
+static inline void ffa_driver_unregister(struct ffa_driver *driver) {}
+
+#endif /* CONFIG_ARM_FFA_TRANSPORT */
+
+#define ffa_register(driver) \
+	ffa_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+#define ffa_unregister(driver) \
+	ffa_driver_unregister(driver)
+
+/**
+ * module_ffa_driver() - Helper macro for registering a psa_ffa driver
+ * @__ffa_driver: ffa_driver structure
+ *
+ * Helper macro for psa_ffa drivers to set up proper module init / exit
+ * functions.  Replaces module_init() and module_exit() and keeps people from
+ * printing pointless things to the kernel log when their driver is loaded.
+ */
+#define module_ffa_driver(__ffa_driver)	\
+	module_driver(__ffa_driver, ffa_register, ffa_unregister)
+
+#endif /* _LINUX_ARM_FFA_H */
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2020-08-29 17:09 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-29 17:09 [PATCH 0/9] firmware: Add initial support for Arm FF-A Sudeep Holla
2020-08-29 17:09 ` Sudeep Holla
2020-08-29 17:09 ` [PATCH 1/9] dt-bindings: Arm: Add Firmware Framework for Armv8-A (FF-A) binding Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-09-01 16:03   ` Jonathan Cameron
2020-09-01 16:03     ` Jonathan Cameron
2020-09-07 11:40     ` Sudeep Holla
2020-09-07 11:40       ` Sudeep Holla
2020-09-02 22:14   ` Rob Herring
2020-09-02 22:14     ` Rob Herring
2020-11-03 15:59     ` Sudeep Holla
2020-11-03 15:59       ` Sudeep Holla
2020-08-29 17:09 ` [PATCH 2/9] dt-bindings: Arm: Extend FF-A binding to support in-kernel usage of partitions Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-09-02 21:36   ` Rob Herring
2020-09-02 21:36     ` Rob Herring
2020-09-07 11:41     ` Sudeep Holla
2020-09-07 11:41       ` Sudeep Holla
2020-08-29 17:09 ` [PATCH 3/9] arm64: smccc: Add support for SMCCCv1.2 input/output registers Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-08-29 17:09 ` [PATCH 4/9] firmware: smccc: export both smccc functions Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-08-29 17:09 ` Sudeep Holla [this message]
2020-08-29 17:09   ` [PATCH 5/9] firmware: arm_ffa: Add initial FFA bus support for device enumeration Sudeep Holla
2020-08-29 17:09 ` [PATCH 6/9] firmware: arm_ffa: Add initial Arm FFA driver support Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-09-07  7:55   ` Fuad Tabba
2020-09-07  7:55     ` Fuad Tabba
2020-09-07  9:29     ` Sudeep Holla
2020-09-07  9:29       ` Sudeep Holla
2020-08-29 17:09 ` [PATCH 7/9] firmware: arm_ffa: Add support for SMCCC as transport to FFA driver Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-09-01 16:23   ` Jonathan Cameron
2020-09-01 16:23     ` Jonathan Cameron
2020-08-29 17:09 ` [PATCH 8/9] firmware: arm_ffa: Setup and register all the KVM managed partitions Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-09-01 16:34   ` Jonathan Cameron
2020-09-01 16:34     ` Jonathan Cameron
2020-09-07 11:20   ` Achin Gupta
2020-09-07 11:20     ` Achin Gupta
2020-08-29 17:09 ` [PATCH 9/9] firmware: arm_ffa: Setup in-kernel users of FFA partitions Sudeep Holla
2020-08-29 17:09   ` Sudeep Holla
2020-09-01 16:38   ` Jonathan Cameron
2020-09-01 16:38     ` Jonathan Cameron
2020-09-07 11:32   ` Achin Gupta
2020-09-07 11:32     ` Achin Gupta
2020-09-07 12:04     ` Andrew Walbran
2020-09-07 12:04       ` Andrew Walbran

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=20200829170923.29949-6-sudeep.holla@arm.com \
    --to=sudeep.holla@arm.com \
    --cc=devicetree@vger.kernel.org \
    --cc=kernel-team@android.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=pratikp@quicinc.com \
    --cc=tsoni@quicinc.com \
    --cc=will@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.