diff options
author | Sinan Kaya <okaya@codeaurora.org> | 2016-07-19 09:01:46 -0400 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2016-07-19 12:26:44 -0400 |
commit | d30daa33ec1d035acfdfc7662d7a5360592af44c (patch) | |
tree | 1ce71778d5c55adade4c911258d797028359d35b /drivers | |
parent | 5afec27474fdc52e9d80b359ce10fab59c85d131 (diff) |
vfio: platform: call _RST method when using ACPI
The device tree code checks for the presence of a reset driver and calls
the of_reset function pointer by looking up the reset driver as a module.
ACPI defines _RST method to perform device level reset. After the _RST
method is executed, the OS can resume using the device. _RST method is
expected to stop DMA transfers and IRQs.
This patch introduces two functions as vfio_platform_acpi_has_reset and
vfio_platform_acpi_call_reset. The has reset method is used to declare
reset capability via the ioctl flag VFIO_DEVICE_FLAGS_RESET. The call
reset function is used to execute the _RST ACPI method.
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/vfio/platform/vfio_platform_common.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index a9760c2e68ad..a15a69b52080 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c | ||||
@@ -28,6 +28,8 @@ | ||||
28 | #define DRIVER_AUTHOR "Antonios Motakis <a.motakis@virtualopensystems.com>" | 28 | #define DRIVER_AUTHOR "Antonios Motakis <a.motakis@virtualopensystems.com>" | |
29 | #define DRIVER_DESC "VFIO platform base module" | 29 | #define DRIVER_DESC "VFIO platform base module" | |
30 | 30 | |||
31 | #define VFIO_PLATFORM_IS_ACPI(vdev) ((vdev)->acpihid != NULL) | |||
32 | ||||
31 | static LIST_HEAD(reset_list); | 33 | static LIST_HEAD(reset_list); | |
32 | static DEFINE_MUTEX(driver_lock); | 34 | static DEFINE_MUTEX(driver_lock); | |
33 | 35 | |||
@@ -71,13 +73,53 @@ static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev, | ||||
71 | return WARN_ON(!vdev->acpihid) ? -EINVAL : 0; | 73 | return WARN_ON(!vdev->acpihid) ? -EINVAL : 0; | |
72 | } | 74 | } | |
73 | 75 | |||
76 | int vfio_platform_acpi_call_reset(struct vfio_platform_device *vdev, | |||
77 | const char **extra_dbg) | |||
78 | { | |||
79 | #ifdef CONFIG_ACPI | |||
80 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | |||
81 | struct device *dev = vdev->device; | |||
82 | acpi_handle handle = ACPI_HANDLE(dev); | |||
83 | acpi_status acpi_ret; | |||
84 | ||||
85 | acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, &buffer); | |||
86 | if (ACPI_FAILURE(acpi_ret)) { | |||
87 | if (extra_dbg) | |||
88 | *extra_dbg = acpi_format_exception(acpi_ret); | |||
89 | return -EINVAL; | |||
90 | } | |||
91 | ||||
92 | return 0; | |||
93 | #else | |||
94 | return -ENOENT; | |||
95 | #endif | |||
96 | } | |||
97 | ||||
98 | bool vfio_platform_acpi_has_reset(struct vfio_platform_device *vdev) | |||
99 | { | |||
100 | #ifdef CONFIG_ACPI | |||
101 | struct device *dev = vdev->device; | |||
102 | acpi_handle handle = ACPI_HANDLE(dev); | |||
103 | ||||
104 | return acpi_has_method(handle, "_RST"); | |||
105 | #else | |||
106 | return false; | |||
107 | #endif | |||
108 | } | |||
109 | ||||
74 | static bool vfio_platform_has_reset(struct vfio_platform_device *vdev) | 110 | static bool vfio_platform_has_reset(struct vfio_platform_device *vdev) | |
75 | { | 111 | { | |
112 | if (VFIO_PLATFORM_IS_ACPI(vdev)) | |||
113 | return vfio_platform_acpi_has_reset(vdev); | |||
114 | ||||
76 | return vdev->of_reset ? true : false; | 115 | return vdev->of_reset ? true #define LMMIO_DIRECT0_ROUTE 0x310 #define LMMIO_DIST_BASE 0x360 #define LMMIO_DIST_MASK 0x368 #define LMMIO_DIST_ROUTE 0x370 #define IOS_DIST_BASE 0x390 #define IOS_DIST_MASK 0x398 #define IOS_DIST_ROUTE 0x3A0 #define IOS_DIRECT_BASE 0x3C0 #define IOS_DIRECT_MASK 0x3C8 #define IOS_DIRECT_ROUTE 0x3D0 /* ** Offsets into I/O TLB (Function 2 and 3 on Ike) */ #define ROPE0_CTL 0x200 /* "regbus pci0" */ #define ROPE1_CTL 0x208 #define ROPE2_CTL 0x210 #define ROPE3_CTL 0x218 #define ROPE4_CTL 0x220 #define ROPE5_CTL 0x228 #define ROPE6_CTL 0x230 #define ROPE7_CTL 0x238 #define IOC_ROPE0_CFG 0x500 /* pluto only */ #define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */ #define HF_ENABLE 0x40 #define IOC_IBASE 0x300 /* IO TLB */ #define IOC_IMASK 0x308 #define IOC_PCOM 0x310 #define IOC_TCNFG 0x318 #define IOC_PDIR_BASE 0x320 /* ** IOC supports 4/8/16/64KB page sizes (see TCNFG register) ** It's safer (avoid memory corruption) to keep DMA page mappings ** equivalently sized to VM PAGE_SIZE. ** ** We really can't avoid generating a new mapping for eachitmus-rt-budgetable-locks.git/.git/tree/drivers/vfio/platform/vfio_platform_common.c?id=d30daa33ec1d035acfdfc7662d7a5360592af44c#n121'>121 | return; |
122 | ||||
81 | vdev->of_reset = vfio_platform_lookup_reset(vdev->compat, | 123 | vdev->of_reset = vfio_platform_lookup_reset(vdev->compat, | |
82 | &vdev->reset_module); | 124 | &vdev->reset_module); | |
83 | if (!vdev->of_reset) { | 125 | if (!vdev->of_reset) { | |
@@ -89,6 +131,9 @@ static void vfio_platform_get_reset(struct vfio_platform_device *vdev) | ||||
89 | 131 | |||
90 | static void vfio_platform_put_reset(struct vfio_platform_device *vdev) | 132 | static void vfio_platform_put_reset(struct vfio_platform_device *vdev) | |
91 | { | 133 | { | |
134 | if (VFIO_PLATFORM_IS_ACPI(vdev)) | |||
135 | return; | |||
136 | ||||
92 | if (vdev->of_reset) | 137 | if (vdev->of_reset) | |
93 | module_put(vdev->reset_module); | 138 | module_put(vdev->reset_module); | |
94 | } | 139 | } | |
@@ -164,7 +209,10 @@ static void vfio_platform_regions_cleanup(struct vfio_platform_device *vdev) | ||||
164 | static int vfio_platform_call_reset(struct vfio_platform_device *vdev, | 209 | static int vfio_platform_call_reset(struct vfio_platform_device *vdev, | |
165 | const char **extra_dbg) | 210 | const char **extra_dbg) | |
166 | { | 211 | { | |
167 | if (vdev->of_reset) { | 212 | if (VFIO_PLATFORM_IS_ACPI(vdev)) { | |
213 | dev_info(vdev->device, "reset\n"); | |||
214 | return vfio_platform_acpi_call_reset(vdev, extra_dbg); | |||
215 | } else if (vdev->of_reset) { | |||
168 | dev_info(vdev->device, "reset\n"); | 216 | dev_info(vdev->device, "reset\n"); | |
169 | return vdev->of_reset(vdev); | 217 | return vdev->of_reset(vdev); | |
170 | } | 218 | } | |