aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/virtio
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-01-17 18:20:10 -0500
committerDave Airlie <airlied@redhat.com>2019-01-17 18:31:28 -0500
commitf164a94c2c87752caeb1a3cbe068c440e7f7921f (patch)
treee914296ef0ce1df83e506a12bf4306d5aa468b24 /drivers/gpu/drm/virtio
parentb122153c7198e35fcb981ca9efd63b0df8ef3eab (diff)
parent94520db52fc0e931327bb77fe79a952a0e9dd2b0 (diff)
Merge tag 'drm-misc-next-2019-01-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.1: UAPI Changes: - New fourcc identifier for ARM Framebuffer Compression v1.3 Cross-subsystem Changes: Core Changes: - Reorganisation of drm_device and drm_framebuffer headers - Cleanup of the drmP inclusion - Fix leaks in the fb-helpers - Allow for depth different from bpp in fb-helper fbdev emulation - Remove drm_mode_object from drm_display_mode Driver Changes: - Add reflection properties to rockchip - a bunch of fixes for virtio - a bunch of fixes for dp_mst and drivers using it, and introduction of a new refcounting scheme - Convertion of bochs to atomic and generic fbdev emulation - Allow meson to remove the firmware framebuffers [airlied: patch rcar-du to add drm_modes.h] Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190116200428.u2n4jbk4mzza7n6e@flea
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r--drivers/gpu/drm/virtio/Makefile2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c7
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drm_bus.c103
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c79
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h10
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_fence.c8
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ioctl.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_kms.c10
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c17
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_vq.c12
10 files changed, 105 insertions, 145 deletions
diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile
index f29deec83d1f..4e90cc8fa651 100644
--- a/drivers/gpu/drm/virtio/Makefile
+++ b/drivers/gpu/drm/virtio/Makefile
@@ -3,7 +3,7 @@
3# Makefile for the drm device driver. This driver provides support for the 3# Makefile for the drm device driver. This driver provides support for the
4# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 4# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
5 5
6virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ 6virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \
7 virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ 7 virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \
8 virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ 8 virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \
9 virtgpu_ioctl.o virtgpu_prime.o 9 virtgpu_ioctl.o virtgpu_prime.o
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index e1c223e18d86..87d7c49cf057 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -243,12 +243,8 @@ static enum drm_connector_status virtio_gpu_conn_detect(
243 243
244static void virtio_gpu_conn_destroy(struct drm_connector *connector) 244static void virtio_gpu_conn_destroy(struct drm_connector *connector)
245{ 245{
246 struct virtio_gpu_output *virtio_gpu_output =
247 drm_connector_to_virtio_gpu_output(connector);
248
249 drm_connector_unregister(connector); 246 drm_connector_unregister(connector);
250 drm_connector_cleanup(connector); 247 drm_connector_cleanup(connector);
251 kfree(virtio_gpu_output);
252} 248}
253 249
254static const struct drm_connector_funcs virtio_gpu_connector_funcs = { 250static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
@@ -362,7 +358,7 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = {
362 .atomic_commit = drm_atomic_helper_commit, 358 .atomic_commit = drm_atomic_helper_commit,
363}; 359};
364 360
365int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) 361void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
366{ 362{
367 int i; 363 int i;
368 364
@@ -381,7 +377,6 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
381 vgdev_output_init(vgdev, i); 377 vgdev_output_init(vgdev, i);
382 378
383 drm_mode_config_reset(vgdev->ddev); 379 drm_mode_config_reset(vgdev->ddev);
384 return 0;
385} 380}
386 381
387void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) 382void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
deleted file mode 100644
index 0887e0b64b9c..000000000000
--- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 * Copyright (C) 2015 Red Hat, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include <linux/pci.h>
27#include <drm/drm_fb_helper.h>
28
29#include "virtgpu_drv.h"
30
31int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)
32{
33 struct drm_device *dev;
34 int ret;
35
36 dev = drm_dev_alloc(driver, &vdev->dev);
37 if (IS_ERR(dev))
38 return PTR_ERR(dev);
39 vdev->priv = dev;
40
41 if (strcmp(vdev->dev.parent->bus->name, "pci") == 0) {
42 struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
43 const char *pname = dev_name(&pdev->dev);
44 bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
45 char unique[20];
46
47 DRM_INFO("pci: %s detected at %s\n",
48 vga ? "virtio-vga" : "virtio-gpu-pci",
49 pname);
50 dev->pdev = pdev;
51 if (vga)
52 drm_fb_helper_remove_conflicting_pci_framebuffers(pdev,
53 0,
54 "virtiodrmfb");
55
56 /*
57 * Normally the drm_dev_set_unique() call is done by core DRM.
58 * The following comment covers, why virtio cannot rely on it.
59 *
60 * Unlike the other virtual GPU drivers, virtio abstracts the
61 * underlying bus type by using struct virtio_device.
62 *
63 * Hence the dev_is_pci() check, used in core DRM, will fail
64 * and the unique returned will be the virtio_device "virtio0",
65 * while a "pci:..." one is required.
66 *
67 * A few other ideas were considered:
68 * - Extend the dev_is_pci() check [in drm_set_busid] to
69 * consider virtio.
70 * Seems like a bigger hack than what we have already.
71 *
72 * - Point drm_device::dev to the parent of the virtio_device
73 * Semantic changes:
74 * * Using the wrong device for i2c, framebuffer_alloc and
75 * prime import.
76 * Visual changes:
77 * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer,
78 * will print the wrong information.
79 *
80 * We could address the latter issues, by introducing
81 * drm_device::bus_dev, ... which would be used solely for this.
82 *
83 * So for the moment keep things as-is, with a bulky comment
84 * for the next person who feels like removing this
85 * drm_dev_set_unique() quirk.
86 */
87 snprintf(unique, sizeof(unique), "pci:%s", pname);
88 ret = drm_dev_set_unique(dev, unique);
89 if (ret)
90 goto err_free;
91
92 }
93
94 ret = drm_dev_register(dev, 0);
95 if (ret)
96 goto err_free;
97
98 return 0;
99
100err_free:
101 drm_dev_put(dev);
102 return ret;
103}
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 7df50920c1e0..af92964b6889 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -40,8 +40,60 @@ static int virtio_gpu_modeset = -1;
40MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 40MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
41module_param_named(modeset, virtio_gpu_modeset, int, 0400); 41module_param_named(modeset, virtio_gpu_modeset, int, 0400);
42 42
43static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vdev)
44{
45 struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
46 const char *pname = dev_name(&pdev->dev);
47 bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
48 char unique[20];
49
50 DRM_INFO("pci: %s detected at %s\n",
51 vga ? "virtio-vga" : "virtio-gpu-pci",
52 pname);
53 dev->pdev = pdev;
54 if (vga)
55 drm_fb_helper_remove_conflicting_pci_framebuffers(pdev,
56 0,
57 "virtiodrmfb");
58
59 /*
60 * Normally the drm_dev_set_unique() call is done by core DRM.
61 * The following comment covers, why virtio cannot rely on it.
62 *
63 * Unlike the other virtual GPU drivers, virtio abstracts the
64 * underlying bus type by using struct virtio_device.
65 *
66 * Hence the dev_is_pci() check, used in core DRM, will fail
67 * and the unique returned will be the virtio_device "virtio0",
68 * while a "pci:..." one is required.
69 *
70 * A few other ideas were considered:
71 * - Extend the dev_is_pci() check [in drm_set_busid] to
72 * consider virtio.
73 * Seems like a bigger hack than what we have already.
74 *
75 * - Point drm_device::dev to the parent of the virtio_device
76 * Semantic changes:
77 * * Using the wrong device for i2c, framebuffer_alloc and
78 * prime import.
79 * Visual changes:
80 * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer,
81 * will print the wrong information.
82 *
83 * We could address the latter issues, by introducing
84 * drm_device::bus_dev, ... which would be used solely for this.
85 *
86 * So for the moment keep things as-is, with a bulky comment
87 * for the next person who feels like removing this
88 * drm_dev_set_unique() quirk.
89 */
90 snprintf(unique, sizeof(unique), "pci:%s", pname);
91 return drm_dev_set_unique(dev, unique);
92}
93
43static int virtio_gpu_probe(struct virtio_device *vdev) 94static int virtio_gpu_probe(struct virtio_device *vdev)
44{ 95{
96 struct drm_device *dev;
45 int ret; 97 int ret;
46 98
47 if (vgacon_text_force() && virtio_gpu_modeset == -1) 99 if (vgacon_text_force() && virtio_gpu_modeset == -1)
@@ -50,18 +102,39 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
50 if (virtio_gpu_modeset == 0) 102 if (virtio_gpu_modeset == 0)
51 return -EINVAL; 103 return -EINVAL;
52 104
53 ret = drm_virtio_init(&driver, vdev); 105 dev = drm_dev_alloc(&driver, &vdev->dev);
106 if (IS_ERR(dev))
107 return PTR_ERR(dev);
108 vdev->priv = dev;
109
110 if (!strcmp(vdev->dev.parent->bus->name, "pci")) {
111 ret = virtio_gpu_pci_quirk(dev, vdev);
112 if (ret)
113 goto err_free;
114 }
115
116 ret = virtio_gpu_init(dev);
54 if (ret) 117 if (ret)
55 return ret; 118 goto err_free;
119
120 ret = drm_dev_register(dev, 0);
121 if (ret)
122 goto err_free;
56 123
57 drm_fbdev_generic_setup(vdev->priv, 32); 124 drm_fbdev_generic_setup(vdev->priv, 32);
58 return 0; 125 return 0;
126
127err_free:
128 drm_dev_put(dev);
129 return ret;
59} 130}
60 131
61static void virtio_gpu_remove(struct virtio_device *vdev) 132static void virtio_gpu_remove(struct virtio_device *vdev)
62{ 133{
63 struct drm_device *dev = vdev->priv; 134 struct drm_device *dev = vdev->priv;
64 135
136 drm_dev_unregister(dev);
137 virtio_gpu_deinit(dev);
65 drm_put_dev(dev); 138 drm_put_dev(dev);
66} 139}
67 140
@@ -123,8 +196,6 @@ static const struct file_operations virtio_gpu_driver_fops = {
123 196
124static struct drm_driver driver = { 197static struct drm_driver driver = {
125 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, 198 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC,
126 .load = virtio_gpu_driver_load,
127 .unload = virtio_gpu_driver_unload,
128 .open = virtio_gpu_driver_open, 199 .open = virtio_gpu_driver_open,
129 .postclose = virtio_gpu_driver_postclose, 200 .postclose = virtio_gpu_driver_postclose,
130 201
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 63704915f8ce..cf896d879382 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -50,9 +50,6 @@
50#define DRIVER_MINOR 1 50#define DRIVER_MINOR 1
51#define DRIVER_PATCHLEVEL 0 51#define DRIVER_PATCHLEVEL 0
52 52
53/* virtgpu_drm_bus.c */
54int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev);
55
56struct virtio_gpu_object { 53struct virtio_gpu_object {
57 struct drm_gem_object gem_base; 54 struct drm_gem_object gem_base;
58 uint32_t hw_res_handle; 55 uint32_t hw_res_handle;
@@ -209,8 +206,8 @@ struct virtio_gpu_fpriv {
209extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; 206extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
210 207
211/* virtio_kms.c */ 208/* virtio_kms.c */
212int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags); 209int virtio_gpu_init(struct drm_device *dev);
213void virtio_gpu_driver_unload(struct drm_device *dev); 210void virtio_gpu_deinit(struct drm_device *dev);
214int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); 211int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file);
215void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); 212void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file);
216 213
@@ -320,7 +317,7 @@ int virtio_gpu_framebuffer_init(struct drm_device *dev,
320 struct virtio_gpu_framebuffer *vgfb, 317 struct virtio_gpu_framebuffer *vgfb,
321 const struct drm_mode_fb_cmd2 *mode_cmd, 318 const struct drm_mode_fb_cmd2 *mode_cmd,
322 struct drm_gem_object *obj); 319 struct drm_gem_object *obj);
323int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); 320void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
324void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); 321void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
325 322
326/* virtio_gpu_plane.c */ 323/* virtio_gpu_plane.c */
@@ -337,7 +334,6 @@ int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma);
337/* virtio_gpu_fence.c */ 334/* virtio_gpu_fence.c */
338struct virtio_gpu_fence *virtio_gpu_fence_alloc( 335struct virtio_gpu_fence *virtio_gpu_fence_alloc(
339 struct virtio_gpu_device *vgdev); 336 struct virtio_gpu_device *vgdev);
340void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence);
341int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, 337int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
342 struct virtio_gpu_ctrl_hdr *cmd_hdr, 338 struct virtio_gpu_ctrl_hdr *cmd_hdr,
343 struct virtio_gpu_fence *fence); 339 struct virtio_gpu_fence *fence);
diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c
index 4d6826b27814..21bd4c4a32d1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fence.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fence.c
@@ -81,14 +81,6 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev)
81 return fence; 81 return fence;
82} 82}
83 83
84void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence)
85{
86 if (!fence)
87 return;
88
89 dma_fence_put(&fence->f);
90}
91
92int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, 84int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
93 struct virtio_gpu_ctrl_hdr *cmd_hdr, 85 struct virtio_gpu_ctrl_hdr *cmd_hdr,
94 struct virtio_gpu_fence *fence) 86 struct virtio_gpu_fence *fence)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 161b80fee492..14ce8188c052 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -351,7 +351,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
351 virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d); 351 virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d);
352 ret = virtio_gpu_object_attach(vgdev, qobj, fence); 352 ret = virtio_gpu_object_attach(vgdev, qobj, fence);
353 if (ret) { 353 if (ret) {
354 virtio_gpu_fence_cleanup(fence); 354 dma_fence_put(&fence->f);
355 goto fail_backoff; 355 goto fail_backoff;
356 } 356 }
357 ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); 357 ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f);
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 1072064a0db2..84b6a6bf00c6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -106,7 +106,7 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev,
106 vgdev->num_capsets = num_capsets; 106 vgdev->num_capsets = num_capsets;
107} 107}
108 108
109int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) 109int virtio_gpu_init(struct drm_device *dev)
110{ 110{
111 static vq_callback_t *callbacks[] = { 111 static vq_callback_t *callbacks[] = {
112 virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack 112 virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack
@@ -193,9 +193,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
193 num_capsets, &num_capsets); 193 num_capsets, &num_capsets);
194 DRM_INFO("number of cap sets: %d\n", num_capsets); 194 DRM_INFO("number of cap sets: %d\n", num_capsets);
195 195
196 ret = virtio_gpu_modeset_init(vgdev); 196 virtio_gpu_modeset_init(vgdev);
197 if (ret)
198 goto err_modeset;
199 197
200 virtio_device_ready(vgdev->vdev); 198 virtio_device_ready(vgdev->vdev);
201 vgdev->vqs_ready = true; 199 vgdev->vqs_ready = true;
@@ -209,7 +207,6 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
209 5 * HZ); 207 5 * HZ);
210 return 0; 208 return 0;
211 209
212err_modeset:
213err_scanouts: 210err_scanouts:
214 virtio_gpu_ttm_fini(vgdev); 211 virtio_gpu_ttm_fini(vgdev);
215err_ttm: 212err_ttm:
@@ -231,7 +228,7 @@ static void virtio_gpu_cleanup_cap_cache(struct virtio_gpu_device *vgdev)
231 } 228 }
232} 229}
233 230
234void virtio_gpu_driver_unload(struct drm_device *dev) 231void virtio_gpu_deinit(struct drm_device *dev)
235{ 232{
236 struct virtio_gpu_device *vgdev = dev->dev_private; 233 struct virtio_gpu_device *vgdev = dev->dev_private;
237 234
@@ -239,6 +236,7 @@ void virtio_gpu_driver_unload(struct drm_device *dev)
239 flush_work(&vgdev->ctrlq.dequeue_work); 236 flush_work(&vgdev->ctrlq.dequeue_work);
240 flush_work(&vgdev->cursorq.dequeue_work); 237 flush_work(&vgdev->cursorq.dequeue_work);
241 flush_work(&vgdev->config_changed_work); 238 flush_work(&vgdev->config_changed_work);
239 vgdev->vdev->config->reset(vgdev->vdev);
242 vgdev->vdev->config->del_vqs(vgdev->vdev); 240 vgdev->vdev->config->del_vqs(vgdev->vdev);
243 241
244 virtio_gpu_modeset_fini(vgdev); 242 virtio_gpu_modeset_fini(vgdev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index ead5c53d4e21..024c2aa0c929 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -130,11 +130,12 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
130 plane->state->src_h >> 16, 130 plane->state->src_h >> 16,
131 plane->state->src_x >> 16, 131 plane->state->src_x >> 16,
132 plane->state->src_y >> 16); 132 plane->state->src_y >> 16);
133 virtio_gpu_cmd_resource_flush(vgdev, handle, 133 if (handle)
134 plane->state->src_x >> 16, 134 virtio_gpu_cmd_resource_flush(vgdev, handle,
135 plane->state->src_y >> 16, 135 plane->state->src_x >> 16,
136 plane->state->src_w >> 16, 136 plane->state->src_y >> 16,
137 plane->state->src_h >> 16); 137 plane->state->src_w >> 16,
138 plane->state->src_h >> 16);
138} 139}
139 140
140static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, 141static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
@@ -168,8 +169,10 @@ static void virtio_gpu_cursor_cleanup_fb(struct drm_plane *plane,
168 return; 169 return;
169 170
170 vgfb = to_virtio_gpu_framebuffer(plane->state->fb); 171 vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
171 if (vgfb->fence) 172 if (vgfb->fence) {
172 virtio_gpu_fence_cleanup(vgfb->fence); 173 dma_fence_put(&vgfb->fence->f);
174 vgfb->fence = NULL;
175 }
173} 176}
174 177
175static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, 178static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index e27c4aedb809..6bc2008b0d0d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -192,8 +192,16 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work)
192 192
193 list_for_each_entry_safe(entry, tmp, &reclaim_list, list) { 193 list_for_each_entry_safe(entry, tmp, &reclaim_list, list) {
194 resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf; 194 resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf;
195 if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) 195 if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) {
196 DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); 196 if (resp->type >= cpu_to_le32(VIRTIO_GPU_RESP_ERR_UNSPEC)) {
197 struct virtio_gpu_ctrl_hdr *cmd;
198 cmd = (struct virtio_gpu_ctrl_hdr *)entry->buf;
199 DRM_ERROR("response 0x%x (command 0x%x)\n",
200 le32_to_cpu(resp->type),
201 le32_to_cpu(cmd->type));
202 } else
203 DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type));
204 }
197 if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) { 205 if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) {
198 u64 f = le64_to_cpu(resp->fence_id); 206 u64 f = le64_to_cpu(resp->fence_id);
199 207