xref: /openbmc/linux/drivers/xen/grant-dma-iommu.c (revision 2062f9fb)
11ca55d50SOleksandr Tyshchenko // SPDX-License-Identifier: GPL-2.0
21ca55d50SOleksandr Tyshchenko /*
31ca55d50SOleksandr Tyshchenko  * Stub IOMMU driver which does nothing.
41ca55d50SOleksandr Tyshchenko  * The main purpose of it being present is to reuse generic IOMMU device tree
51ca55d50SOleksandr Tyshchenko  * bindings by Xen grant DMA-mapping layer.
61ca55d50SOleksandr Tyshchenko  *
71ca55d50SOleksandr Tyshchenko  * Copyright (C) 2022 EPAM Systems Inc.
81ca55d50SOleksandr Tyshchenko  */
91ca55d50SOleksandr Tyshchenko 
101ca55d50SOleksandr Tyshchenko #include <linux/iommu.h>
111ca55d50SOleksandr Tyshchenko #include <linux/of.h>
121ca55d50SOleksandr Tyshchenko #include <linux/platform_device.h>
131ca55d50SOleksandr Tyshchenko 
141ca55d50SOleksandr Tyshchenko struct grant_dma_iommu_device {
151ca55d50SOleksandr Tyshchenko 	struct device *dev;
161ca55d50SOleksandr Tyshchenko 	struct iommu_device iommu;
171ca55d50SOleksandr Tyshchenko };
181ca55d50SOleksandr Tyshchenko 
grant_dma_iommu_probe_device(struct device * dev)19*2062f9fbSOleksandr Tyshchenko static struct iommu_device *grant_dma_iommu_probe_device(struct device *dev)
20*2062f9fbSOleksandr Tyshchenko {
21*2062f9fbSOleksandr Tyshchenko 	return ERR_PTR(-ENODEV);
22*2062f9fbSOleksandr Tyshchenko }
23*2062f9fbSOleksandr Tyshchenko 
24*2062f9fbSOleksandr Tyshchenko /* Nothing is really needed here except a dummy probe_device callback */
25*2062f9fbSOleksandr Tyshchenko static const struct iommu_ops grant_dma_iommu_ops = {
26*2062f9fbSOleksandr Tyshchenko 	.probe_device = grant_dma_iommu_probe_device,
27*2062f9fbSOleksandr Tyshchenko };
281ca55d50SOleksandr Tyshchenko 
291ca55d50SOleksandr Tyshchenko static const struct of_device_id grant_dma_iommu_of_match[] = {
301ca55d50SOleksandr Tyshchenko 	{ .compatible = "xen,grant-dma" },
311ca55d50SOleksandr Tyshchenko 	{ },
321ca55d50SOleksandr Tyshchenko };
331ca55d50SOleksandr Tyshchenko 
grant_dma_iommu_probe(struct platform_device * pdev)341ca55d50SOleksandr Tyshchenko static int grant_dma_iommu_probe(struct platform_device *pdev)
351ca55d50SOleksandr Tyshchenko {
361ca55d50SOleksandr Tyshchenko 	struct grant_dma_iommu_device *mmu;
371ca55d50SOleksandr Tyshchenko 	int ret;
381ca55d50SOleksandr Tyshchenko 
391ca55d50SOleksandr Tyshchenko 	mmu = devm_kzalloc(&pdev->dev, sizeof(*mmu), GFP_KERNEL);
401ca55d50SOleksandr Tyshchenko 	if (!mmu)
411ca55d50SOleksandr Tyshchenko 		return -ENOMEM;
421ca55d50SOleksandr Tyshchenko 
431ca55d50SOleksandr Tyshchenko 	mmu->dev = &pdev->dev;
441ca55d50SOleksandr Tyshchenko 
451ca55d50SOleksandr Tyshchenko 	ret = iommu_device_register(&mmu->iommu, &grant_dma_iommu_ops, &pdev->dev);
461ca55d50SOleksandr Tyshchenko 	if (ret)
471ca55d50SOleksandr Tyshchenko 		return ret;
481ca55d50SOleksandr Tyshchenko 
491ca55d50SOleksandr Tyshchenko 	platform_set_drvdata(pdev, mmu);
501ca55d50SOleksandr Tyshchenko 
511ca55d50SOleksandr Tyshchenko 	return 0;
521ca55d50SOleksandr Tyshchenko }
531ca55d50SOleksandr Tyshchenko 
grant_dma_iommu_remove(struct platform_device * pdev)541ca55d50SOleksandr Tyshchenko static int grant_dma_iommu_remove(struct platform_device *pdev)
551ca55d50SOleksandr Tyshchenko {
561ca55d50SOleksandr Tyshchenko 	struct grant_dma_iommu_device *mmu = platform_get_drvdata(pdev);
571ca55d50SOleksandr Tyshchenko 
581ca55d50SOleksandr Tyshchenko 	platform_set_drvdata(pdev, NULL);
591ca55d50SOleksandr Tyshchenko 	iommu_device_unregister(&mmu->iommu);
601ca55d50SOleksandr Tyshchenko 
611ca55d50SOleksandr Tyshchenko 	return 0;
621ca55d50SOleksandr Tyshchenko }
631ca55d50SOleksandr Tyshchenko 
641ca55d50SOleksandr Tyshchenko static struct platform_driver grant_dma_iommu_driver = {
651ca55d50SOleksandr Tyshchenko 	.driver = {
661ca55d50SOleksandr Tyshchenko 		.name = "grant-dma-iommu",
671ca55d50SOleksandr Tyshchenko 		.of_match_table = grant_dma_iommu_of_match,
681ca55d50SOleksandr Tyshchenko 	},
691ca55d50SOleksandr Tyshchenko 	.probe = grant_dma_iommu_probe,
701ca55d50SOleksandr Tyshchenko 	.remove = grant_dma_iommu_remove,
711ca55d50SOleksandr Tyshchenko };
721ca55d50SOleksandr Tyshchenko 
grant_dma_iommu_init(void)731ca55d50SOleksandr Tyshchenko static int __init grant_dma_iommu_init(void)
741ca55d50SOleksandr Tyshchenko {
751ca55d50SOleksandr Tyshchenko 	struct device_node *iommu_np;
761ca55d50SOleksandr Tyshchenko 
771ca55d50SOleksandr Tyshchenko 	iommu_np = of_find_matching_node(NULL, grant_dma_iommu_of_match);
781ca55d50SOleksandr Tyshchenko 	if (!iommu_np)
791ca55d50SOleksandr Tyshchenko 		return 0;
801ca55d50SOleksandr Tyshchenko 
811ca55d50SOleksandr Tyshchenko 	of_node_put(iommu_np);
821ca55d50SOleksandr Tyshchenko 
831ca55d50SOleksandr Tyshchenko 	return platform_driver_register(&grant_dma_iommu_driver);
841ca55d50SOleksandr Tyshchenko }
851ca55d50SOleksandr Tyshchenko subsys_initcall(grant_dma_iommu_init);
86