Inter-revision diff: patch 3

Comparing v3 (message) to v5 (message)

--- v3
+++ v5
@@ -1,143 +1,131 @@
 Implement vas_init() and vas_exit() functions for a new VAS module.
 This VAS module is essentially a library for other device drivers
 and kernel users of the NX coprocessors like NX-842 and NX-GZIP.
+In the future this will be extended to add support for user space
+to access the NX coprocessors.
+
+VAS is currently only supported with 64K page size.
 
 Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
 ---
+Changelog[v5]:
+	- [Ben Herrenschmidt]: Create and use platform device tree nodes,
+	  fix up the "reg" properties for the VAS DT node and use the
+	  platform device helpers to parse the reg properties; Use linked
+	  list of VAS instances (don't assume vasids are sequential);
+	  Use CONFIG_PPC_VAS instead of CONFIG_VAS.
+
+Changelog[v4]:
+	- [Michael Neuling] Fix some accidental deletions; fix help text
+	  in Kconfig; change vas_initialized to a function; move from
+	  drivers/misc to arch/powerpc/kernel
+	- Drop the vas_window_reset() interface. It is not needed as
+	  window will be initialized before each use.
+	- Add a "depends on PPC_64K_PAGES"
+
 Changelog[v3]:
 	- Zero vas_instances memory on allocation
 	- [Haren Myneni] Fix description in Kconfig
 Changelog[v2]:
 	- Get HVWC, UWC and window address parameters from device tree.
 ---
- MAINTAINERS                     |   8 ++-
- arch/powerpc/include/asm/reg.h  |   1 +
- drivers/misc/Kconfig            |   1 +
- drivers/misc/Makefile           |   1 +
- drivers/misc/vas/Kconfig        |  21 ++++++
- drivers/misc/vas/Makefile       |   3 +
- drivers/misc/vas/vas-internal.h |   3 +
- drivers/misc/vas/vas-window.c   |  19 +++++
- drivers/misc/vas/vas.c          | 155 ++++++++++++++++++++++++++++++++++++++++
- 9 files changed, 210 insertions(+), 2 deletions(-)
- create mode 100644 drivers/misc/vas/Kconfig
- create mode 100644 drivers/misc/vas/Makefile
- create mode 100644 drivers/misc/vas/vas-window.c
- create mode 100644 drivers/misc/vas/vas.c
-
+ .../devicetree/bindings/powerpc/ibm,vas.txt        |  24 +++
+ MAINTAINERS                                        |   8 +
+ arch/powerpc/platforms/powernv/Kconfig             |  14 ++
+ arch/powerpc/platforms/powernv/Makefile            |   1 +
+ arch/powerpc/platforms/powernv/vas-window.c        |  19 +++
+ arch/powerpc/platforms/powernv/vas.c               | 183 +++++++++++++++++++++
+ arch/powerpc/platforms/powernv/vas.h               |  10 +-
+ 7 files changed, 257 insertions(+), 2 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/powerpc/ibm,vas.txt
+ create mode 100644 arch/powerpc/platforms/powernv/vas-window.c
+ create mode 100644 arch/powerpc/platforms/powernv/vas.c
+
+diff --git a/Documentation/devicetree/bindings/powerpc/ibm,vas.txt b/Documentation/devicetree/bindings/powerpc/ibm,vas.txt
+new file mode 100644
+index 0000000..8468a3a
+--- /dev/null
++++ b/Documentation/devicetree/bindings/powerpc/ibm,vas.txt
+@@ -0,0 +1,24 @@
++* IBM Powerpc Virtual Accelerator Switchboard (VAS)
++
++VAS is a hardware mechanism that allows ekrnel subsystems and user processes
++to directly submit compression and other requests to Nest accelerators (NX)
++or other coprocessors functions.
++
++Required properties:
++- compatible : should be "ibm,vas" or "ibm,power9-vas"
++- ibm,vas-id : A unique identifier for each instance of VAS in the system
++- reg : Should contain 4 pairs of 64-bit fields specifying the Hypervisor
++  window context start and length, OS/User window context start and length,
++  "Paste address" start and length, "Paste window id" start bit and number
++  of bits)
++- name : "vas"
++
++Example:
++
++	vas@6019100000000 {
++		compatible = "ibm,vas", "ibm,power9-vas";
++		reg = <0x6019100000000 0x2000000 0x6019000000000 0x100000000 0x8000000000000 0x100000000 0x20 0x10>;
++		name = "vas";
++		ibm,vas-id = <0x1>;
++	};
++
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 2a910c9..4037252 100644
+index 9e98464..4c4f05e 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -3673,8 +3673,6 @@ F:	arch/powerpc/platforms/powernv/pci-cxl.c
- F:	drivers/misc/cxl/
- F:	include/misc/cxl*
- F:	include/uapi/misc/cxl.h
--F:	Documentation/powerpc/cxl.txt
--F:	Documentation/ABI/testing/sysfs-class-cxl
+@@ -6331,6 +6331,14 @@ F:	drivers/crypto/nx/nx.*
+ F:	drivers/crypto/nx/nx_csbcpb.h
+ F:	drivers/crypto/nx/nx_debugfs.h
  
