vfio_platform.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2013 - Virtual Open Systems
  4. * Author: Antonios Motakis <a.motakis@virtualopensystems.com>
  5. */
  6. #include <linux/module.h>
  7. #include <linux/slab.h>
  8. #include <linux/vfio.h>
  9. #include <linux/pm_runtime.h>
  10. #include <linux/platform_device.h>
  11. #include "vfio_platform_private.h"
  12. #define DRIVER_VERSION "0.10"
  13. #define DRIVER_AUTHOR "Antonios Motakis <a.motakis@virtualopensystems.com>"
  14. #define DRIVER_DESC "VFIO for platform devices - User Level meta-driver"
  15. static bool reset_required = true;
  16. module_param(reset_required, bool, 0444);
  17. MODULE_PARM_DESC(reset_required, "override reset requirement (default: 1)");
  18. /* probing devices from the linux platform bus */
  19. static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
  20. int num)
  21. {
  22. struct platform_device *dev = (struct platform_device *) vdev->opaque;
  23. return platform_get_mem_or_io(dev, num);
  24. }
  25. static int get_platform_irq(struct vfio_platform_device *vdev, int i)
  26. {
  27. struct platform_device *pdev = (struct platform_device *) vdev->opaque;
  28. return platform_get_irq_optional(pdev, i);
  29. }
  30. static int vfio_platform_init_dev(struct vfio_device *core_vdev)
  31. {
  32. struct vfio_platform_device *vdev =
  33. container_of(core_vdev, struct vfio_platform_device, vdev);
  34. struct platform_device *pdev = to_platform_device(core_vdev->dev);
  35. vdev->opaque = (void *) pdev;
  36. vdev->name = pdev->name;
  37. vdev->flags = VFIO_DEVICE_FLAGS_PLATFORM;
  38. vdev->get_resource = get_platform_resource;
  39. vdev->get_irq = get_platform_irq;
  40. vdev->reset_required = reset_required;
  41. return vfio_platform_init_common(vdev);
  42. }
  43. static const struct vfio_device_ops vfio_platform_ops;
  44. static int vfio_platform_probe(struct platform_device *pdev)
  45. {
  46. struct vfio_platform_device *vdev;
  47. int ret;
  48. vdev = vfio_alloc_device(vfio_platform_device, vdev, &pdev->dev,
  49. &vfio_platform_ops);
  50. if (IS_ERR(vdev))
  51. return PTR_ERR(vdev);
  52. ret = vfio_register_group_dev(&vdev->vdev);
  53. if (ret)
  54. goto out_put_vdev;
  55. pm_runtime_enable(&pdev->dev);
  56. dev_set_drvdata(&pdev->dev, vdev);
  57. return 0;
  58. out_put_vdev:
  59. vfio_put_device(&vdev->vdev);
  60. return ret;
  61. }
  62. static void vfio_platform_release_dev(struct vfio_device *core_vdev)
  63. {
  64. struct vfio_platform_device *vdev =
  65. container_of(core_vdev, struct vfio_platform_device, vdev);
  66. vfio_platform_release_common(vdev);
  67. }
  68. static void vfio_platform_remove(struct platform_device *pdev)
  69. {
  70. struct vfio_platform_device *vdev = dev_get_drvdata(&pdev->dev);
  71. vfio_unregister_group_dev(&vdev->vdev);
  72. pm_runtime_disable(vdev->device);
  73. vfio_put_device(&vdev->vdev);
  74. }
  75. static const struct vfio_device_ops vfio_platform_ops = {
  76. .name = "vfio-platform",
  77. .init = vfio_platform_init_dev,
  78. .release = vfio_platform_release_dev,
  79. .open_device = vfio_platform_open_device,
  80. .close_device = vfio_platform_close_device,
  81. .ioctl = vfio_platform_ioctl,
  82. .read = vfio_platform_read,
  83. .write = vfio_platform_write,
  84. .mmap = vfio_platform_mmap,
  85. .bind_iommufd = vfio_iommufd_physical_bind,
  86. .unbind_iommufd = vfio_iommufd_physical_unbind,
  87. .attach_ioas = vfio_iommufd_physical_attach_ioas,
  88. .detach_ioas = vfio_iommufd_physical_detach_ioas,
  89. };
  90. static struct platform_driver vfio_platform_driver = {
  91. .probe = vfio_platform_probe,
  92. .remove_new = vfio_platform_remove,
  93. .driver = {
  94. .name = "vfio-platform",
  95. },
  96. .driver_managed_dma = true,
  97. };
  98. module_platform_driver(vfio_platform_driver);
  99. MODULE_VERSION(DRIVER_VERSION);
  100. MODULE_LICENSE("GPL v2");
  101. MODULE_AUTHOR(DRIVER_AUTHOR);
  102. MODULE_DESCRIPTION(DRIVER_DESC);