struct miscdevice dev;
struct sm_instance *sm_handle; /* Handle for videocore service. */
+ spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */
+ struct idr kernelid_map;
+
struct mutex map_lock; /* Global map lock. */
struct list_head buffer_list; /* List of buffer. */
/* ---- Private Functions ------------------------------------------------ */
+static int get_kernel_id(struct vc_sm_buffer *buffer)
+{
+ int handle;
+
+ spin_lock(&sm_state->kernelid_map_lock);
+ handle = idr_alloc(&sm_state->kernelid_map, buffer, 0, 0, GFP_KERNEL);
+ spin_unlock(&sm_state->kernelid_map_lock);
+
+ return handle;
+}
+
+static struct vc_sm_buffer *lookup_kernel_id(int handle)
+{
+ return idr_find(&sm_state->kernelid_map, handle);
+}
+
+static void free_kernel_id(int handle)
+{
+ spin_lock(&sm_state->kernelid_map_lock);
+ idr_remove(&sm_state->kernelid_map, handle);
+ spin_unlock(&sm_state->kernelid_map_lock);
+}
+
static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v)
{
struct sm_pde_t *sm_pde;
if (!sm_state)
return 0;
- seq_printf(s, "\nVC-ServiceHandle 0x%x\n",
- (unsigned int)sm_state->sm_handle);
+ seq_printf(s, "\nVC-ServiceHandle %p\n", sm_state->sm_handle);
/* Log all applicable mapping(s). */
resource);
seq_printf(s, " NAME %s\n",
resource->name);
- seq_printf(s, " SIZE %d\n",
+ seq_printf(s, " SIZE %zu\n",
resource->size);
seq_printf(s, " DMABUF %p\n",
resource->dma_buf);
list_add(&buffer->global_buffer_list, &sm_state->buffer_list);
mutex_unlock(&sm_state->map_lock);
- pr_debug("[%s]: added buffer %p (name %s, size %d)\n",
+ pr_debug("[%s]: added buffer %p (name %s, size %zu)\n",
__func__, buffer, buffer->name, buffer->size);
}
mutex_lock(&sm_state->map_lock);
mutex_lock(&buffer->lock);
- pr_debug("[%s]: buffer %p (name %s, size %d)\n",
+ pr_debug("[%s]: buffer %p (name %s, size %zu)\n",
__func__, buffer, buffer->name, buffer->size);
if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) {
struct vc_sm_import_result result = { };
struct dma_buf_attachment *attach = NULL;
struct sg_table *sgt = NULL;
+ dma_addr_t dma_addr;
int ret = 0;
int status;
}
import.type = VC_SM_ALLOC_NON_CACHED;
- import.addr = (uint32_t)sg_dma_address(sgt->sgl);
+ dma_addr = sg_dma_address(sgt->sgl);
+ import.addr = (uint32_t)dma_addr;
if ((import.addr & 0xC0000000) != 0xC0000000) {
- pr_err("%s: Expecting an uncached alias for dma_addr %08x\n",
- __func__, import.addr);
+ pr_err("%s: Expecting an uncached alias for dma_addr %pad\n",
+ __func__, &dma_addr);
import.addr |= 0xC0000000;
}
import.size = sg_dma_len(sgt->sgl);
import.allocator = current->tgid;
- import.kernel_id = (uint32_t)buffer; //FIXME: 64 bit support needed.
+ import.kernel_id = get_kernel_id(buffer);
memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT,
sizeof(VC_SM_RESOURCE_NAME_DEFAULT));
- pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n",
- __func__, import.name, import.type, (void *)import.addr,
+ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n",
+ __func__, import.name, import.type, &dma_addr,
import.size);
/* Allocate the videocore buffer. */
buffer->attach = attach;
buffer->sgt = sgt;
- buffer->dma_addr = sg_dma_address(sgt->sgl);
+ buffer->dma_addr = dma_addr;
buffer->in_use = 1;
/*
vc_sm_cma_vchi_free(sm_state->sm_handle, &free,
&sm_state->int_trans_id);
}
+ free_kernel_id(import.kernel_id);
kfree(buffer);
if (sgt)
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
{
struct vc_sm_released *release = (struct vc_sm_released *)reply;
struct vc_sm_buffer *buffer =
- (struct vc_sm_buffer *)release->kernel_id;
+ lookup_kernel_id(release->kernel_id);
/*
* FIXME: Need to check buffer is still valid and allocated
buffer->vc_handle = 0;
buffer->vpu_state = VPU_NOT_MAPPED;
mutex_unlock(&buffer->lock);
+ free_kernel_id(release->kernel_id);
vc_sm_release_resource(buffer, 0);
}
sm_state->pdev = pdev;
mutex_init(&sm_state->map_lock);
+ spin_lock_init(&sm_state->kernelid_map_lock);
+ idr_init_base(&sm_state->kernelid_map, 1);
+
pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
sizeof(*pdev->dev.dma_parms),
GFP_KERNEL);
/* Stop the videocore shared memory service. */
vc_sm_cma_vchi_stop(&sm_state->sm_handle);
+ idr_destroy(&sm_state->kernelid_map);
+
/* Free the memory for the state structure. */
mutex_destroy(&sm_state->map_lock);
kfree(sm_state);