- CXLFLASH (IBM Coherent Accelerator Processor Interface CAPI Flash) SCSI DRIVER
- M:	Manoj N. Kumar <manoj@linux.vnet.ibm.com>
-@@ -3686,6 +3684,12 @@ F:	drivers/scsi/cxlflash/
- F:	include/uapi/scsi/cxlflash_ioctls.h
- F:	Documentation/powerpc/cxlflash.txt
- 
-+VAS (IBM Virtual Accelerator Switch) DRIVER
-+M:	Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
++IBM Power Virtual Accelerator Switchboard
++M:	Sukadev Bhattiprolu
 +L:	linuxppc-dev@lists.ozlabs.org
 +S:	Supported
-+F:	drivers/misc/vas/
-+
- STMMAC ETHERNET DRIVER
- M:	Giuseppe Cavallaro <peppe.cavallaro@st.com>
- M:	Alexandre Torgue <alexandre.torgue@st.com>
-diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
-index fc879fd..7a45ff7 100644
---- a/arch/powerpc/include/asm/reg.h
-+++ b/arch/powerpc/include/asm/reg.h
-@@ -1225,6 +1225,7 @@
- #define PVR_POWER8E	0x004B
- #define PVR_POWER8NVL	0x004C
- #define PVR_POWER8	0x004D
-+#define PVR_POWER9	0x004E
- #define PVR_BE		0x0070
- #define PVR_PA6T	0x0090
- 
-diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
-index c290990..97d652e 100644
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -783,4 +783,5 @@ source "drivers/misc/mic/Kconfig"
- source "drivers/misc/genwqe/Kconfig"
- source "drivers/misc/echo/Kconfig"
- source "drivers/misc/cxl/Kconfig"
-+source "drivers/misc/vas/Kconfig"
- endmenu
-diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
-index 7a3ea89..5201ffd 100644
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -53,6 +53,7 @@ obj-$(CONFIG_GENWQE)		+= genwqe/
- obj-$(CONFIG_ECHO)		+= echo/
- obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
- obj-$(CONFIG_CXL_BASE)		+= cxl/
-+obj-$(CONFIG_VAS)		+= vas/
- obj-$(CONFIG_PANEL)             += panel.o
- 
- lkdtm-$(CONFIG_LKDTM)		+= lkdtm_core.o
-diff --git a/drivers/misc/vas/Kconfig b/drivers/misc/vas/Kconfig
-new file mode 100644
-index 0000000..43cedda
---- /dev/null
-+++ b/drivers/misc/vas/Kconfig
-@@ -0,0 +1,21 @@
-+#
-+# IBM Virtual Accelarator Switchboard (VAS) compatible devices
-+#depends on PPC_POWERNV && PCI_MSI && EEH
-+#
-+
-+config VAS
-+	tristate "Support for IBM Virtual Accelerator Switchboard (VAS)"
-+	depends on PPC_POWERNV
++F:	arch/powerpc/platforms/powernv/vas*
++F:	arch/powerpc/include/asm/vas.h
++F:	arch/powerpc/include/uapi/asm/vas.h
++
+ IBM Power 842 compression accelerator
+ M:	Haren Myneni <haren@us.ibm.com>
+ S:	Supported
+diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
+index 6a6f4ef..f565454 100644
+--- a/arch/powerpc/platforms/powernv/Kconfig
++++ b/arch/powerpc/platforms/powernv/Kconfig
+@@ -30,3 +30,17 @@ config OPAL_PRD
+ 	help
+ 	  This enables the opal-prd driver, a facility to run processor
+ 	  recovery diagnostics on OpenPower machines
++
++config PPC_VAS
++	bool "IBM Virtual Accelerator Switchboard (VAS)"
++	depends on PPC_POWERNV && PPC_64K_PAGES
 +	default n
 +	help
