diff options
author | Inki Dae <inki.dae@samsung.com> | 2014-11-20 22:29:39 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-21 19:13:44 +0900 |
commit | fdba906c052b853cc3fd792d4f45f904247c2a4a (patch) | |
tree | c174bf68104ae50d817d9c4eea9f847eb054767d /include | |
parent | 2fc9531a488deb9dce86dd7259b46b603fe99d37 (diff) | |
download | linux-3.10-fdba906c052b853cc3fd792d4f45f904247c2a4a.tar.gz linux-3.10-fdba906c052b853cc3fd792d4f45f904247c2a4a.tar.bz2 linux-3.10-fdba906c052b853cc3fd792d4f45f904247c2a4a.zip |
dma-buf/dmabuf-sync: add dmabuf sync framework
The DMA Buffer synchronization API provides buffer synchronization
mechanism based on DMA buffer sharing machanism[1], dmafence and
reservation frameworks[2];
i.e., buffer access control to CPU and DMA, and easy-to-use interfaces
for device drivers and user application. And this API can be used
for all dma devices using system memory as dma buffer, especially
for most ARM based SoCs.
For more details, please refer to Documentation/dma-buf-syc.txt
[1] http://lwn.net/Articles/470339/
[2] https://lkml.org/lkml/2014/2/24/824
Change-Id: I3b2084a3c331fc06992fa8d2a4c71378e88b10b5
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/dmabuf-sync.h | 108 | ||||
-rw-r--r-- | include/linux/reservation.h | 1 |
2 files changed, 109 insertions, 0 deletions
diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h new file mode 100644 index 00000000000..9ce13812d09 --- /dev/null +++ b/include/linux/dmabuf-sync.h @@ -0,0 +1,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); +} diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 5a0b64cf68b..77fd051b1a4 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -62,6 +62,7 @@ struct reservation_object { struct fence __rcu *fence_excl; struct reservation_object_list __rcu *fence; struct reservation_object_list *staged; + unsigned int accessed_type; }; #define reservation_object_held(obj) lockdep_is_held(&(obj)->lock.base) |