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
128128 goto free_chunk;
129129 }
130130
131+ mutex_lock(&p->ctx->lock);
132+
131133 /* skip guilty context job */
132134 if (atomic_read(&p->ctx->guilty) == 1) {
133135 ret = -ECANCELED;
@@ -709,6 +711,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, · 575 unmodified lines
709711 dma_fence_put(parser->fence);
710712
711713 if (parser->ctx) {
714+ mutex_unlock(&parser->ctx->lock);
712715 amdgpu_ctx_put(parser->ctx);
713716 }
714717 if (parser->bo_list)
@@ -1157,6 +1160,9 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 442 unmodified lines
11571160 {
11581161 int i, r;
11591162
1163+ /* TODO: Investigate why we still need the context lock */
1164+ mutex_unlock(&p->ctx->lock);
1165+
11601166 for (i = 0; i < p->nchunks; ++i) {
11611167 struct amdgpu_cs_chunk *chunk;
11621168
@@ -1167,32 +1173,34 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 4 unmodified lines
11671173 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
11681174 r = amdgpu_cs_process_fence_dep(p, chunk);
11691175 if (r)
1170− return r;
1176+ goto out;
11711177 break;
11721178 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
11731179 r = amdgpu_cs_process_syncobj_in_dep(p, chunk);
11741180 if (r)
1175− return r;
1181+ goto out;
11761182 break;
11771183 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
11781184 r = amdgpu_cs_process_syncobj_out_dep(p, chunk);
11791185 if (r)
1180− return r;
1186+ goto out;
11811187 break;
11821188 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
11831189 r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);
11841190 if (r)
1185− return r;
1191+ goto out;
11861192 break;
11871193 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
11881194 r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);
11891195 if (r)
1190− return r;
1196+ goto out;
11911197 break;
11921198 }
11931199 }
11941200
1195− return 0;
1201+out:
1202+ mutex_lock(&p->ctx->lock);
1203+ return r;
11961204 }
11971205
11981206 static 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
13681376 goto out;
13691377
13701378 r = amdgpu_cs_submit(&parser, cs);
1379+
13711380 out:
13721381 amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
13731382
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
237237
238238 kref_init(&ctx->refcount);
239239 spin_lock_init(&ctx->ring_lock);
240+ mutex_init(&ctx->lock);
240241
241242 ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
242243 ctx->reset_counter_query = ctx->reset_counter;
@@ -357,6 +358,7 @@ static void amdgpu_ctx_fini(struct kref *ref) · 114 unmodified lines
357358 drm_dev_exit(idx);
358359 }
359360
361+ mutex_destroy(&ctx->lock);
360362 kfree(ctx);
361363 }
362364
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h+1−0
@@ -49,6 +49,7 @@ struct amdgpu_ctx { · 48 unmodified lines
4949 bool preamble_presented;
5050 int32_t init_priority;
5151 int32_t override_priority;
52+ struct mutex lock;
5253 atomic_t guilty;
5354 unsigned long ras_counter_ce;
5455 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
214214 }
215215 EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
216216
217−static 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−
240217 /**
241218 * drm_of_find_panel_or_bridge - return connected panel or bridge device
242219 * @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
259236 struct drm_panel **panel,
260237 struct drm_bridge **bridge)
261238 {
262− struct device_node *node;
263− int ret;
239+ int ret = -EPROBE_DEFER;
240+ struct device_node *remote;
264241
265242 if (!panel && !bridge)
266243 return -EINVAL;
267−
268244 if (panel)
269245 *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− }
284246
285− /* Otherwise check for any child node other than port/ports. */
286− for_each_available_child_of_node(np, node) {
287− if (of_node_name_eq(node, "port") ||
288− of_node_name_eq(node, "ports"))
289− continue;
247+ /*
248+ * of_graph_get_remote_node() produces a noisy error message if port
249+ * node isn't found and the absence of the port is a legit case here,
250+ * so at first we silently check whether graph presents in the
251+ * device-tree node.
252+ */
253+ if (!of_graph_is_present(np))
254+ return -ENODEV;
290255
291− ret = find_panel_or_bridge(node, panel, bridge);
292− of_node_put(node);
256+ remote = of_graph_get_remote_node(np, port, endpoint);
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+ }
293277
294− /* Stop at the first found occurrence. */
295− if (!ret)
296− return 0;
297278 }
298279
299− return -EPROBE_DEFER;
280+ of_node_put(remote);
281+ return ret;
300282 }
301283 EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
302284
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
229229
230230 ret = i2c_smbus_write_byte_data(ts->i2c, reg, val);
231231 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);
233233 }
234234
235235 static 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
265265 return 0;
266266 }
267267
268−static int rpi_touchscreen_enable(struct drm_panel *panel)
268+static int rpi_touchscreen_prepare(struct drm_panel *panel)
269269 {
270270 struct rpi_touchscreen *ts = panel_to_ts(panel);
271271 int i;
@@ -295,6 +295,13 @@ static int rpi_touchscreen_enable(struct drm_panel *panel) · 23 unmodified lines
295295 rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01);
296296 msleep(100);
297297
298+ return 0;
299+}
300+
301+static int rpi_touchscreen_enable(struct drm_panel *panel)
302+{
303+ struct rpi_touchscreen *ts = panel_to_ts(panel);
304+
298305 /* Turn on the backlight. */
299306 rpi_touchscreen_i2c_write(ts, REG_PWM, 255);
300307
@@ -349,7 +356,7 @@ static int rpi_touchscreen_get_modes(struct drm_panel *panel, · 48 unmodified lines
349356 static const struct drm_panel_funcs rpi_touchscreen_funcs = {
350357 .disable = rpi_touchscreen_disable,
351358 .unprepare = rpi_touchscreen_noop,
352− .prepare = rpi_touchscreen_noop,
359+ .prepare = rpi_touchscreen_prepare,
353360 .enable = rpi_touchscreen_enable,
354361 .get_modes = rpi_touchscreen_get_modes,
355362 };
drivers/gpu/drm/radeon/radeon_sync.c+1−1
@@ -96,7 +96,7 @@ int radeon_sync_resv(struct radeon_device *rdev, · 95 unmodified lines
9696 struct dma_fence *f;
9797 int r = 0;
9898
99− dma_resv_for_each_fence(&cursor, resv, shared, f) {
99+ dma_resv_for_each_fence(&cursor, resv, !shared, f) {
100100 fence = to_radeon_fence(f);
101101 if (fence && fence->rdev == rdev)
102102 radeon_sync_fence(sync, fence);
drivers/gpu/drm/vc4/Kconfig+3−0
@@ -2,6 +2,9 @@ · 1 unmodified line
22 config DRM_VC4
33 tristate "Broadcom VC4 Graphics"
44 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)
58 depends on DRM
69 depends on SND && SND_SOC
710 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
846846 unsigned long phy_clock;
847847 int ret;
848848
849− ret = pm_runtime_get_sync(dev);
849+ ret = pm_runtime_resume_and_get(dev);
850850 if (ret) {
851851 DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port);
852852 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
4646 return container_of(bo, struct vmw_buffer_object, base);
4747 }
4848
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+ */
59+static 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+}
4964
5065 /**
5166 * 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
615630
616631 ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
617632 vmw_bo_unreference(&vbo);
618− if (unlikely(ret != 0 && ret != -ERESTARTSYS &&
619− ret != -EBUSY)) {
633+ if (unlikely(ret != 0)) {
634+ if (ret == -ERESTARTSYS || ret == -EBUSY)
635+ return -EBUSY;
620636 DRM_ERROR("Failed synccpu grab on handle 0x%08x.\n",
621637 (unsigned int) arg->handle);
622638 return ret;
@@ -798,7 +814,7 @@ int vmw_dumb_create(struct drm_file *file_priv, · 175 unmodified lines
798814 void vmw_bo_swap_notify(struct ttm_buffer_object *bo)
799815 {
800816 /* Is @bo embedded in a struct vmw_buffer_object? */
801− if (vmw_bo_is_vmw_bo(bo))
817+ if (!bo_is_vmw(bo))
802818 return;
803819
804820 /* Kill any cached kernel maps before swapout */
@@ -822,7 +838,7 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, · 17 unmodified lines
822838 struct vmw_buffer_object *vbo;
823839
824840 /* 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))
826842 return;
827843
828844 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
843859 if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB)
844860 vmw_resource_unbind_list(vbo);
845861 }
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− */
857−bool 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
998998 goto out_no_fman;
999999 }
10001000
1001− drm_vma_offset_manager_init(&dev_priv->vma_manager,
1002− DRM_FILE_PAGE_OFFSET_START,
1003− DRM_FILE_PAGE_OFFSET_SIZE);
10041001 ret = ttm_device_init(&dev_priv->bdev, &vmw_bo_driver,
10051002 dev_priv->drm.dev,
10061003 dev_priv->drm.anon_inode->i_mapping,
1007− &dev_priv->vma_manager,
1004+ dev_priv->drm.vma_offset_manager,
10081005 dev_priv->map_mode == vmw_dma_alloc_coherent,
10091006 false);
10101007 if (unlikely(ret != 0)) {
@@ -1174,7 +1171,6 @@ static void vmw_driver_unload(struct drm_device *dev) · 163 unmodified lines
11741171 vmw_devcaps_destroy(dev_priv);
11751172 vmw_vram_manager_fini(dev_priv);
11761173 ttm_device_fini(&dev_priv->bdev);
1177− drm_vma_offset_manager_destroy(&dev_priv->vma_manager);
11781174 vmw_release_device_late(dev_priv);
11791175 vmw_fence_manager_takedown(dev_priv->fman);
11801176 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
@@ -1398,7 +1394,7 @@ vmw_get_unmapped_area(struct file *file, unsigned long uaddr, · 217 unmodified lines
13981394 struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev);
13991395
14001396 return drm_get_unmapped_area(file, uaddr, len, pgoff, flags,
1401− &dev_priv->vma_manager);
1397+ dev_priv->drm.vma_offset_manager);
14021398 }
14031399
14041400 static 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
683683 container_of(base, struct vmw_user_surface, prime.base);
684684 struct vmw_resource *res = &user_srf->srf.res;
685685
686+ if (base->shareable && res && res->backup)
687+ drm_gem_object_put(&res->backup->base.base);
688+
686689 *p_base = NULL;
687690 vmw_resource_unreference(&res);
688691 }
@@ -857,6 +860,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, · 168 unmodified lines
857860 goto out_unlock;
858861 }
859862 vmw_bo_reference(res->backup);
863+ drm_gem_object_get(&res->backup->base.base);
860864 }
861865
862866 tmp = vmw_resource_reference(&srf->res);
@@ -1513,7 +1517,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 650 unmodified lines
15131517 &res->backup);
15141518 if (ret == 0)
15151519 vmw_bo_reference(res->backup);
1516−
15171520 }
15181521
15191522 if (unlikely(ret != 0)) {
@@ -1561,6 +1564,8 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 41 unmodified lines
15611564 drm_vma_node_offset_addr(&res->backup->base.base.vma_node);
15621565 rep->buffer_size = res->backup->base.base.size;
15631566 rep->buffer_handle = backup_handle;
1567+ if (user_srf->prime.base.shareable)
1568+ drm_gem_object_get(&res->backup->base.base);
15641569 } else {
15651570 rep->buffer_map_handle = 0;
15661571 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− */
115−struct 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− */
140−static 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− */
153−static 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− */
171−static 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− */
192−static 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− */
209−static 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− */
222−static 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− */
242−static 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− */
258−static 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__ */