-+	  Select this option to enable driver support for IBM Virtual
-+	  Accelerator Switchboard (VAS).
-+
-+	  VAS allows accelerators in co processors like NX-842 to be
-+	  directly available to a user process. This driver enables
-+	  userspace programs to access these accelerators via device
-+	  nodes like /dev/crypto/nx-gzip.
++	  This enables support for IBM Virtual Accelerator Switchboard (VAS).
++
++	  VAS allows accelerators in co-processors like NX-GZIP and NX-842
++	  to be accessible to kernel subsystems and user processes.
 +
 +	  VAS adapters are found in POWER9 based systems.
 +
 +	  If unsure, say N.
-diff --git a/drivers/misc/vas/Makefile b/drivers/misc/vas/Makefile
+diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
+index b5d98cb..e4db292 100644
+--- a/arch/powerpc/platforms/powernv/Makefile
++++ b/arch/powerpc/platforms/powernv/Makefile
+@@ -12,3 +12,4 @@ obj-$(CONFIG_PPC_SCOM)	+= opal-xscom.o
+ obj-$(CONFIG_MEMORY_FAILURE)	+= opal-memory-errors.o
+ obj-$(CONFIG_TRACEPOINTS)	+= opal-tracepoints.o
+ obj-$(CONFIG_OPAL_PRD)	+= opal-prd.o
++obj-$(CONFIG_PPC_VAS)	+= vas.o vas-window.o
+diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
 new file mode 100644
-index 0000000..7dd7139
+index 0000000..6156fbe
 --- /dev/null
-+++ b/drivers/misc/vas/Makefile
-@@ -0,0 +1,3 @@
-+ccflags-y			:= $(call cc-disable-warning, unused-const-variable)
-+ccflags-$(CONFIG_PPC_WERROR)	+= -Werror
-+obj-$(CONFIG_VAS)		+= vas.o vas-window.o
-diff --git a/drivers/misc/vas/vas-internal.h b/drivers/misc/vas/vas-internal.h
-index ce48f14..15b62e0 100644
---- a/drivers/misc/vas/vas-internal.h
-+++ b/drivers/misc/vas/vas-internal.h
-@@ -389,4 +389,7 @@ struct vas_winctx {
- 	enum vas_notify_after_count notify_after_count;
- };
- 
-+extern int vas_initialized;
-+extern int vas_window_reset(struct vas_instance *vinst, int winid);
-+extern struct vas_instance *find_vas_instance(int vasid);
- #endif
-diff --git a/drivers/misc/vas/vas-window.c b/drivers/misc/vas/vas-window.c
-new file mode 100644
-index 0000000..468f3bf
---- /dev/null
-+++ b/drivers/misc/vas/vas-window.c
++++ b/arch/powerpc/platforms/powernv/vas-window.c
 @@ -0,0 +1,19 @@
 +/*
 + * Copyright 2016 IBM Corp.
@@ -150,20 +138,20 @@
 +
 +#include <linux/types.h>
 +#include <linux/mutex.h>
-+#include <asm/vas.h>
-+#include "vas-internal.h"
++
++#include "vas.h"
 +
 +/* stub for now */
-+int vas_window_reset(struct vas_instance *vinst, int winid)
-+{
-+	return 0;
-+}
-diff --git a/drivers/misc/vas/vas.c b/drivers/misc/vas/vas.c
++int vas_win_close(struct vas_window *window)
++{
++	return -1;
++}
+diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c
 new file mode 100644
-index 0000000..75e55f9
+index 0000000..556156b
 --- /dev/null
