Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013 - Virtual Open Systems
0004  * Author: Antonios Motakis <a.motakis@virtualopensystems.com>
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/vfio.h>
0010 #include <linux/platform_device.h>
0011 
0012 #include "vfio_platform_private.h"
0013 
0014 #define DRIVER_VERSION  "0.10"
0015 #define DRIVER_AUTHOR   "Antonios Motakis <a.motakis@virtualopensystems.com>"
0016 #define DRIVER_DESC     "VFIO for platform devices - User Level meta-driver"
0017 
0018 static bool reset_required = true;
0019 module_param(reset_required, bool, 0444);
0020 MODULE_PARM_DESC(reset_required, "override reset requirement (default: 1)");
0021 
0022 /* probing devices from the linux platform bus */
0023 
0024 static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
0025                           int num)
0026 {
0027     struct platform_device *dev = (struct platform_device *) vdev->opaque;
0028 
0029     return platform_get_mem_or_io(dev, num);
0030 }
0031 
0032 static int get_platform_irq(struct vfio_platform_device *vdev, int i)
0033 {
0034     struct platform_device *pdev = (struct platform_device *) vdev->opaque;
0035 
0036     return platform_get_irq_optional(pdev, i);
0037 }
0038 
0039 static int vfio_platform_probe(struct platform_device *pdev)
0040 {
0041     struct vfio_platform_device *vdev;
0042     int ret;
0043 
0044     vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
0045     if (!vdev)
0046         return -ENOMEM;
0047 
0048     vdev->opaque = (void *) pdev;
0049     vdev->name = pdev->name;
0050     vdev->flags = VFIO_DEVICE_FLAGS_PLATFORM;
0051     vdev->get_resource = get_platform_resource;
0052     vdev->get_irq = get_platform_irq;
0053     vdev->reset_required = reset_required;
0054 
0055     ret = vfio_platform_probe_common(vdev, &pdev->dev);
0056     if (ret) {
0057         kfree(vdev);
0058         return ret;
0059     }
0060     dev_set_drvdata(&pdev->dev, vdev);
0061     return 0;
0062 }
0063 
0064 static int vfio_platform_remove(struct platform_device *pdev)
0065 {
0066     struct vfio_platform_device *vdev = dev_get_drvdata(&pdev->dev);
0067 
0068     vfio_platform_remove_common(vdev);
0069     kfree(vdev);
0070     return 0;
0071 }
0072 
0073 static struct platform_driver vfio_platform_driver = {
0074     .probe      = vfio_platform_probe,
0075     .remove     = vfio_platform_remove,
0076     .driver = {
0077         .name   = "vfio-platform",
0078     },
0079     .driver_managed_dma = true,
0080 };
0081 
0082 module_platform_driver(vfio_platform_driver);
0083 
0084 MODULE_VERSION(DRIVER_VERSION);
0085 MODULE_LICENSE("GPL v2");
0086 MODULE_AUTHOR(DRIVER_AUTHOR);
0087 MODULE_DESCRIPTION(DRIVER_DESC);