1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/*
* Copyright (C) 2014 Samsung Electronics Co.Ltd
* Authors:
* Inki Dae <inki.dae@samsung.com>
* Chango Park <chanho61.park@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/dma-buf.h>
#include <linux/seqno-fence.h>
#define DMABUF_SYNC_NAME_SIZE 256
#define DMA_BUF_ACCESS_R 0x1
#define DMA_BUF_ACCESS_W 0x2
#define DMA_BUF_ACCESS_DMA 0x4
#define DMA_BUF_ACCESS_RW (DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_W)
#define DMA_BUF_ACCESS_DMA_R (DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_DMA)
#define DMA_BUF_ACCESS_DMA_W (DMA_BUF_ACCESS_W | DMA_BUF_ACCESS_DMA)
#define DMA_BUF_ACCESS_DMA_RW (DMA_BUF_ACCESS_DMA_R | DMA_BUF_ACCESS_DMA_W)
#define IS_VALID_DMA_BUF_ACCESS_TYPE(t) (t == DMA_BUF_ACCESS_R || \
t == DMA_BUF_ACCESS_W || \
t == DMA_BUF_ACCESS_DMA_R || \
t == DMA_BUF_ACCESS_DMA_W || \
t == DMA_BUF_ACCESS_RW || \
t == DMA_BUF_ACCESS_DMA_RW)
/*
* A structure for dmabuf_sync_object.
*
* @head: A list head to be added to dmabuf_sync's syncs.
* @access_type: Indicate how a current task tries to access
* a given buffer, and one of the below types could be set.
* DMA_BUF_ACCESS_R -> CPU access for read.
* DMA_BUF_ACCRSS_W -> CPU access for write.
* DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_DMA -> DMA access for read.
* DMA_BUF_ACCESS_W | DMA_BUF_ACCESS_DMA -> DMA access for write.
*/
struct dmabuf_sync_object {
struct kref refcount;
struct list_head l_head;
struct list_head g_head;
struct seqno_fence *sfence;
struct dma_buf *dmabuf;
unsigned int access_type;
};
struct dmabuf_sync_priv_ops {
void (*free)(void *priv);
};
/*
* A structure for dmabuf_sync.
*
* @syncs: A list head to sync object and this is global to system.
* This contains sync objects of dmabuf_sync owner.
* @priv: A private data.
* @name: A string to dmabuf sync owner.
*/
struct dmabuf_sync {
struct list_head list;
struct list_head syncs;
struct seqno_fence sfence;
unsigned int obj_cnt;
struct dmabuf_sync_priv_ops *ops;
char name[DMABUF_SYNC_NAME_SIZE];
struct dmabuf_sync_object *single_sobj;
struct timer_list sync_free_worker;
spinlock_t lock;
spinlock_t flock;
void *priv;
};
bool dmabuf_sync_is_supported(void);
struct dmabuf_sync *dmabuf_sync_init(const char *name,
struct dmabuf_sync_priv_ops *ops,
void *priv);
void dmabuf_sync_fini(struct dmabuf_sync *sync);
int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
unsigned int ctx, unsigned int type);
void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf);
void dmabuf_sync_put_all(struct dmabuf_sync *sync);
long dmabuf_sync_wait(struct dma_buf *dmabuf, unsigned int ctx,
unsigned int access_type);
long dmabuf_sync_wait_all(struct dmabuf_sync *sync);
int dmabuf_sync_signal(struct dma_buf *dmabuf);
int dmabuf_sync_signal_all(struct dmabuf_sync *sync);
static inline struct dmabuf_sync *to_dmabuf_sync(struct seqno_fence *sf)
{
if (!sf)
return NULL;
return container_of(sf, struct dmabuf_sync, sfence);
}
|