Loading drivers/cam_req_mgr/cam_mem_mgr.c +33 −4 Original line number Diff line number Diff line Loading @@ -196,6 +196,7 @@ static void cam_mem_put_slot(int32_t idx) mutex_lock(&tbl.m_lock); mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; tbl.bufq[idx].is_internal = false; mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); Loading Loading @@ -540,7 +541,8 @@ static int cam_mem_util_map_hw_va(uint32_t flags, int fd, dma_addr_t *hw_vaddr, size_t *len, enum cam_smmu_region_id region) enum cam_smmu_region_id region, bool is_internal) { int i; int rc = -1; Loading Loading @@ -582,7 +584,8 @@ static int cam_mem_util_map_hw_va(uint32_t flags, dir, (dma_addr_t *)hw_vaddr, len, region); region, is_internal); if (rc < 0) { CAM_ERR(CAM_MEM, Loading Loading @@ -675,7 +678,8 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) fd, &hw_vaddr, &len, region); region, true); if (rc) { CAM_ERR(CAM_MEM, Loading @@ -691,6 +695,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) tbl.bufq[idx].dma_buf = NULL; tbl.bufq[idx].flags = cmd->flags; tbl.bufq[idx].buf_handle = GET_MEM_HANDLE(idx, fd); tbl.bufq[idx].is_internal = true; if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE) CAM_MEM_MGR_SET_SECURE_HDL(tbl.bufq[idx].buf_handle, true); Loading Loading @@ -733,6 +738,23 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) return rc; } static bool cam_mem_util_is_map_internal(int32_t fd) { uint32_t i; bool is_internal = false; mutex_lock(&tbl.m_lock); for_each_set_bit(i, tbl.bitmap, tbl.bits) { if (tbl.bufq[i].fd == fd) { is_internal = tbl.bufq[i].is_internal; break; } } mutex_unlock(&tbl.m_lock); return is_internal; } int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) { int32_t idx; Loading @@ -740,6 +762,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) struct dma_buf *dmabuf; dma_addr_t hw_vaddr = 0; size_t len = 0; bool is_internal = false; if (!atomic_read(&cam_mem_mgr_state)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); Loading Loading @@ -769,6 +792,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) return -EINVAL; } is_internal = cam_mem_util_is_map_internal(cmd->fd); if ((cmd->flags & CAM_MEM_FLAG_HW_READ_WRITE) || (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)) { rc = cam_mem_util_map_hw_va(cmd->flags, Loading @@ -777,7 +802,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) cmd->fd, &hw_vaddr, &len, CAM_SMMU_REGION_IO); CAM_SMMU_REGION_IO, is_internal); if (rc) { CAM_ERR(CAM_MEM, "Failed in map_hw_va, flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", Loading Loading @@ -813,6 +839,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls, sizeof(int32_t) * cmd->num_hdl); tbl.bufq[idx].is_imported = true; tbl.bufq[idx].is_internal = is_internal; mutex_unlock(&tbl.bufq[idx].q_lock); cmd->out.buf_handle = tbl.bufq[idx].buf_handle; Loading Loading @@ -939,6 +966,7 @@ static int cam_mem_mgr_cleanup_table(void) tbl.bufq[i].num_hdl = 0; tbl.bufq[i].dma_buf = NULL; tbl.bufq[i].active = false; tbl.bufq[i].is_internal = false; mutex_unlock(&tbl.bufq[i].q_lock); mutex_destroy(&tbl.bufq[i].q_lock); } Loading Loading @@ -1034,6 +1062,7 @@ static int cam_mem_util_unmap(int32_t idx, tbl.bufq[idx].fd = -1; tbl.bufq[idx].dma_buf = NULL; tbl.bufq[idx].is_imported = false; tbl.bufq[idx].is_internal = false; tbl.bufq[idx].len = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].active = false; Loading drivers/cam_req_mgr/cam_mem_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ enum cam_smmu_mapping_client { * @kmdvaddr: Kernel virtual address * @active: state of the buffer * @is_imported: Flag indicating if buffer is imported from an FD in user space * @is_internal: Flag indicating kernel allocated buffer */ struct cam_mem_buf_queue { struct dma_buf *dma_buf; Loading @@ -56,6 +57,7 @@ struct cam_mem_buf_queue { uintptr_t kmdvaddr; bool active; bool is_imported; bool is_internal; }; /** Loading drivers/cam_req_mgr/cam_req_mgr_dev.c +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/highmem.h> #include <linux/types.h> #include <mm/slab.h> Loading drivers/cam_smmu/cam_smmu_api.c +11 −4 Original line number Diff line number Diff line Loading @@ -197,6 +197,7 @@ struct cam_dma_buff_info { int ion_fd; size_t len; size_t phys_len; bool is_internal; }; struct cam_sec_buff_info { Loading Loading @@ -249,7 +250,7 @@ static struct cam_dma_buff_info *cam_smmu_find_mapping_by_virt_address(int idx, static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, bool dis_delayed_unmap, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id); enum cam_smmu_region_id region_id, bool is_internal); static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, struct dma_buf *buf, enum dma_data_direction dma_dir, Loading Loading @@ -1997,7 +1998,7 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf, static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, bool dis_delayed_unmap, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id) enum cam_smmu_region_id region_id, bool is_internal) { int rc = -1; struct cam_dma_buff_info *mapping_info = NULL; Loading @@ -2015,6 +2016,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, } mapping_info->ion_fd = ion_fd; mapping_info->is_internal = is_internal; /* add to the list */ list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); Loading Loading @@ -2118,6 +2120,9 @@ static int cam_smmu_unmap_buf_and_remove_from_list( iommu_cb_set.cb_info[idx].io_mapping_size -= mapping_info->len; } if (mapping_info->is_internal) mapping_info->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; dma_buf_unmap_attachment(mapping_info->attach, mapping_info->table, mapping_info->dir); dma_buf_detach(mapping_info->buf, mapping_info->attach); Loading Loading @@ -2877,7 +2882,8 @@ static int cam_smmu_map_iova_validate_params(int handle, int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id) size_t *len_ptr, enum cam_smmu_region_id region_id, bool is_internal) { int idx, rc = 0; enum cam_smmu_buf_state buf_state; Loading Loading @@ -2927,7 +2933,8 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, } rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id, is_internal); if (rc < 0) { CAM_ERR(CAM_SMMU, "mapping or add list fail, idx=%d, fd=%d, region=%d, rc=%d", Loading drivers/cam_smmu/cam_smmu_api.h +4 −1 Original line number Diff line number Diff line Loading @@ -111,11 +111,13 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param op); * CAM_SMMU_REGION_SHARED, dma_addr is used as an input parameter * which specifies the cpu virtual address to map. * @len_ptr : Length of buffer mapped returned by CAM SMMU driver. * @region_id : Memory region identifier * @is_internal: Specifies if this buffer is kernel allocated. * @return Status of operation. Negative in case of error. Zero otherwise. */ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *dma_addr, size_t *len_ptr, enum cam_smmu_region_id region_id); enum cam_smmu_region_id region_id, bool is_internal); /** * @brief : Maps kernel space IOVA for calling driver Loading @@ -129,6 +131,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, * CAM_SMMU_REGION_SHARED, dma_addr is used as an input * parameter which specifies the cpu virtual address to map. * @len_ptr : Length of buffer mapped returned by CAM SMMU driver. * @region_id : Memory region identifier * @return Status of operation. Negative in case of error. Zero otherwise. */ int cam_smmu_map_kernel_iova(int handle, Loading Loading
drivers/cam_req_mgr/cam_mem_mgr.c +33 −4 Original line number Diff line number Diff line Loading @@ -196,6 +196,7 @@ static void cam_mem_put_slot(int32_t idx) mutex_lock(&tbl.m_lock); mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; tbl.bufq[idx].is_internal = false; mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); Loading Loading @@ -540,7 +541,8 @@ static int cam_mem_util_map_hw_va(uint32_t flags, int fd, dma_addr_t *hw_vaddr, size_t *len, enum cam_smmu_region_id region) enum cam_smmu_region_id region, bool is_internal) { int i; int rc = -1; Loading Loading @@ -582,7 +584,8 @@ static int cam_mem_util_map_hw_va(uint32_t flags, dir, (dma_addr_t *)hw_vaddr, len, region); region, is_internal); if (rc < 0) { CAM_ERR(CAM_MEM, Loading Loading @@ -675,7 +678,8 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) fd, &hw_vaddr, &len, region); region, true); if (rc) { CAM_ERR(CAM_MEM, Loading @@ -691,6 +695,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) tbl.bufq[idx].dma_buf = NULL; tbl.bufq[idx].flags = cmd->flags; tbl.bufq[idx].buf_handle = GET_MEM_HANDLE(idx, fd); tbl.bufq[idx].is_internal = true; if (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE) CAM_MEM_MGR_SET_SECURE_HDL(tbl.bufq[idx].buf_handle, true); Loading Loading @@ -733,6 +738,23 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) return rc; } static bool cam_mem_util_is_map_internal(int32_t fd) { uint32_t i; bool is_internal = false; mutex_lock(&tbl.m_lock); for_each_set_bit(i, tbl.bitmap, tbl.bits) { if (tbl.bufq[i].fd == fd) { is_internal = tbl.bufq[i].is_internal; break; } } mutex_unlock(&tbl.m_lock); return is_internal; } int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) { int32_t idx; Loading @@ -740,6 +762,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) struct dma_buf *dmabuf; dma_addr_t hw_vaddr = 0; size_t len = 0; bool is_internal = false; if (!atomic_read(&cam_mem_mgr_state)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); Loading Loading @@ -769,6 +792,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) return -EINVAL; } is_internal = cam_mem_util_is_map_internal(cmd->fd); if ((cmd->flags & CAM_MEM_FLAG_HW_READ_WRITE) || (cmd->flags & CAM_MEM_FLAG_PROTECTED_MODE)) { rc = cam_mem_util_map_hw_va(cmd->flags, Loading @@ -777,7 +802,8 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) cmd->fd, &hw_vaddr, &len, CAM_SMMU_REGION_IO); CAM_SMMU_REGION_IO, is_internal); if (rc) { CAM_ERR(CAM_MEM, "Failed in map_hw_va, flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", Loading Loading @@ -813,6 +839,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls, sizeof(int32_t) * cmd->num_hdl); tbl.bufq[idx].is_imported = true; tbl.bufq[idx].is_internal = is_internal; mutex_unlock(&tbl.bufq[idx].q_lock); cmd->out.buf_handle = tbl.bufq[idx].buf_handle; Loading Loading @@ -939,6 +966,7 @@ static int cam_mem_mgr_cleanup_table(void) tbl.bufq[i].num_hdl = 0; tbl.bufq[i].dma_buf = NULL; tbl.bufq[i].active = false; tbl.bufq[i].is_internal = false; mutex_unlock(&tbl.bufq[i].q_lock); mutex_destroy(&tbl.bufq[i].q_lock); } Loading Loading @@ -1034,6 +1062,7 @@ static int cam_mem_util_unmap(int32_t idx, tbl.bufq[idx].fd = -1; tbl.bufq[idx].dma_buf = NULL; tbl.bufq[idx].is_imported = false; tbl.bufq[idx].is_internal = false; tbl.bufq[idx].len = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].active = false; Loading
drivers/cam_req_mgr/cam_mem_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ enum cam_smmu_mapping_client { * @kmdvaddr: Kernel virtual address * @active: state of the buffer * @is_imported: Flag indicating if buffer is imported from an FD in user space * @is_internal: Flag indicating kernel allocated buffer */ struct cam_mem_buf_queue { struct dma_buf *dma_buf; Loading @@ -56,6 +57,7 @@ struct cam_mem_buf_queue { uintptr_t kmdvaddr; bool active; bool is_imported; bool is_internal; }; /** Loading
drivers/cam_req_mgr/cam_req_mgr_dev.c +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/highmem.h> #include <linux/types.h> #include <mm/slab.h> Loading
drivers/cam_smmu/cam_smmu_api.c +11 −4 Original line number Diff line number Diff line Loading @@ -197,6 +197,7 @@ struct cam_dma_buff_info { int ion_fd; size_t len; size_t phys_len; bool is_internal; }; struct cam_sec_buff_info { Loading Loading @@ -249,7 +250,7 @@ static struct cam_dma_buff_info *cam_smmu_find_mapping_by_virt_address(int idx, static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, bool dis_delayed_unmap, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id); enum cam_smmu_region_id region_id, bool is_internal); static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, struct dma_buf *buf, enum dma_data_direction dma_dir, Loading Loading @@ -1997,7 +1998,7 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf, static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, bool dis_delayed_unmap, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id) enum cam_smmu_region_id region_id, bool is_internal) { int rc = -1; struct cam_dma_buff_info *mapping_info = NULL; Loading @@ -2015,6 +2016,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, } mapping_info->ion_fd = ion_fd; mapping_info->is_internal = is_internal; /* add to the list */ list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); Loading Loading @@ -2118,6 +2120,9 @@ static int cam_smmu_unmap_buf_and_remove_from_list( iommu_cb_set.cb_info[idx].io_mapping_size -= mapping_info->len; } if (mapping_info->is_internal) mapping_info->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; dma_buf_unmap_attachment(mapping_info->attach, mapping_info->table, mapping_info->dir); dma_buf_detach(mapping_info->buf, mapping_info->attach); Loading Loading @@ -2877,7 +2882,8 @@ static int cam_smmu_map_iova_validate_params(int handle, int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr, size_t *len_ptr, enum cam_smmu_region_id region_id) size_t *len_ptr, enum cam_smmu_region_id region_id, bool is_internal) { int idx, rc = 0; enum cam_smmu_buf_state buf_state; Loading Loading @@ -2927,7 +2933,8 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, } rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id, is_internal); if (rc < 0) { CAM_ERR(CAM_SMMU, "mapping or add list fail, idx=%d, fd=%d, region=%d, rc=%d", Loading
drivers/cam_smmu/cam_smmu_api.h +4 −1 Original line number Diff line number Diff line Loading @@ -111,11 +111,13 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param op); * CAM_SMMU_REGION_SHARED, dma_addr is used as an input parameter * which specifies the cpu virtual address to map. * @len_ptr : Length of buffer mapped returned by CAM SMMU driver. * @region_id : Memory region identifier * @is_internal: Specifies if this buffer is kernel allocated. * @return Status of operation. Negative in case of error. Zero otherwise. */ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, enum cam_smmu_map_dir dir, dma_addr_t *dma_addr, size_t *len_ptr, enum cam_smmu_region_id region_id); enum cam_smmu_region_id region_id, bool is_internal); /** * @brief : Maps kernel space IOVA for calling driver Loading @@ -129,6 +131,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, * CAM_SMMU_REGION_SHARED, dma_addr is used as an input * parameter which specifies the cpu virtual address to map. * @len_ptr : Length of buffer mapped returned by CAM SMMU driver. * @region_id : Memory region identifier * @return Status of operation. Negative in case of error. Zero otherwise. */ int cam_smmu_map_kernel_iova(int handle, Loading