|
@@ -1,6 +1,7 @@
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
/*
|
|
|
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
|
|
|
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
|
*/
|
|
|
|
|
|
#include <linux/init.h>
|
|
@@ -13,10 +14,10 @@
|
|
|
#include <linux/list.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
#include <linux/dma-buf.h>
|
|
|
+#include <linux/dma-buf-map.h>
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/of_device.h>
|
|
|
#include <linux/export.h>
|
|
|
-#include <linux/ion.h>
|
|
|
#include <linux/ioctl.h>
|
|
|
#include <linux/cdev.h>
|
|
|
#include <linux/fs.h>
|
|
@@ -58,7 +59,7 @@ struct msm_audio_ion_private {
|
|
|
|
|
|
struct msm_audio_alloc_data {
|
|
|
size_t len;
|
|
|
- void *vaddr;
|
|
|
+ struct dma_buf_map *vmap;
|
|
|
struct dma_buf *dma_buf;
|
|
|
struct dma_buf_attachment *attach;
|
|
|
struct sg_table *table;
|
|
@@ -98,11 +99,10 @@ static void msm_audio_ion_add_allocation(
|
|
|
mutex_unlock(&(msm_audio_ion_data->list_mutex));
|
|
|
}
|
|
|
|
|
|
-static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf,
|
|
|
- struct msm_audio_ion_private *ion_data)
|
|
|
+static int msm_audio_ion_map_kernel(struct dma_buf *dma_buf,
|
|
|
+ struct msm_audio_ion_private *ion_data, struct dma_buf_map *dma_vmap)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
- void *addr = NULL;
|
|
|
struct msm_audio_alloc_data *alloc_data = NULL;
|
|
|
|
|
|
rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
|
|
@@ -111,8 +111,8 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf,
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
|
- addr = dma_buf_vmap(dma_buf);
|
|
|
- if (!addr) {
|
|
|
+ rc = dma_buf_vmap(dma_buf, dma_vmap);
|
|
|
+ if (rc) {
|
|
|
pr_err("%s: kernel mapping of dma_buf failed\n",
|
|
|
__func__);
|
|
|
goto exit;
|
|
@@ -126,14 +126,14 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf,
|
|
|
list_for_each_entry(alloc_data, &(ion_data->alloc_list),
|
|
|
list) {
|
|
|
if (alloc_data->dma_buf == dma_buf) {
|
|
|
- alloc_data->vaddr = addr;
|
|
|
+ alloc_data->vmap = dma_vmap;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
mutex_unlock(&(ion_data->list_mutex));
|
|
|
|
|
|
exit:
|
|
|
- return addr;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
|
|
@@ -143,7 +143,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
|
|
|
|
|
|
struct msm_audio_alloc_data *alloc_data = NULL;
|
|
|
int rc = 0;
|
|
|
- void *vaddr = NULL;
|
|
|
+ struct dma_buf_map dma_vmap;
|
|
|
struct device *cb_dev = ion_data->cb_dev;
|
|
|
|
|
|
/* Data required per buffer mapping */
|
|
@@ -185,14 +185,14 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
|
|
|
/* physical address from mapping */
|
|
|
if (!is_iova) {
|
|
|
*addr = sg_phys(alloc_data->table->sgl);
|
|
|
- vaddr = msm_audio_ion_map_kernel((void *)dma_buf, ion_data);
|
|
|
- if (IS_ERR_OR_NULL(vaddr)) {
|
|
|
- pr_err("%s: ION memory mapping for AUDIO failed\n",
|
|
|
- __func__);
|
|
|
+ rc = msm_audio_ion_map_kernel((void *)dma_buf, ion_data, &dma_vmap);
|
|
|
+ if (rc) {
|
|
|
+ pr_err("%s: ION memory mapping for AUDIO failed, err:%d\n",
|
|
|
+ __func__, rc);
|
|
|
rc = -ENOMEM;
|
|
|
goto detach_dma_buf;
|
|
|
}
|
|
|
- alloc_data->vaddr = vaddr;
|
|
|
+ alloc_data->vmap = &dma_vmap;
|
|
|
} else {
|
|
|
*addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
|
|
|
}
|
|
@@ -284,7 +284,7 @@ err:
|
|
|
static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf, struct msm_audio_ion_private *ion_data)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
- void *vaddr = NULL;
|
|
|
+ struct dma_buf_map *dma_vmap = NULL;
|
|
|
struct msm_audio_alloc_data *alloc_data = NULL;
|
|
|
struct device *cb_dev = ion_data->cb_dev;
|
|
|
|
|
@@ -296,13 +296,13 @@ static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf, struct msm_audio_
|
|
|
list_for_each_entry(alloc_data, &(ion_data->alloc_list),
|
|
|
list) {
|
|
|
if (alloc_data->dma_buf == dma_buf) {
|
|
|
- vaddr = alloc_data->vaddr;
|
|
|
+ dma_vmap = alloc_data->vmap;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
mutex_unlock(&(ion_data->list_mutex));
|
|
|
|
|
|
- if (!vaddr) {
|
|
|
+ if (!dma_vmap) {
|
|
|
dev_err(cb_dev,
|
|
|
"%s: cannot find allocation for dma_buf %pK",
|
|
|
__func__, dma_buf);
|
|
@@ -310,7 +310,7 @@ static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf, struct msm_audio_
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
- dma_buf_vunmap(dma_buf, vaddr);
|
|
|
+ dma_buf_vunmap(dma_buf, dma_vmap);
|
|
|
|
|
|
rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
|
|
|
if (rc) {
|
|
@@ -324,12 +324,13 @@ err:
|
|
|
}
|
|
|
|
|
|
static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
|
|
|
- size_t *plen, void **vaddr, struct msm_audio_ion_private *ion_data)
|
|
|
+ size_t *plen, struct dma_buf_map *dma_vmap,
|
|
|
+ struct msm_audio_ion_private *ion_data)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
bool is_iova = true;
|
|
|
|
|
|
- if (!dma_buf || !paddr || !vaddr || !plen) {
|
|
|
+ if (!dma_buf || !paddr || !plen) {
|
|
|
pr_err("%s: Invalid params\n", __func__);
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -342,9 +343,10 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
- *vaddr = msm_audio_ion_map_kernel(dma_buf, ion_data);
|
|
|
- if (IS_ERR_OR_NULL(*vaddr)) {
|
|
|
- pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
|
|
|
+ rc = msm_audio_ion_map_kernel(dma_buf, ion_data, dma_vmap);
|
|
|
+ if (rc) {
|
|
|
+ pr_err("%s: ION memory mapping for AUDIO failed, err:%d\n",
|
|
|
+ __func__, rc);
|
|
|
rc = -ENOMEM;
|
|
|
msm_audio_dma_buf_unmap(dma_buf, ion_data);
|
|
|
goto err;
|
|
@@ -460,13 +462,13 @@ void msm_audio_get_handle(int fd, void **handle)
|
|
|
* @bufsz: buffer size
|
|
|
* @paddr: Physical address to be assigned with allocated region
|
|
|
* @plen: length of allocated region to be assigned
|
|
|
- * @vaddr: virtual address to be assigned
|
|
|
+ * @dma_vmap: Virtual mapping vmap pointer to be assigned
|
|
|
*
|
|
|
* Returns 0 on success or error on failure
|
|
|
*/
|
|
|
static int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
|
|
|
unsigned long *ionflag, size_t bufsz,
|
|
|
- dma_addr_t *paddr, size_t *plen, void **vaddr,
|
|
|
+ dma_addr_t *paddr, size_t *plen, struct dma_buf_map *dma_vmap,
|
|
|
struct msm_audio_ion_private *ion_data)
|
|
|
{
|
|
|
int rc = 0;
|
|
@@ -476,7 +478,7 @@ static int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
|
|
|
return -EPROBE_DEFER;
|
|
|
}
|
|
|
|
|
|
- if (!dma_buf || !paddr || !vaddr || !plen) {
|
|
|
+ if (!dma_buf || !paddr || !plen) {
|
|
|
pr_err("%s: Invalid params\n", __func__);
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -499,13 +501,13 @@ static int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
|
|
|
}
|
|
|
}
|
|
|
if (ion_data->smmu_enabled) {
|
|
|
- rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr, ion_data);
|
|
|
+ rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, dma_vmap, ion_data);
|
|
|
if (rc) {
|
|
|
pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
|
|
|
goto err;
|
|
|
}
|
|
|
pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
|
|
|
- *vaddr, bufsz);
|
|
|
+ dma_vmap->vaddr, bufsz);
|
|
|
} else {
|
|
|
msm_audio_dma_buf_map(*dma_buf, paddr, plen, true, ion_data);
|
|
|
}
|
|
@@ -609,7 +611,7 @@ static long msm_audio_ion_ioctl(struct file *file, unsigned int ioctl_num,
|
|
|
void *mem_handle;
|
|
|
dma_addr_t paddr;
|
|
|
size_t pa_len = 0;
|
|
|
- void *vaddr;
|
|
|
+ struct dma_buf_map dma_vmap;
|
|
|
int ret = 0;
|
|
|
int dest_perms_map[2] = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE};
|
|
|
int source_vm_map[1] = {VMID_HLOS};
|
|
@@ -629,7 +631,7 @@ static long msm_audio_ion_ioctl(struct file *file, unsigned int ioctl_num,
|
|
|
if (!msm_audio_fd_data)
|
|
|
return -ENOMEM;
|
|
|
ret = msm_audio_ion_import((struct dma_buf **)&mem_handle, (int)ioctl_param,
|
|
|
- NULL, 0, &paddr, &pa_len, &vaddr, ion_data);
|
|
|
+ NULL, 0, &paddr, &pa_len, &dma_vmap, ion_data);
|
|
|
if (ret < 0) {
|
|
|
pr_err("%s Memory map Failed %d\n", __func__, ret);
|
|
|
kfree(msm_audio_fd_data);
|