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 int 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 return 0; 62} 63 64static struct platform_driver grant_dma_iommu_driver = { 65 .driver = { 66 .name = "grant-dma-iommu", 67 .of_match_table = grant_dma_iommu_of_match, 68 }, 69 .probe = grant_dma_iommu_probe, 70 .remove = grant_dma_iommu_remove, 71}; 72 73static int __init grant_dma_iommu_init(void) 74{ 75 struct device_node *iommu_np; 76 77 iommu_np = of_find_matching_node(NULL, grant_dma_iommu_of_match); 78 if (!iommu_np) 79 return 0; 80 81 of_node_put(iommu_np); 82 83 return platform_driver_register(&grant_dma_iommu_driver); 84} 85subsys_initcall(grant_dma_iommu_init); 86