brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · 42d1462 Raw
128 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2013 - Virtual Open Systems4 * 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 void 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}96 97static const struct vfio_device_ops vfio_platform_ops = {98	.name		= "vfio-platform",99	.init		= vfio_platform_init_dev,100	.release	= vfio_platform_release_dev,101	.open_device	= vfio_platform_open_device,102	.close_device	= vfio_platform_close_device,103	.ioctl		= vfio_platform_ioctl,104	.read		= vfio_platform_read,105	.write		= vfio_platform_write,106	.mmap		= vfio_platform_mmap,107	.bind_iommufd	= vfio_iommufd_physical_bind,108	.unbind_iommufd	= vfio_iommufd_physical_unbind,109	.attach_ioas	= vfio_iommufd_physical_attach_ioas,110	.detach_ioas	= vfio_iommufd_physical_detach_ioas,111};112 113static struct platform_driver vfio_platform_driver = {114	.probe		= vfio_platform_probe,115	.remove_new	= vfio_platform_remove,116	.driver	= {117		.name	= "vfio-platform",118	},119	.driver_managed_dma = true,120};121 122module_platform_driver(vfio_platform_driver);123 124MODULE_VERSION(DRIVER_VERSION);125MODULE_LICENSE("GPL v2");126MODULE_AUTHOR(DRIVER_AUTHOR);127MODULE_DESCRIPTION(DRIVER_DESC);128