diff options
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 : false; |
| 77 | } | 116 | } |
| 78 | 117 | ||
| 79 | static void vfio_platform_get_reset(struct vfio_platform_device *vdev) | 118 | static void vfio_platform_get_reset(struct vfio_platform_device *vdev) |
| 80 | { | 119 | { |
| 120 | if (VFIO_PLATFORM_IS_ACPI(vdev)) | ||
| 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 | } |
