Linux Audio

Check our new training course

Loading...
v6.8
  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
  7#include <linux/module.h>
  8#include <linux/slab.h>
  9#include <linux/vfio.h>
 10#include <linux/pm_runtime.h>
 11#include <linux/platform_device.h>
 12
 13#include "vfio_platform_private.h"
 14
 15#define DRIVER_VERSION  "0.10"
 16#define DRIVER_AUTHOR   "Antonios Motakis <a.motakis@virtualopensystems.com>"
 17#define DRIVER_DESC     "VFIO for platform devices - User Level meta-driver"
 18
 19static bool reset_required = true;
 20module_param(reset_required, bool, 0444);
 21MODULE_PARM_DESC(reset_required, "override reset requirement (default: 1)");
 22
 23/* probing devices from the linux platform bus */
 24
 25static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
 26					      int num)
 27{
 28	struct platform_device *dev = (struct platform_device *) vdev->opaque;
 
 
 
 
 29
 30	return platform_get_mem_or_io(dev, num);
 
 
 
 
 
 
 
 31}
 32
 33static int get_platform_irq(struct vfio_platform_device *vdev, int i)
 34{
 35	struct platform_device *pdev = (struct platform_device *) vdev->opaque;
 36
 37	return platform_get_irq_optional(pdev, i);
 38}
 39
 40static int vfio_platform_init_dev(struct vfio_device *core_vdev)
 41{
 42	struct vfio_platform_device *vdev =
 43		container_of(core_vdev, struct vfio_platform_device, vdev);
 44	struct platform_device *pdev = to_platform_device(core_vdev->dev);
 
 
 
 45
 46	vdev->opaque = (void *) pdev;
 47	vdev->name = pdev->name;
 48	vdev->flags = VFIO_DEVICE_FLAGS_PLATFORM;
 49	vdev->get_resource = get_platform_resource;
 50	vdev->get_irq = get_platform_irq;
 51	vdev->reset_required = reset_required;
 52
 53	return vfio_platform_init_common(vdev);
 54}
 55
 56static const struct vfio_device_ops vfio_platform_ops;
 57static int vfio_platform_probe(struct platform_device *pdev)
 58{
 59	struct vfio_platform_device *vdev;
 60	int ret;
 61
 62	vdev = vfio_alloc_device(vfio_platform_device, vdev, &pdev->dev,
 63				 &vfio_platform_ops);
 64	if (IS_ERR(vdev))
 65		return PTR_ERR(vdev);
 66
 67	ret = vfio_register_group_dev(&vdev->vdev);
 68	if (ret)
 69		goto out_put_vdev;
 70
 71	pm_runtime_enable(&pdev->dev);
 72	dev_set_drvdata(&pdev->dev, vdev);
 73	return 0;
 74
 75out_put_vdev:
 76	vfio_put_device(&vdev->vdev);
 77	return ret;
 78}
 79
 80static void vfio_platform_release_dev(struct vfio_device *core_vdev)
 81{
 82	struct vfio_platform_device *vdev =
 83		container_of(core_vdev, struct vfio_platform_device, vdev);
 84
 85	vfio_platform_release_common(vdev);
 86}
 87
 88static int vfio_platform_remove(struct platform_device *pdev)
 89{
 90	struct vfio_platform_device *vdev = dev_get_drvdata(&pdev->dev);
 91
 92	vfio_unregister_group_dev(&vdev->vdev);
 93	pm_runtime_disable(vdev->device);
 94	vfio_put_device(&vdev->vdev);
 95	return 0;
 96}
 97
 98static const struct vfio_device_ops vfio_platform_ops = {
 99	.name		= "vfio-platform",
100	.init		= vfio_platform_init_dev,
101	.release	= vfio_platform_release_dev,
102	.open_device	= vfio_platform_open_device,
103	.close_device	= vfio_platform_close_device,
104	.ioctl		= vfio_platform_ioctl,
105	.read		= vfio_platform_read,
106	.write		= vfio_platform_write,
107	.mmap		= vfio_platform_mmap,
108	.bind_iommufd	= vfio_iommufd_physical_bind,
109	.unbind_iommufd	= vfio_iommufd_physical_unbind,
110	.attach_ioas	= vfio_iommufd_physical_attach_ioas,
111	.detach_ioas	= vfio_iommufd_physical_detach_ioas,
112};
113
114static struct platform_driver vfio_platform_driver = {
115	.probe		= vfio_platform_probe,
116	.remove		= vfio_platform_remove,
117	.driver	= {
118		.name	= "vfio-platform",
119	},
120	.driver_managed_dma = true,
121};
122
123module_platform_driver(vfio_platform_driver);
124
125MODULE_VERSION(DRIVER_VERSION);
126MODULE_LICENSE("GPL v2");
127MODULE_AUTHOR(DRIVER_AUTHOR);
128MODULE_DESCRIPTION(DRIVER_DESC);
v4.6
 
  1/*
  2 * Copyright (C) 2013 - Virtual Open Systems
  3 * Author: Antonios Motakis <a.motakis@virtualopensystems.com>
  4 *
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License, version 2, as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 */
 14
 15#include <linux/module.h>
 16#include <linux/slab.h>
 17#include <linux/vfio.h>
 
 18#include <linux/platform_device.h>
 19
 20#include "vfio_platform_private.h"
 21
 22#define DRIVER_VERSION  "0.10"
 23#define DRIVER_AUTHOR   "Antonios Motakis <a.motakis@virtualopensystems.com>"
 24#define DRIVER_DESC     "VFIO for platform devices - User Level meta-driver"
 25
 
 
 
 
 26/* probing devices from the linux platform bus */
 27
 28static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
 29					      int num)
 30{
 31	struct platform_device *dev = (struct platform_device *) vdev->opaque;
 32	int i;
 33
 34	for (i = 0; i < dev->num_resources; i++) {
 35		struct resource *r = &dev->resource[i];
 36
 37		if (resource_type(r) & (IORESOURCE_MEM|IORESOURCE_IO)) {
 38			if (!num)
 39				return r;
 40
 41			num--;
 42		}
 43	}
 44	return NULL;
 45}
 46
 47static int get_platform_irq(struct vfio_platform_device *vdev, int i)
 48{
 49	struct platform_device *pdev = (struct platform_device *) vdev->opaque;
 50
 51	return platform_get_irq(pdev, i);
 52}
 53
 54static int vfio_platform_probe(struct platform_device *pdev)
 55{
 56	struct vfio_platform_device *vdev;
 57	int ret;
 58
 59	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
 60	if (!vdev)
 61		return -ENOMEM;
 62
 63	vdev->opaque = (void *) pdev;
 64	vdev->name = pdev->name;
 65	vdev->flags = VFIO_DEVICE_FLAGS_PLATFORM;
 66	vdev->get_resource = get_platform_resource;
 67	vdev->get_irq = get_platform_irq;
 68	vdev->parent_module = THIS_MODULE;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 69
 70	ret = vfio_platform_probe_common(vdev, &pdev->dev);
 71	if (ret)
 72		kfree(vdev);
 73
 
 
 
 
 
 
 74	return ret;
 75}
 76
 
 
 
 
 
 
 
 
 77static int vfio_platform_remove(struct platform_device *pdev)
 78{
 79	struct vfio_platform_device *vdev;
 80
 81	vdev = vfio_platform_remove_common(&pdev->dev);
 82	if (vdev) {
 83		kfree(vdev);
 84		return 0;
 85	}
 86
 87	return -EINVAL;
 88}
 
 
 
 
 
 
 
 
 
 
 
 
 
 89
 90static struct platform_driver vfio_platform_driver = {
 91	.probe		= vfio_platform_probe,
 92	.remove		= vfio_platform_remove,
 93	.driver	= {
 94		.name	= "vfio-platform",
 95	},
 
 96};
 97
 98module_platform_driver(vfio_platform_driver);
 99
100MODULE_VERSION(DRIVER_VERSION);
101MODULE_LICENSE("GPL v2");
102MODULE_AUTHOR(DRIVER_AUTHOR);
103MODULE_DESCRIPTION(DRIVER_DESC);