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 14struct grant_dma_iommu_device { 15 struct device *dev; 16 struct iommu_device iommu; 17}; 18 19static 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 */ 25static const struct iommu_ops grant_dma_iommu_ops = { 26 .probe_device = grant_dma_iommu_probe_device, 27}; 28 29static const struct of_device_id grant_dma_iommu_of_match[] = { 30 { .compatible = "xen,grant-dma" }, 31 { }, 32}; 33 34static 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 54static 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 62static 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 71static 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} 83subsys_initcall(grant_dma_iommu_init); 84