0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/iommu.h>
0011 #include <linux/of.h>
0012 #include <linux/platform_device.h>
0013
0014 struct grant_dma_iommu_device {
0015 struct device *dev;
0016 struct iommu_device iommu;
0017 };
0018
0019
0020 static const struct iommu_ops grant_dma_iommu_ops;
0021
0022 static const struct of_device_id grant_dma_iommu_of_match[] = {
0023 { .compatible = "xen,grant-dma" },
0024 { },
0025 };
0026
0027 static int grant_dma_iommu_probe(struct platform_device *pdev)
0028 {
0029 struct grant_dma_iommu_device *mmu;
0030 int ret;
0031
0032 mmu = devm_kzalloc(&pdev->dev, sizeof(*mmu), GFP_KERNEL);
0033 if (!mmu)
0034 return -ENOMEM;
0035
0036 mmu->dev = &pdev->dev;
0037
0038 ret = iommu_device_register(&mmu->iommu, &grant_dma_iommu_ops, &pdev->dev);
0039 if (ret)
0040 return ret;
0041
0042 platform_set_drvdata(pdev, mmu);
0043
0044 return 0;
0045 }
0046
0047 static int grant_dma_iommu_remove(struct platform_device *pdev)
0048 {
0049 struct grant_dma_iommu_device *mmu = platform_get_drvdata(pdev);
0050
0051 platform_set_drvdata(pdev, NULL);
0052 iommu_device_unregister(&mmu->iommu);
0053
0054 return 0;
0055 }
0056
0057 static struct platform_driver grant_dma_iommu_driver = {
0058 .driver = {
0059 .name = "grant-dma-iommu",
0060 .of_match_table = grant_dma_iommu_of_match,
0061 },
0062 .probe = grant_dma_iommu_probe,
0063 .remove = grant_dma_iommu_remove,
0064 };
0065
0066 static int __init grant_dma_iommu_init(void)
0067 {
0068 struct device_node *iommu_np;
0069
0070 iommu_np = of_find_matching_node(NULL, grant_dma_iommu_of_match);
0071 if (!iommu_np)
0072 return 0;
0073
0074 of_node_put(iommu_np);
0075
0076 return platform_driver_register(&grant_dma_iommu_driver);
0077 }
0078 subsys_initcall(grant_dma_iommu_init);