History

Merge tag 'drm-misc-fixes-2022-04-22' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

Two fixes for the raspberrypi panel initialisation, one fix for a logic inversion in radeon, a build and pm refcounting fix for vc4, two reverts for drm_of_get_bridge that caused a number of regression and a locking regression for amdgpu. Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 4 years ago

Commit c18a2a22 parents 70da382 94f4c4912 files · +94 −358Browse files

Unified · Split

12 files
  1. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +15 −6
  2. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +2 −0
  3. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h +1 −0
  4. drivers/gpu/drm/drm_of.c +33 −51
  5. drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +10 −3
  6. drivers/gpu/drm/radeon/radeon_sync.c +1 −1
  7. drivers/gpu/drm/vc4/Kconfig +3 −0
  8. drivers/gpu/drm/vc4/vc4_dsi.c +1 −1
  9. drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +20 −23
  10. drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +2 −6
  11. drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +6 −1
  12. include/linux/dma-buf-map.h +0 −266
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+15−6
@@ -128,6 +128,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs · 127 unmodified lines
128 goto free_chunk;128 goto free_chunk;
129 }129 }
130 130
131 mutex_lock(&p->ctx->lock);
132
131 /* skip guilty context job */133 /* skip guilty context job */
132 if (atomic_read(&p->ctx->guilty) == 1) {134 if (atomic_read(&p->ctx->guilty) == 1) {
133 ret = -ECANCELED;135 ret = -ECANCELED;
@@ -709,6 +711,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, · 575 unmodified lines
709 dma_fence_put(parser->fence);711 dma_fence_put(parser->fence);
710 712
711 if (parser->ctx) {713 if (parser->ctx) {
714 mutex_unlock(&parser->ctx->lock);
712 amdgpu_ctx_put(parser->ctx);715 amdgpu_ctx_put(parser->ctx);
713 }716 }
714 if (parser->bo_list)717 if (parser->bo_list)
@@ -1157,6 +1160,9 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 442 unmodified lines
1157{1160{
1158 int i, r;1161 int i, r;
1159 1162
1163 /* TODO: Investigate why we still need the context lock */
1164 mutex_unlock(&p->ctx->lock);
1165
1160 for (i = 0; i < p->nchunks; ++i) {1166 for (i = 0; i < p->nchunks; ++i) {
1161 struct amdgpu_cs_chunk *chunk;1167 struct amdgpu_cs_chunk *chunk;
1162 1168
@@ -1167,32 +1173,34 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 4 unmodified lines
1167 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:1173 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
1168 r = amdgpu_cs_process_fence_dep(p, chunk);1174 r = amdgpu_cs_process_fence_dep(p, chunk);
1169 if (r)1175 if (r)
1170 return r;1176 goto out;
1171 break;1177 break;
1172 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:1178 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
1173 r = amdgpu_cs_process_syncobj_in_dep(p, chunk);1179 r = amdgpu_cs_process_syncobj_in_dep(p, chunk);
1174 if (r)1180 if (r)
1175 return r;1181 goto out;
1176 break;1182 break;
1177 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:1183 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
1178 r = amdgpu_cs_process_syncobj_out_dep(p, chunk);1184 r = amdgpu_cs_process_syncobj_out_dep(p, chunk);
1179 if (r)1185 if (r)
1180 return r;1186 goto out;
1181 break;1187 break;
1182 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:1188 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
1183 r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);1189 r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);
1184 if (r)1190 if (r)
1185 return r;1191 goto out;
1186 break;1192 break;
1187 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:1193 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
1188 r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);1194 r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);
1189 if (r)1195 if (r)
1190 return r;1196 goto out;
1191 break;1197 break;
1192 }1198 }
1193 }1199 }
1194 1200
1195 return 0;1201out:
1202 mutex_lock(&p->ctx->lock);
1203 return r;
1196}1204}
1197 1205
1198static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)1206static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
@@ -1368,6 +1376,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 169 unmodified lines
1368 goto out;1376 goto out;
1369 1377
1370 r = amdgpu_cs_submit(&parser, cs);1378 r = amdgpu_cs_submit(&parser, cs);
1379
1371out:1380out:
1372 amdgpu_cs_parser_fini(&parser, r, reserved_buffers);1381 amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
1373 1382
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c+2−0
@@ -237,6 +237,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, · 236 unmodified lines
237 237
238 kref_init(&ctx->refcount);238 kref_init(&ctx->refcount);
239 spin_lock_init(&ctx->ring_lock);239 spin_lock_init(&ctx->ring_lock);
240 mutex_init(&ctx->lock);
240 241
241 ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);242 ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
242 ctx->reset_counter_query = ctx->reset_counter;243 ctx->reset_counter_query = ctx->reset_counter;
@@ -357,6 +358,7 @@ static void amdgpu_ctx_fini(struct kref *ref) · 114 unmodified lines
357 drm_dev_exit(idx);358 drm_dev_exit(idx);
358 }359 }
359 360
361 mutex_destroy(&ctx->lock);
360 kfree(ctx);362 kfree(ctx);
361}363}
362 364
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h+1−0
@@ -49,6 +49,7 @@ struct amdgpu_ctx { · 48 unmodified lines
49 bool preamble_presented;49 bool preamble_presented;
50 int32_t init_priority;50 int32_t init_priority;
51 int32_t override_priority;51 int32_t override_priority;
52 struct mutex lock;
52 atomic_t guilty;53 atomic_t guilty;
53 unsigned long ras_counter_ce;54 unsigned long ras_counter_ce;
54 unsigned long ras_counter_ue;55 unsigned long ras_counter_ue;
drivers/gpu/drm/drm_of.c+33−51
@@ -214,29 +214,6 @@ int drm_of_encoder_active_endpoint(struct device_node *node, · 213 unmodified lines
214}214}
215EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);215EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
216 216
217static int find_panel_or_bridge(struct device_node *node,
218 struct drm_panel **panel,
219 struct drm_bridge **bridge)
220{
221 if (panel) {
222 *panel = of_drm_find_panel(node);
223 if (!IS_ERR(*panel))
224 return 0;
225
226 /* Clear the panel pointer in case of error. */
227 *panel = NULL;
228 }
229
230 /* No panel found yet, check for a bridge next. */
231 if (bridge) {
232 *bridge = of_drm_find_bridge(node);
233 if (*bridge)
234 return 0;
235 }
236
237 return -EPROBE_DEFER;
238}
239
240/**217/**
241 * drm_of_find_panel_or_bridge - return connected panel or bridge device218 * drm_of_find_panel_or_bridge - return connected panel or bridge device
242 * @np: device tree node containing encoder output ports219 * @np: device tree node containing encoder output ports
@@ -259,44 +236,49 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, · 16 unmodified lines
259 struct drm_panel **panel,236 struct drm_panel **panel,
260 struct drm_bridge **bridge)237 struct drm_bridge **bridge)
261{238{
262 struct device_node *node;239 int ret = -EPROBE_DEFER;
263 int ret;240 struct device_node *remote;
264 241
265 if (!panel && !bridge)242 if (!panel && !bridge)
266 return -EINVAL;243 return -EINVAL;
267
268 if (panel)244 if (panel)
269 *panel = NULL;245 *panel = NULL;
270 if (bridge)
271 *bridge = NULL;
272
273 /* Check for a graph on the device node first. */
274 if (of_graph_is_present(np)) {
275 node = of_graph_get_remote_node(np, port, endpoint);
276 if (node) {
277 ret = find_panel_or_bridge(node, panel, bridge);
278 of_node_put(node);
279
280 if (!ret)
281 return 0;
282 }
283 }
284 246
285 /* Otherwise check for any child node other than port/ports. */247 /*
286 for_each_available_child_of_node(np, node) {248 * of_graph_get_remote_node() produces a noisy error message if port
287 if (of_node_name_eq(node, "port") ||249 * node isn't found and the absence of the port is a legit case here,
288 of_node_name_eq(node, "ports"))250 * so at first we silently check whether graph presents in the
289 continue;251 * device-tree node.
252 */
253 if (!of_graph_is_present(np))
254 return -ENODEV;
290 255
291 ret = find_panel_or_bridge(node, panel, bridge);256 remote = of_graph_get_remote_node(np, port, endpoint);
292 of_node_put(node);257 if (!remote)
258 return -ENODEV;
259
260 if (panel) {
261 *panel = of_drm_find_panel(remote);
262 if (!IS_ERR(*panel))
263 ret = 0;
264 else
265 *panel = NULL;
266 }
267
268 /* No panel found yet, check for a bridge next. */
269 if (bridge) {
270 if (ret) {
271 *bridge = of_drm_find_bridge(remote);
272 if (*bridge)
273 ret = 0;
274 } else {
275 *bridge = NULL;
276 }
293 277
294 /* Stop at the first found occurrence. */
295 if (!ret)
296 return 0;
297 }278 }
298 279
299 return -EPROBE_DEFER;280 of_node_put(remote);
281 return ret;
300}282}
301EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);283EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
302 284
drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c+10−3
@@ -229,7 +229,7 @@ static void rpi_touchscreen_i2c_write(struct rpi_touchscreen *ts, · 228 unmodified lines
229 229
230 ret = i2c_smbus_write_byte_data(ts->i2c, reg, val);230 ret = i2c_smbus_write_byte_data(ts->i2c, reg, val);
231 if (ret)231 if (ret)
232 dev_err(&ts->dsi->dev, "I2C write failed: %d\n", ret);232 dev_err(&ts->i2c->dev, "I2C write failed: %d\n", ret);
233}233}
234 234
235static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val)235static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val)
@@ -265,7 +265,7 @@ static int rpi_touchscreen_noop(struct drm_panel *panel) · 29 unmodified lines
265 return 0;265 return 0;
266}266}
267 267
268static int rpi_touchscreen_enable(struct drm_panel *panel)268static int rpi_touchscreen_prepare(struct drm_panel *panel)
269{269{
270 struct rpi_touchscreen *ts = panel_to_ts(panel);270 struct rpi_touchscreen *ts = panel_to_ts(panel);
271 int i;271 int i;
@@ -295,6 +295,13 @@ static int rpi_touchscreen_enable(struct drm_panel *panel) · 23 unmodified lines
295 rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01);295 rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01);
296 msleep(100);296 msleep(100);
297 297
298 return 0;
299}
300
301static int rpi_touchscreen_enable(struct drm_panel *panel)
302{
303 struct rpi_touchscreen *ts = panel_to_ts(panel);
304
298 /* Turn on the backlight. */305 /* Turn on the backlight. */
299 rpi_touchscreen_i2c_write(ts, REG_PWM, 255);306 rpi_touchscreen_i2c_write(ts, REG_PWM, 255);
300 307
@@ -349,7 +356,7 @@ static int rpi_touchscreen_get_modes(struct drm_panel *panel, · 48 unmodified lines
349static const struct drm_panel_funcs rpi_touchscreen_funcs = {356static const struct drm_panel_funcs rpi_touchscreen_funcs = {
350 .disable = rpi_touchscreen_disable,357 .disable = rpi_touchscreen_disable,
351 .unprepare = rpi_touchscreen_noop,358 .unprepare = rpi_touchscreen_noop,
352 .prepare = rpi_touchscreen_noop,359 .prepare = rpi_touchscreen_prepare,
353 .enable = rpi_touchscreen_enable,360 .enable = rpi_touchscreen_enable,
354 .get_modes = rpi_touchscreen_get_modes,361 .get_modes = rpi_touchscreen_get_modes,
355};362};
drivers/gpu/drm/radeon/radeon_sync.c+1−1
@@ -96,7 +96,7 @@ int radeon_sync_resv(struct radeon_device *rdev, · 95 unmodified lines
96 struct dma_fence *f;96 struct dma_fence *f;
97 int r = 0;97 int r = 0;
98 98
99 dma_resv_for_each_fence(&cursor, resv, shared, f) {99 dma_resv_for_each_fence(&cursor, resv, !shared, f) {
100 fence = to_radeon_fence(f);100 fence = to_radeon_fence(f);
101 if (fence && fence->rdev == rdev)101 if (fence && fence->rdev == rdev)
102 radeon_sync_fence(sync, fence);102 radeon_sync_fence(sync, fence);
drivers/gpu/drm/vc4/Kconfig+3−0
@@ -2,6 +2,9 @@ · 1 unmodified line
2config DRM_VC42config DRM_VC4
3 tristate "Broadcom VC4 Graphics"3 tristate "Broadcom VC4 Graphics"
4 depends on ARCH_BCM || ARCH_BCM2835 || COMPILE_TEST4 depends on ARCH_BCM || ARCH_BCM2835 || COMPILE_TEST
5 # Make sure not 'y' when RASPBERRYPI_FIRMWARE is 'm'. This can only
6 # happen when COMPILE_TEST=y, hence the added !RASPBERRYPI_FIRMWARE.
7 depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
5 depends on DRM8 depends on DRM
6 depends on SND && SND_SOC9 depends on SND && SND_SOC
7 depends on COMMON_CLK10 depends on COMMON_CLK
drivers/gpu/drm/vc4/vc4_dsi.c+1−1
@@ -846,7 +846,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) · 845 unmodified lines
846 unsigned long phy_clock;846 unsigned long phy_clock;
847 int ret;847 int ret;
848 848
849 ret = pm_runtime_get_sync(dev);849 ret = pm_runtime_resume_and_get(dev);
850 if (ret) {850 if (ret) {
851 DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port);851 DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port);
852 return;852 return;
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c+20−23
@@ -46,6 +46,21 @@ vmw_buffer_object(struct ttm_buffer_object *bo) · 45 unmodified lines
46 return container_of(bo, struct vmw_buffer_object, base);46 return container_of(bo, struct vmw_buffer_object, base);
47}47}
48 48
49/**
50 * bo_is_vmw - check if the buffer object is a &vmw_buffer_object
51 * @bo: ttm buffer object to be checked
52 *
53 * Uses destroy function associated with the object to determine if this is
54 * a &vmw_buffer_object.
55 *
56 * Returns:
57 * true if the object is of &vmw_buffer_object type, false if not.
58 */
59static bool bo_is_vmw(struct ttm_buffer_object *bo)
60{
61 return bo->destroy == &vmw_bo_bo_free ||
62 bo->destroy == &vmw_gem_destroy;
63}
49 64
50/**65/**
51 * vmw_bo_pin_in_placement - Validate a buffer to placement.66 * vmw_bo_pin_in_placement - Validate a buffer to placement.
@@ -615,8 +630,9 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, · 563 unmodified lines
615 630
616 ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);631 ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
617 vmw_bo_unreference(&vbo);632 vmw_bo_unreference(&vbo);
618 if (unlikely(ret != 0 && ret != -ERESTARTSYS &&633 if (unlikely(ret != 0)) {
619 ret != -EBUSY)) {634 if (ret == -ERESTARTSYS || ret == -EBUSY)
635 return -EBUSY;
620 DRM_ERROR("Failed synccpu grab on handle 0x%08x.\n",636 DRM_ERROR("Failed synccpu grab on handle 0x%08x.\n",
621 (unsigned int) arg->handle);637 (unsigned int) arg->handle);
622 return ret;638 return ret;
@@ -798,7 +814,7 @@ int vmw_dumb_create(struct drm_file *file_priv, · 175 unmodified lines
798void vmw_bo_swap_notify(struct ttm_buffer_object *bo)814void vmw_bo_swap_notify(struct ttm_buffer_object *bo)
799{815{
800 /* Is @bo embedded in a struct vmw_buffer_object? */816 /* Is @bo embedded in a struct vmw_buffer_object? */
801 if (vmw_bo_is_vmw_bo(bo))817 if (!bo_is_vmw(bo))
802 return;818 return;
803 819
804 /* Kill any cached kernel maps before swapout */820 /* Kill any cached kernel maps before swapout */
@@ -822,7 +838,7 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, · 17 unmodified lines
822 struct vmw_buffer_object *vbo;838 struct vmw_buffer_object *vbo;
823 839
824 /* Make sure @bo is embedded in a struct vmw_buffer_object? */840 /* Make sure @bo is embedded in a struct vmw_buffer_object? */
825 if (vmw_bo_is_vmw_bo(bo))841 if (!bo_is_vmw(bo))
826 return;842 return;
827 843
828 vbo = container_of(bo, struct vmw_buffer_object, base);844 vbo = container_of(bo, struct vmw_buffer_object, base);
@@ -843,22 +859,3 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, · 14 unmodified lines
843 if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB)859 if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB)
844 vmw_resource_unbind_list(vbo);860 vmw_resource_unbind_list(vbo);
845}861}
846
847/**
848 * vmw_bo_is_vmw_bo - check if the buffer object is a &vmw_buffer_object
849 * @bo: buffer object to be checked
850 *
851 * Uses destroy function associated with the object to determine if this is
852 * a &vmw_buffer_object.
853 *
854 * Returns:
855 * true if the object is of &vmw_buffer_object type, false if not.
856 */
857bool vmw_bo_is_vmw_bo(struct ttm_buffer_object *bo)
858{
859 if (bo->destroy == &vmw_bo_bo_free ||
860 bo->destroy == &vmw_gem_destroy)
861 return true;
862
863 return false;
864}
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c+2−6
@@ -998,13 +998,10 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) · 997 unmodified lines
998 goto out_no_fman;998 goto out_no_fman;
999 }999 }
1000 1000
1001 drm_vma_offset_manager_init(&dev_priv->vma_manager,
1002 DRM_FILE_PAGE_OFFSET_START,
1003 DRM_FILE_PAGE_OFFSET_SIZE);
1004 ret = ttm_device_init(&dev_priv->bdev, &vmw_bo_driver,1001 ret = ttm_device_init(&dev_priv->bdev, &vmw_bo_driver,
1005 dev_priv->drm.dev,1002 dev_priv->drm.dev,
1006 dev_priv->drm.anon_inode->i_mapping,1003 dev_priv->drm.anon_inode->i_mapping,
1007 &dev_priv->vma_manager,1004 dev_priv->drm.vma_offset_manager,
1008 dev_priv->map_mode == vmw_dma_alloc_coherent,1005 dev_priv->map_mode == vmw_dma_alloc_coherent,
1009 false);1006 false);
1010 if (unlikely(ret != 0)) {1007 if (unlikely(ret != 0)) {
@@ -1174,7 +1171,6 @@ static void vmw_driver_unload(struct drm_device *dev) · 163 unmodified lines
1174 vmw_devcaps_destroy(dev_priv);1171 vmw_devcaps_destroy(dev_priv);
1175 vmw_vram_manager_fini(dev_priv);1172 vmw_vram_manager_fini(dev_priv);
1176 ttm_device_fini(&dev_priv->bdev);1173 ttm_device_fini(&dev_priv->bdev);
1177 drm_vma_offset_manager_destroy(&dev_priv->vma_manager);
1178 vmw_release_device_late(dev_priv);1174 vmw_release_device_late(dev_priv);
1179 vmw_fence_manager_takedown(dev_priv->fman);1175 vmw_fence_manager_takedown(dev_priv->fman);
1180 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)1176 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
@@ -1398,7 +1394,7 @@ vmw_get_unmapped_area(struct file *file, unsigned long uaddr, · 217 unmodified lines
1398 struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev);1394 struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev);
1399 1395
1400 return drm_get_unmapped_area(file, uaddr, len, pgoff, flags,1396 return drm_get_unmapped_area(file, uaddr, len, pgoff, flags,
1401 &dev_priv->vma_manager);1397 dev_priv->drm.vma_offset_manager);
1402}1398}
1403 1399
1404static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,1400static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c+6−1
@@ -683,6 +683,9 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base) · 682 unmodified lines
683 container_of(base, struct vmw_user_surface, prime.base);683 container_of(base, struct vmw_user_surface, prime.base);
684 struct vmw_resource *res = &user_srf->srf.res;684 struct vmw_resource *res = &user_srf->srf.res;
685 685
686 if (base->shareable && res && res->backup)
687 drm_gem_object_put(&res->backup->base.base);
688
686 *p_base = NULL;689 *p_base = NULL;
687 vmw_resource_unreference(&res);690 vmw_resource_unreference(&res);
688}691}
@@ -857,6 +860,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, · 168 unmodified lines
857 goto out_unlock;860 goto out_unlock;
858 }861 }
859 vmw_bo_reference(res->backup);862 vmw_bo_reference(res->backup);
863 drm_gem_object_get(&res->backup->base.base);
860 }864 }
861 865
862 tmp = vmw_resource_reference(&srf->res);866 tmp = vmw_resource_reference(&srf->res);
@@ -1513,7 +1517,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 650 unmodified lines
1513 &res->backup);1517 &res->backup);
1514 if (ret == 0)1518 if (ret == 0)
1515 vmw_bo_reference(res->backup);1519 vmw_bo_reference(res->backup);
1516
1517 }1520 }
1518 1521
1519 if (unlikely(ret != 0)) {1522 if (unlikely(ret != 0)) {
@@ -1561,6 +1564,8 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 41 unmodified lines
1561 drm_vma_node_offset_addr(&res->backup->base.base.vma_node);1564 drm_vma_node_offset_addr(&res->backup->base.base.vma_node);
1562 rep->buffer_size = res->backup->base.base.size;1565 rep->buffer_size = res->backup->base.base.size;
1563 rep->buffer_handle = backup_handle;1566 rep->buffer_handle = backup_handle;
1567 if (user_srf->prime.base.shareable)
1568 drm_gem_object_get(&res->backup->base.base);
1564 } else {1569 } else {
1565 rep->buffer_map_handle = 0;1570 rep->buffer_map_handle = 0;
1566 rep->buffer_size = 0;1571 rep->buffer_size = 0;
include/linux/dma-buf-map.h+0−266
@@ -1,266 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Pointer to dma-buf-mapped memory, plus helpers.
4 */
5
6#ifndef __DMA_BUF_MAP_H__
7#define __DMA_BUF_MAP_H__
8
9#include <linux/io.h>
10#include <linux/string.h>
11
12/**
13 * DOC: overview
14 *
15 * Calling dma-buf's vmap operation returns a pointer to the buffer's memory.
16 * Depending on the location of the buffer, users may have to access it with
17 * I/O operations or memory load/store operations. For example, copying to
18 * system memory could be done with memcpy(), copying to I/O memory would be
19 * done with memcpy_toio().
20 *
21 * .. code-block:: c
22 *
23 * void *vaddr = ...; // pointer to system memory
24 * memcpy(vaddr, src, len);
25 *
26 * void *vaddr_iomem = ...; // pointer to I/O memory
27 * memcpy_toio(vaddr, _iomem, src, len);
28 *
29 * When using dma-buf's vmap operation, the returned pointer is encoded as
30 * :c:type:`struct dma_buf_map <dma_buf_map>`.
31 * :c:type:`struct dma_buf_map <dma_buf_map>` stores the buffer's address in
32 * system or I/O memory and a flag that signals the required method of
33 * accessing the buffer. Use the returned instance and the helper functions
34 * to access the buffer's memory in the correct way.
35 *
36 * The type :c:type:`struct dma_buf_map <dma_buf_map>` and its helpers are
37 * actually independent from the dma-buf infrastructure. When sharing buffers
38 * among devices, drivers have to know the location of the memory to access
39 * the buffers in a safe way. :c:type:`struct dma_buf_map <dma_buf_map>`
40 * solves this problem for dma-buf and its users. If other drivers or
41 * sub-systems require similar functionality, the type could be generalized
42 * and moved to a more prominent header file.
43 *
44 * Open-coding access to :c:type:`struct dma_buf_map <dma_buf_map>` is
45 * considered bad style. Rather then accessing its fields directly, use one
46 * of the provided helper functions, or implement your own. For example,
47 * instances of :c:type:`struct dma_buf_map <dma_buf_map>` can be initialized
48 * statically with DMA_BUF_MAP_INIT_VADDR(), or at runtime with
49 * dma_buf_map_set_vaddr(). These helpers will set an address in system memory.
50 *
51 * .. code-block:: c
52 *
53 * struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(0xdeadbeaf);
54 *
55 * dma_buf_map_set_vaddr(&map, 0xdeadbeaf);
56 *
57 * To set an address in I/O memory, use dma_buf_map_set_vaddr_iomem().
58 *
59 * .. code-block:: c
60 *
61 * dma_buf_map_set_vaddr_iomem(&map, 0xdeadbeaf);
62 *
63 * Instances of struct dma_buf_map do not have to be cleaned up, but
64 * can be cleared to NULL with dma_buf_map_clear(). Cleared mappings
65 * always refer to system memory.
66 *
67 * .. code-block:: c
68 *
69 * dma_buf_map_clear(&map);
70 *
71 * Test if a mapping is valid with either dma_buf_map_is_set() or
72 * dma_buf_map_is_null().
73 *
74 * .. code-block:: c
75 *
76 * if (dma_buf_map_is_set(&map) != dma_buf_map_is_null(&map))
77 * // always true
78 *
79 * Instances of :c:type:`struct dma_buf_map <dma_buf_map>` can be compared
80 * for equality with dma_buf_map_is_equal(). Mappings the point to different
81 * memory spaces, system or I/O, are never equal. That's even true if both
82 * spaces are located in the same address space, both mappings contain the
83 * same address value, or both mappings refer to NULL.
84 *
85 * .. code-block:: c
86 *
87 * struct dma_buf_map sys_map; // refers to system memory
88 * struct dma_buf_map io_map; // refers to I/O memory
89 *
90 * if (dma_buf_map_is_equal(&sys_map, &io_map))
91 * // always false
92 *
93 * A set up instance of struct dma_buf_map can be used to access or manipulate
94 * the buffer memory. Depending on the location of the memory, the provided
95 * helpers will pick the correct operations. Data can be copied into the memory
96 * with dma_buf_map_memcpy_to(). The address can be manipulated with
97 * dma_buf_map_incr().
98 *
99 * .. code-block:: c
100 *
101 * const void *src = ...; // source buffer
102 * size_t len = ...; // length of src
103 *
104 * dma_buf_map_memcpy_to(&map, src, len);
105 * dma_buf_map_incr(&map, len); // go to first byte after the memcpy
106 */
107
108/**
109 * struct dma_buf_map - Pointer to vmap'ed dma-buf memory.
110 * @vaddr_iomem: The buffer's address if in I/O memory
111 * @vaddr: The buffer's address if in system memory
112 * @is_iomem: True if the dma-buf memory is located in I/O
113 * memory, or false otherwise.
114 */
115struct dma_buf_map {
116 union {
117 void __iomem *vaddr_iomem;
118 void *vaddr;
119 };
120 bool is_iomem;
121};
122
123/**
124 * DMA_BUF_MAP_INIT_VADDR - Initializes struct dma_buf_map to an address in system memory
125 * @vaddr_: A system-memory address
126 */
127#define DMA_BUF_MAP_INIT_VADDR(vaddr_) \
128 { \
129 .vaddr = (vaddr_), \
130 .is_iomem = false, \
131 }
132
133/**
134 * dma_buf_map_set_vaddr - Sets a dma-buf mapping structure to an address in system memory
135 * @map: The dma-buf mapping structure
136 * @vaddr: A system-memory address
137 *
138 * Sets the address and clears the I/O-memory flag.
139 */
140static inline void dma_buf_map_set_vaddr(struct dma_buf_map *map, void *vaddr)
141{
142 map->vaddr = vaddr;
143 map->is_iomem = false;
144}
145
146/**
147 * dma_buf_map_set_vaddr_iomem - Sets a dma-buf mapping structure to an address in I/O memory
148 * @map: The dma-buf mapping structure
149 * @vaddr_iomem: An I/O-memory address
150 *
151 * Sets the address and the I/O-memory flag.
152 */
153static inline void dma_buf_map_set_vaddr_iomem(struct dma_buf_map *map,
154 void __iomem *vaddr_iomem)
155{
156 map->vaddr_iomem = vaddr_iomem;
157 map->is_iomem = true;
158}
159
160/**
161 * dma_buf_map_is_equal - Compares two dma-buf mapping structures for equality
162 * @lhs: The dma-buf mapping structure
163 * @rhs: A dma-buf mapping structure to compare with
164 *
165 * Two dma-buf mapping structures are equal if they both refer to the same type of memory
166 * and to the same address within that memory.
167 *
168 * Returns:
169 * True is both structures are equal, or false otherwise.
170 */
171static inline bool dma_buf_map_is_equal(const struct dma_buf_map *lhs,
172 const struct dma_buf_map *rhs)
173{
174 if (lhs->is_iomem != rhs->is_iomem)
175 return false;
176 else if (lhs->is_iomem)
177 return lhs->vaddr_iomem == rhs->vaddr_iomem;
178 else
179 return lhs->vaddr == rhs->vaddr;
180}
181
182/**
183 * dma_buf_map_is_null - Tests for a dma-buf mapping to be NULL
184 * @map: The dma-buf mapping structure
185 *
186 * Depending on the state of struct dma_buf_map.is_iomem, tests if the
187 * mapping is NULL.
188 *
189 * Returns:
190 * True if the mapping is NULL, or false otherwise.
191 */
192static inline bool dma_buf_map_is_null(const struct dma_buf_map *map)
193{
194 if (map->is_iomem)
195 return !map->vaddr_iomem;
196 return !map->vaddr;
197}
198
199/**
200 * dma_buf_map_is_set - Tests is the dma-buf mapping has been set
201 * @map: The dma-buf mapping structure
202 *
203 * Depending on the state of struct dma_buf_map.is_iomem, tests if the
204 * mapping has been set.
205 *
206 * Returns:
207 * True if the mapping is been set, or false otherwise.
208 */
209static inline bool dma_buf_map_is_set(const struct dma_buf_map *map)
210{
211 return !dma_buf_map_is_null(map);
212}
213
214/**
215 * dma_buf_map_clear - Clears a dma-buf mapping structure
216 * @map: The dma-buf mapping structure
217 *
218 * Clears all fields to zero; including struct dma_buf_map.is_iomem. So
219 * mapping structures that were set to point to I/O memory are reset for
220 * system memory. Pointers are cleared to NULL. This is the default.
221 */
222static inline void dma_buf_map_clear(struct dma_buf_map *map)
223{
224 if (map->is_iomem) {
225 map->vaddr_iomem = NULL;
226 map->is_iomem = false;
227 } else {
228 map->vaddr = NULL;
229 }
230}
231
232/**
233 * dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
234 * @dst: The dma-buf mapping structure
235 * @src: The source buffer
236 * @len: The number of byte in src
237 *
238 * Copies data into a dma-buf mapping. The source buffer is in system
239 * memory. Depending on the buffer's location, the helper picks the correct
240 * method of accessing the memory.
241 */
242static inline void dma_buf_map_memcpy_to(struct dma_buf_map *dst, const void *src, size_t len)
243{
244 if (dst->is_iomem)
245 memcpy_toio(dst->vaddr_iomem, src, len);
246 else
247 memcpy(dst->vaddr, src, len);
248}
249
250/**
251 * dma_buf_map_incr - Increments the address stored in a dma-buf mapping
252 * @map: The dma-buf mapping structure
253 * @incr: The number of bytes to increment
254 *
255 * Increments the address stored in a dma-buf mapping. Depending on the
256 * buffer's location, the correct value will be updated.
257 */
258static inline void dma_buf_map_incr(struct dma_buf_map *map, size_t incr)
259{
260 if (map->is_iomem)
261 map->vaddr_iomem += incr;
262 else
263 map->vaddr += incr;
264}
265
266#endif /* __DMA_BUF_MAP_H__ */