1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Stub IOMMU driver which does nothing. 4 * The main purpose of it being present is to reuse generic IOMMU device tree 5 * bindings by Xen grant DMA-mapping layer. 6 * 7 * Copyright (C) 2022 EPAM Systems Inc. 8 */ 9 10 #include <linux/iommu.h> 11 #include <linux/of.h> 12 #include <linux/platform_device.h> 13 14 struct grant_dma_iommu_device { 15 struct device *dev; 16 struct iommu_device iommu; 17 }; 18 19 static struct iommu_device *grant_dma_iommu_probe_device(struct device *dev) 20 { 21 return ERR_PTR(-ENODEV); 22 } 23 24 /* Nothing is really needed here except a dummy probe_device callback */ 25 static const struct iommu_ops grant_dma_iommu_ops = { 26 .probe_device = grant_dma_iommu_probe_device, 27 }; 28 29 static const struct of_device_id grant_dma_iommu_of_match[] = { 30 { .compatible = "xen,grant-dma" }, 31 { }, 32 }; 33 34 static int grant_dma_iommu_probe(struct platform_device *pdev) 35 { 36 struct grant_dma_iommu_device *mmu; 37 int ret; 38 39 mmu = devm_kzalloc(&pdev->dev, sizeof(*mmu), GFP_KERNEL); 40 if (!mmu) 41 return -ENOMEM; 42 43 mmu->dev = &pdev->dev; 44 45 ret = iommu_device_register(&mmu->iommu, &grant_dma_iommu_ops, &pdev->dev); 46 if (ret) 47 return ret; 48 49 platform_set_drvdata(pdev, mmu); 50 51 return 0; 52 } 53 54 static void grant_dma_iommu_remove(struct platform_device *pdev) 55 { 56 struct grant_dma_iommu_device *mmu = platform_get_drvdata(pdev); 57 58 platform_set_drvdata(pdev, NULL); 59 iommu_device_unregister(&mmu->iommu); 60 } 61 62 static struct platform_driver grant_dma_iommu_driver = { 63 .driver = { 64 .name = "grant-dma-iommu", 65 .of_match_table = grant_dma_iommu_of_match, 66 }, 67 .probe = grant_dma_iommu_probe, 68 .remove_new = grant_dma_iommu_remove, 69 }; 70 71 static int __init grant_dma_iommu_init(void) 72 { 73 struct device_node *iommu_np; 74 75 iommu_np = of_find_matching_node(NULL, grant_dma_iommu_of_match); 76 if (!iommu_np) 77 return 0; 78 79 of_node_put(iommu_np); 80 81 return platform_driver_register(&grant_dma_iommu_driver); 82 } 83 subsys_initcall(grant_dma_iommu_init); 84