iommu/iommu-debug: Add functional test for ARM DMA IOMMU mapper

The vanilla ARM DMA IOMMU mapper is used by many clients in our system,
but we have no functional test coverage of it.  Add some functional
testing for it by leveraging the tests that were recently added for the
Fast DMA mapper.  Since the Fast mapper and the ARM mapper are both DMA
API implementations we can share most of the code.

CRs-Fixed: 997751
Change-Id: I58734a82f4dc3e4658ab7995b6682205097da991
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 76681c4..e828469 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -1411,6 +1411,47 @@
 	.release = single_release,
 };
 
+static int iommu_debug_functional_arm_dma_api_show(struct seq_file *s,
+						   void *ignored)
+{
+	struct dma_iommu_mapping *mapping;
+	struct iommu_debug_device *ddev = s->private;
+	struct device *dev = ddev->dev;
+	size_t sizes[] = {SZ_4K, SZ_64K, SZ_2M, SZ_1M * 12, 0};
+	int ret = -EINVAL;
+
+	mapping = arm_iommu_create_mapping(&platform_bus_type, 0, SZ_1G * 4UL);
+	if (!mapping)
+		goto out;
+
+	if (arm_iommu_attach_device(dev, mapping))
+		goto out_release_mapping;
+
+	ret = __functional_dma_api_alloc_test(dev, s, mapping->domain, sizes);
+	ret |= __functional_dma_api_basic_test(dev, s, mapping->domain, sizes);
+
+	arm_iommu_detach_device(dev);
+out_release_mapping:
+	arm_iommu_release_mapping(mapping);
+out:
+	seq_printf(s, "%s\n", ret ? "FAIL" : "SUCCESS");
+	return 0;
+}
+
+static int iommu_debug_functional_arm_dma_api_open(struct inode *inode,
+						   struct file *file)
+{
+	return single_open(file, iommu_debug_functional_arm_dma_api_show,
+			   inode->i_private);
+}
+
+static const struct file_operations iommu_debug_functional_arm_dma_api_fops = {
+	.open	 = iommu_debug_functional_arm_dma_api_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release,
+};
+
 static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
 					int val, bool is_secure)
 {
@@ -1810,6 +1851,13 @@
 		goto err_rmdir;
 	}
 
+	if (!debugfs_create_file("functional_arm_dma_api", S_IRUSR, dir, ddev,
+				 &iommu_debug_functional_arm_dma_api_fops)) {
+		pr_err("Couldn't create iommu/devices/%s/functional_arm_dma_api debugfs file\n",
+		       dev_name(dev));
+		goto err_rmdir;
+	}
+
 	if (!debugfs_create_file("attach", S_IRUSR, dir, ddev,
 				 &iommu_debug_attach_fops)) {
 		pr_err("Couldn't create iommu/devices/%s/attach debugfs file\n",