Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/vc4: Use the atomic state's commit workqueue.

Now that we're using the atomic helpers for fence waits, we can use
the same codepath as drm_atomic_helper_commit() does for async,
getting rid of our custom vc4_commit struct.

Signed-off-by: Eric Anholt <eric@anholt.net>
Link: http://patchwork.freedesktop.org/patch/msgid/20170621185002.28563-3-eric@anholt.net
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>

+13 -58
+13 -58
drivers/gpu/drm/vc4/vc4_kms.c
··· 29 29 drm_fbdev_cma_hotplug_event(vc4->fbdev); 30 30 } 31 31 32 - struct vc4_commit { 33 - struct drm_device *dev; 34 - struct drm_atomic_state *state; 35 - struct vc4_seqno_cb cb; 36 - }; 37 - 38 32 static void 39 - vc4_atomic_complete_commit(struct vc4_commit *c) 33 + vc4_atomic_complete_commit(struct drm_atomic_state *state) 40 34 { 41 - struct drm_atomic_state *state = c->state; 42 35 struct drm_device *dev = state->dev; 43 36 struct vc4_dev *vc4 = to_vc4_dev(dev); 44 37 ··· 65 72 drm_atomic_state_put(state); 66 73 67 74 up(&vc4->async_modeset); 68 - 69 - kfree(c); 70 75 } 71 76 72 - static void 73 - vc4_atomic_complete_commit_seqno_cb(struct vc4_seqno_cb *cb) 77 + static void commit_work(struct work_struct *work) 74 78 { 75 - struct vc4_commit *c = container_of(cb, struct vc4_commit, cb); 76 - 77 - vc4_atomic_complete_commit(c); 78 - } 79 - 80 - static struct vc4_commit *commit_init(struct drm_atomic_state *state) 81 - { 82 - struct vc4_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); 83 - 84 - if (!c) 85 - return NULL; 86 - c->dev = state->dev; 87 - c->state = state; 88 - 89 - return c; 79 + struct drm_atomic_state *state = container_of(work, 80 + struct drm_atomic_state, 81 + commit_work); 82 + vc4_atomic_complete_commit(state); 90 83 } 91 84 92 85 /** ··· 94 115 { 95 116 struct vc4_dev *vc4 = to_vc4_dev(dev); 96 117 int ret; 97 - int i; 98 - uint64_t wait_seqno = 0; 99 - struct vc4_commit *c; 100 - struct drm_plane *plane; 101 - struct drm_plane_state *new_state; 102 - 103 - c = commit_init(state); 104 - if (!c) 105 - return -ENOMEM; 106 118 107 119 ret = drm_atomic_helper_setup_commit(state, nonblock); 108 120 if (ret) 109 121 return ret; 110 122 123 + INIT_WORK(&state->commit_work, commit_work); 124 + 111 125 ret = down_interruptible(&vc4->async_modeset); 112 - if (ret) { 113 - kfree(c); 126 + if (ret) 114 127 return ret; 115 - } 116 128 117 129 ret = drm_atomic_helper_prepare_planes(dev, state); 118 130 if (ret) { 119 - kfree(c); 120 131 up(&vc4->async_modeset); 121 132 return ret; 122 133 } ··· 115 146 ret = drm_atomic_helper_wait_for_fences(dev, state, true); 116 147 if (ret) { 117 148 drm_atomic_helper_cleanup_planes(dev, state); 118 - kfree(c); 119 149 up(&vc4->async_modeset); 120 150 return ret; 121 - } 122 - } 123 - 124 - for_each_plane_in_state(state, plane, new_state, i) { 125 - if ((plane->state->fb != new_state->fb) && new_state->fb) { 126 - struct drm_gem_cma_object *cma_bo = 127 - drm_fb_cma_get_gem_obj(new_state->fb, 0); 128 - struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); 129 - 130 - wait_seqno = max(bo->seqno, wait_seqno); 131 151 } 132 152 } 133 153 ··· 145 187 */ 146 188 147 189 drm_atomic_state_get(state); 148 - if (nonblock) { 149 - vc4_queue_seqno_cb(dev, &c->cb, wait_seqno, 150 - vc4_atomic_complete_commit_seqno_cb); 151 - } else { 152 - vc4_wait_for_seqno(dev, wait_seqno, ~0ull, false); 153 - vc4_atomic_complete_commit(c); 154 - } 190 + if (nonblock) 191 + queue_work(system_unbound_wq, &state->commit_work); 192 + else 193 + vc4_atomic_complete_commit(state); 155 194 156 195 return 0; 157 196 }