-+++ b/drivers/misc/vas/vas.c
-@@ -0,0 +1,155 @@
++++ b/arch/powerpc/platforms/powernv/vas.c
+@@ -0,0 +1,183 @@
 +/*
 + * Copyright 2016 IBM Corp.
 + *
@@ -178,64 +166,67 @@
 +#include <linux/export.h>
 +#include <linux/types.h>
 +#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/of_platform.h>
++#include <linux/of_address.h>
 +#include <linux/of.h>
-+#include <asm/vas.h>
-+#include "vas-internal.h"
-+
-+int vas_initialized;
-+int vas_num_instances;
-+struct vas_instance *vas_instances;
-+
-+static void init_vas_chip(struct vas_instance *vinst)
-+{
-+	int i;
-+
-+	for (i = 0; i < VAS_MAX_WINDOWS_PER_CHIP; i++)
-+		vas_window_reset(vinst, i);
-+}
-+
-+static int init_vas_instance(struct device_node *dn,
-+				struct vas_instance *vinst)
-+{
-+	int rc;
-+	const __be32 *p;
-+
++
++#include "vas.h"
++
++static bool init_done;
++LIST_HEAD(vas_instances);
++
++static int init_vas_instance(struct platform_device *pdev)
++{
++	int rc, vasid;
++	struct vas_instance *vinst;
++	struct device_node *dn = pdev->dev.of_node;
++	struct resource *res;
++
++	rc = of_property_read_u32(dn, "ibm,vas-id", &vasid);
++	if (rc) {
++		pr_err("VAS: No ibm,vas-id property for %s?\n", pdev->name);
++		return -ENODEV;
++	}
++
++	if (pdev->num_resources != 4) {
++		pr_err("VAS: Unexpected DT configuration for [%s, %d]\n",
++				pdev->name, vasid);
++		return -ENODEV;
++	}
++
++	vinst = kcalloc(1, sizeof(*vinst), GFP_KERNEL);
++	if (!vinst)
++		return -ENOMEM;
++
++	INIT_LIST_HEAD(&vinst->node);
 +	ida_init(&vinst->ida);
 +	mutex_init(&vinst->mutex);
-+
-+	p = of_get_property(dn, "vas-id", NULL);
-+	if (!p) {
-+		pr_err("VAS: NULL vas-id? %p\n", p);
-+		return -ENODEV;
-+	}
-+
-+	vinst->vas_id = of_read_number(p, 1);
-+
-+	rc = of_property_read_u64(dn, "hvwc-bar-start", &vinst->hvwc_bar_start);
-+	if (rc)
-+		return rc;
-+
-+	rc = of_property_read_u64(dn, "hvwc-bar-size", &vinst->hvwc_bar_len);
-+	if (rc)
-+		return rc;
-+
-+	rc = of_property_read_u64(dn, "uwc-bar-start", &vinst->uwc_bar_start);
-+	if (rc)
-+		return rc;
-+
-+	rc = of_property_read_u64(dn, "uwc-bar-size", &vinst->uwc_bar_len);
-+	if (rc)
-+		return rc;
-+
-+	rc = of_property_read_u64(dn, "window-base", &vinst->win_base_addr);
-+	if (rc)
-+		return rc;
-+
-+	rc = of_property_read_u64(dn, "window-shift", &vinst->win_id_shift);
-+	if (rc)
-+		return rc;
-+
-+	init_vas_chip(vinst);
++	vinst->vas_id = vasid;
++	vinst->pdev = pdev;
++
++	res = &pdev->resource[0];
++	vinst->hvwc_bar_start = res->start;
++	vinst->hvwc_bar_len = res->end - res->start + 1;
++
++	res = &pdev->resource[1];
++	vinst->uwc_bar_start = res->start;
++	vinst->uwc_bar_len = res->end - res->start + 1;
++
++	res = &pdev->resource[2];
++	vinst->paste_base_addr = res->start;
++
++	res = &pdev->resource[3];
++	vinst->paste_win_id_shift = 63 - res->end;
++
++	pr_devel("VAS: Initialized instance [%s, %d], paste_base 0x%llx, "
++			"paste_win_id_shift 0x%llx\n", pdev->name, vasid,
++			vinst->paste_base_addr, vinst->paste_win_id_shift);
++
++	vinst->ready = true;
++	list_add(&vinst->node, &vas_instances);
++
++	dev_set_drvdata(&pdev->dev, vinst);
 +
 +	return 0;
 +}
@@ -246,78 +237,135 @@
 + */
 +struct vas_instance *find_vas_instance(int vasid)
 +{
-+	int i;
++	struct list_head *ent;
 +	struct vas_instance *vinst;
 +
-+	for (i = 0; i < vas_num_instances; i++) {
-+		vinst = &vas_instances[i];
++	list_for_each(ent, &vas_instances) {
++		vinst = list_entry(ent, struct vas_instance, node);
 +		if (vinst->vas_id == vasid)
 +			return vinst;
 +	}
-+	pr_err("VAS instance for vas-id %d not found\n", vasid);
-+	WARN_ON_ONCE(1);
++
++	pr_devel("VAS: Instance %d not found\n", vasid);
 +	return NULL;
 +}
 +
++bool vas_initialized(void)
++{
++	return init_done;
++}
++
++static int vas_probe(struct platform_device *pdev)
++{
++	if (!pdev || !pdev->dev.of_node)
++		return -ENODEV;
++
++	return init_vas_instance(pdev);
++}
++
++static void free_inst(struct vas_instance *vinst)
++{
++	list_del(&vinst->node);
++
++	kfree(vinst);
++}
++
++static int vas_remove(struct platform_device *pdev)
++{
++	struct vas_instance *vinst;
++
++	vinst = dev_get_drvdata(&pdev->dev);
++
++	pr_devel("VAS: Removed instance [%s, %d]\n", pdev->name,
++				vinst->vas_id);
++	free_inst(vinst);
++
++	return 0;
++}
++static const struct of_device_id powernv_vas_match[] = {
++	{ .compatible = "ibm,vas",},
++	{},
++};
++
++static struct platform_driver vas_driver = {
++	.driver = {
++		.name = "vas",
++		.of_match_table = powernv_vas_match,
++	},
++	.probe = vas_probe,
++	.remove = vas_remove,
++};
++
++module_platform_driver(vas_driver);
 +
 +int vas_init(void)
 +{
-+	int rc;
++	int found = 0;
 +	struct device_node *dn;
++
++	for_each_compatible_node(dn, NULL, "ibm,vas") {
++		of_platform_device_create(dn, NULL, NULL);
++		found++;
++	}
++
++	if (!found)
++		return -ENODEV;
++
++	pr_devel("VAS: Found %d instances\n", found);
++	init_done = true;
++
++	return 0;
++}
++
++void vas_exit(void)
++{
++	struct list_head *ent;
 +	struct vas_instance *vinst;
 +
-+	if (!pvr_version_is(PVR_POWER9))
-+		return -ENODEV;
-+
-+	vas_num_instances = 0;
-+	for_each_node_by_name(dn, "vas")
-+		vas_num_instances++;
-+
-+	if (!vas_num_instances)
-+		return -ENODEV;
-+
-+	vas_instances = kcalloc(vas_num_instances, sizeof(*vinst), GFP_KERNEL);
-+	if (!vas_instances)
-+		return -ENOMEM;
-+
-+	vinst = &vas_instances[0];
-+	for_each_node_by_name(dn, "vas") {
-+		rc = init_vas_instance(dn, vinst);
-+		if (rc) {
-+			pr_err("Error %d initializing VAS instance %ld\n", rc,
-+					(vinst-&vas_instances[0]));
-+			goto cleanup;
-+		}
-+		vinst++;
-+	}
-+
-+	rc = -ENODEV;
-+	if (vinst == &vas_instances[0]) {
-+		/* Should not happen as we saw some above. */
-+		pr_err("VAS: Did not find any VAS DT nodes now!\n");
-+		goto cleanup;
-+	}
-+
-+	pr_devel("VAS: Initialized %d instances\n", vas_num_instances);
-+	vas_initialized = 1;
-+
-+	return 0;
-+
-+cleanup:
-+	kfree(vas_instances);
-+	return rc;
-+}
-+
-+void vas_exit(void)
-+{
-+	vas_initialized = 0;
-+	kfree(vas_instances);
++	list_for_each(ent, &vas_instances) {
++		vinst = list_entry(ent, struct vas_instance, node);
++		of_platform_depopulate(&vinst->pdev->dev);
++	}
++
++	init_done = false;
 +}
 +
 +module_init(vas_init);
 +module_exit(vas_exit);
-+MODULE_DESCRIPTION("IBM Virtual Accelerator Switchboard");
++MODULE_DESCRIPTION("Bare metal IBM Virtual Accelerator Switchboard");
 +MODULE_AUTHOR("Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>");
 +MODULE_LICENSE("GPL");
+diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h
+index c6bcc0c..12c6380 100644
+--- a/arch/powerpc/platforms/powernv/vas.h
++++ b/arch/powerpc/platforms/powernv/vas.h
+@@ -291,14 +291,17 @@ enum vas_notify_after_count {
+  */
+ struct vas_instance {
+ 	int vas_id;
++	bool ready;
+ 	struct ida ida;
++	struct list_head node;
++	struct platform_device *pdev;
+ 
+ 	u64 hvwc_bar_start;
+ 	u64 hvwc_bar_len;
+ 	u64 uwc_bar_start;
+ 	u64 uwc_bar_len;
+-	u64 win_base_addr;
+-	u64 win_id_shift;
++	u64 paste_base_addr;
++	u64 paste_win_id_shift;
+ 
+ 	struct mutex mutex;
+ 	struct vas_window *rxwin[VAS_COP_TYPE_MAX];
+@@ -376,4 +379,7 @@ struct vas_winctx {
+ 	enum vas_notify_after_count notify_after_count;
+ };
+ 
++extern bool vas_initialized(void);
++extern struct vas_instance *find_vas_instance(int vasid);
++
+ #endif /* _VAS_H */
 -- 
 2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help