/* SPDX-License-Identifier: GPL-2.0-only */


#ifndef _MEM_BUF_H
#define _MEM_BUF_H

#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gunyah/gh_rm_drv.h>
#include <linux/types.h>
#include <linux/dma-buf.h>
#include <uapi/linux/mem-buf.h>


#define MEM_BUF_BUDDY_MEM_TYPE (MEM_BUF_ION_MEM_TYPE + 2)


struct mem_buf_vmperm *to_mem_buf_vmperm(struct dma_buf *dmabuf);


bool mem_buf_dma_buf_exclusive_owner(struct dma_buf *dmabuf);


int mem_buf_dma_buf_copy_vmperm(struct dma_buf *dmabuf, int **vmids, int **perms,
		int *nr_acl_entries);

typedef int (*mem_buf_dma_buf_destructor)(void *dtor_data);
int mem_buf_dma_buf_set_destructor(struct dma_buf *dmabuf,
				   mem_buf_dma_buf_destructor dtor,
				   void *dtor_data);


struct mem_buf_allocation_data {
	size_t size;
	unsigned int nr_acl_entries;
	int *vmids;
	int *perms;
	u32 trans_type;
	struct gh_sgl_desc *sgl_desc;
	enum mem_buf_mem_type src_mem_type;
	void *src_data;
	enum mem_buf_mem_type dst_mem_type;
	void *dst_data;
};

struct mem_buf_lend_kernel_arg {
	unsigned int nr_acl_entries;
	int *vmids;
	int *perms;
	gh_memparcel_handle_t memparcel_hdl;
	u32 flags;
	u64 label;
};

int mem_buf_lend(struct dma_buf *dmabuf,
		struct mem_buf_lend_kernel_arg *arg);


int mem_buf_share(struct dma_buf *dmabuf,
		struct mem_buf_lend_kernel_arg *arg);


struct mem_buf_retrieve_kernel_arg {
	int sender_vmid;
	unsigned int nr_acl_entries;
	int *vmids;
	int *perms;
	gh_memparcel_handle_t memparcel_hdl;
	int fd_flags;
};
struct dma_buf *mem_buf_retrieve(struct mem_buf_retrieve_kernel_arg *arg);
int mem_buf_reclaim(struct dma_buf *dmabuf);

#if IS_ENABLED(CONFIG_QCOM_MEM_BUF)

void *mem_buf_alloc(struct mem_buf_allocation_data *alloc_data);
void mem_buf_free(void *membuf);
struct gh_sgl_desc *mem_buf_get_sgl(void *membuf);
int mem_buf_current_vmid(void);
#else

static inline void *mem_buf_alloc(struct mem_buf_allocation_data *alloc_data)
{
	return ERR_PTR(-ENODEV);
}

static inline void mem_buf_free(void *membuf) {}

static inline struct gh_sgl_desc *mem_buf_get_sgl(void *membuf)
{
	return ERR_PTR(-EINVAL);
}
static inline int mem_buf_current_vmid(void)
{
	return -EINVAL;
}
#endif 


#ifdef CONFIG_QCOM_MEM_BUF_DEV_GH
int mem_buf_map_mem_s1(struct gh_sgl_desc *sgl_desc);
int mem_buf_unmap_mem_s1(struct gh_sgl_desc *sgl_desc);

#else
static inline int mem_buf_map_mem_s1(struct gh_sgl_desc *sgl_desc)
{
	return -EINVAL;
}

static inline int mem_buf_unmap_mem_s1(struct gh_sgl_desc *sgl_desc)
{
	return -EINVAL;
}
#endif 
#endif 
