diff options
author | Antonios Motakis <a.motakis@virtualopensystems.com> | 2015-03-16 16:08:44 -0400 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2015-03-16 16:08:44 -0400 |
commit | 36fe431f2811fa3b5fed15d272c585d5a47977aa (patch) | |
tree | f97aca881bc369ff33479bf85aa5ded45338529a | |
parent | 53161532394b3b3c7e1ec9c80658edd75446ac77 (diff) |
vfio: amba: VFIO support for AMBA devices
Add support for discovering AMBA devices with VFIO and handle them
similarly to Linux platform devices.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
Reviewed-by: Eric Auger <eric.auger@linaro.org>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r-- | drivers/vfio/platform/vfio_amba.c | 115 | ||||
-rw-r--r-- | include/uapi/linux/vfio.h | 1 |
2 files changed, 116 insertions, 0 deletions
diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c new file mode 100644 index 000000000000..ff0331f72526 --- /dev/null +++ b/drivers/vfio/platform/vfio_amba.c | |||
@@ -0,0 +1,115 @@ | |||
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/amba/bus.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 AMBA devices - User Level meta-driver" | ||
25 | |||
26 | /* probing devices from the AMBA bus */ | ||
27 | |||
28 | static struct resource *get_amba_resource(struct vfio_platform_device *vdev, | ||
29 | int i) | ||
30 | { | ||
31 | struct amba_device *adev = (struct amba_device *) vdev->opaque; | ||
32 | |||
33 | if (i == 0) | ||
34 | return &adev->res; | ||
35 | |||
36 | return NULL; | ||
37 | } | ||
38 | |||
39 | static int get_amba_irq(struct vfio_platform_device *vdev, int i) | ||
40 | { | ||
41 | struct amba_device *adev = (struct amba_device *) vdev->opaque; | ||
42 | int ret = 0; | ||
43 | |||
44 | if (i < AMBA_NR_IRQS) | ||
45 | ret = adev->irq[i]; | ||
46 | |||
47 | /* zero is an unset IRQ for AMBA devices */ | ||
48 | return ret ? ret : -ENXIO; | ||
49 | } | ||
50 | |||
51 | static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id) | ||
52 | { | ||
53 | struct vfio_platform_device *vdev; | ||
54 | int ret; | ||
55 | |||
56 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); | ||
57 | if (!vdev) | ||
58 | return -ENOMEM; | ||
59 | |||
60 | vdev->name = kasprintf(GFP_KERNEL, "vfio-amba-%08x", adev->periphid); | ||
61 | if (!vdev->name) { | ||
62 | kfree(vdev); | ||
63 | return -ENOMEM; | ||
64 | } | ||
65 | |||
66 | vdev->opaque = (void *) adev; | ||
67 | vdev->flags = VFIO_DEVICE_FLAGS_AMBA; | ||
68 | vdev->get_resource = get_amba_resource; | ||
69 | vdev->get_irq = get_amba_irq; | ||
70 | |||
71 | ret = vfio_platform_probe_common(vdev, &adev->dev); | ||
72 | if (ret) { | ||
73 | kfree(vdev->name); | ||
74 | kfree(vdev); | ||
75 | } | ||
76 | |||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static int vfio_amba_remove(struct amba_device *adev) | ||
81 | { | ||
82 | struct vfio_platform_device *vdev; | ||
83 | |||
84 | vdev = vfio_platform_remove_common(&adev->dev); | ||
85 | if (vdev) { | ||
86 | kfree(vdev->name); | ||
87 | kfree(vdev); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | return -EINVAL; | ||
92 | } | ||
93 | |||
94 | static struct amba_id pl330_ids[] = { | ||
95 | { 0, 0 }, | ||
96 | }; | ||
97 | |||
98 | MODULE_DEVICE_TABLE(amba, pl330_ids); | ||
99 | |||
100 | static struct amba_driver vfio_amba_driver = { | ||
101 | .probe = vfio_amba_probe, | ||
102 | .remove = vfio_amba_remove, | ||
103 | .id_table = pl330_ids, | ||
104 | .drv = { | ||
105 | .name = "vfio-amba", | ||
106 | .owner = THIS_MODULE, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | module_amba_driver(vfio_amba_driver); | ||
111 | |||
112 | MODULE_VERSION(DRIVER_VERSION); | ||
113 | MODULE_LICENSE("GPL v2"); | ||
114 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
115 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index ea9514b6bb5c..b57b750c222f 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h | |||
@@ -161,6 +161,7 @@ struct vfio_device_info { | |||
161 | #define VFIO_DEVICE_FLAGS_RESET (1 << 0) /* Device supports reset */ | 161 | #define VFIO_DEVICE_FLAGS_RESET (1 << 0) /* Device supports reset */ |
162 | #define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */ | 162 | #define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */ |
163 | #define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */ | 163 | #define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */ |
164 | #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */ | ||
164 | __u32 num_regions; /* Max region index + 1 */ | 165 | __u32 num_regions; /* Max region index + 1 */ |
165 | __u32 num_irqs; /* Max IRQ index + 1 */ | 166 | __u32 num_irqs; /* Max IRQ index + 1 */ |
166 | }; | 167 | }; |