diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 2692a7fc5d8d..7486ad7dc80c 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -119,7 +119,7 @@ struct session { struct tap_point rx_tap_point; phys_addr_t sess_paddr; void *sess_kvaddr; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; struct mem_map_table tp_mem_table; }; @@ -145,7 +145,6 @@ struct hpcm_drv { struct mutex lock; struct session session[MAX_SESSION]; struct mixer_conf mixer_conf; - struct ion_client *ion_client; struct start_cmd start_cmd; }; @@ -452,19 +451,12 @@ static void hpcm_free_allocated_mem(struct hpcm_drv *prtd) paddr = sess->sess_paddr; if (paddr) { - msm_audio_ion_free(prtd->ion_client, sess->ion_handle); - prtd->ion_client = NULL; - sess->ion_handle = NULL; - msm_audio_ion_free(sess->tp_mem_table.client, - sess->tp_mem_table.handle); - sess->tp_mem_table.client = NULL; - sess->tp_mem_table.handle = NULL; + msm_audio_ion_free(sess->dma_buf); + sess->dma_buf = NULL; + msm_audio_ion_free(sess->tp_mem_table.dma_buf); + sess->tp_mem_table.dma_buf = NULL; sess->sess_paddr = 0; sess->sess_kvaddr = 0; - sess->ion_handle = 0; - prtd->ion_client = 0; - sess->tp_mem_table.client = 0; - sess->tp_mem_table.handle = 0; txtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0; txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0; @@ -531,9 +523,7 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) txtp = &sess->tx_tap_point; rxtp = &sess->rx_tap_point; - result = msm_audio_ion_alloc("host_pcm_buffer", - &prtd->ion_client, - &sess->ion_handle, + result = msm_audio_ion_alloc(&sess->dma_buf, VHPCM_BLOCK_SIZE, &sess->sess_paddr, &mem_len, @@ -549,9 +539,7 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) pr_debug("%s: Host PCM memory block allocated\n", __func__); /* Allocate mem_map_table for tap point */ - result = msm_audio_ion_alloc("host_pcm_table", - &sess->tp_mem_table.client, - &sess->tp_mem_table.handle, + result = msm_audio_ion_alloc(&sess->tp_mem_table.dma_buf, sizeof(struct vss_imemory_table_t), &sess->tp_mem_table.phys, &len, @@ -560,9 +548,8 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) if (result) { pr_err("%s: msm_audio_ion_alloc error, rc = %d\n", __func__, result); - msm_audio_ion_free(prtd->ion_client, sess->ion_handle); - prtd->ion_client = NULL; - sess->ion_handle = NULL; + msm_audio_ion_free(sess->dma_buf); + sess->dma_buf = NULL; sess->sess_paddr = 0; sess->sess_kvaddr = 0; ret = -ENOMEM; diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 62753155e873..249f8a5b1e9b 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -20,6 +20,7 @@ #include <linux/slab.h> #include <linux/of_device.h> #include <linux/dma-mapping.h> +#include <linux/dma-buf.h> #include <sound/core.h> #include <sound/soc.h> @@ -451,7 +452,13 @@ static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, apd = prtd->audio_client->port; ab = &(apd[dir].buf[0]); - mmap_fd->fd = ion_share_dma_buf_fd(ab->client, ab->handle); + /* + * Passing O_CLOEXEC as flag passed to fd, to be in sync with + * previous implimentation. + * This was the flag used by previous internal wrapper API, which + * used to call dma_buf_fd internally. + */ + mmap_fd->fd = dma_buf_fd(ab->dma_buf, O_CLOEXEC); if (mmap_fd->fd >= 0) { mmap_fd->dir = dir; mmap_fd->actual_size = ab->actual_size; diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index ad1dc3d35ce3..95794796c4f1 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -442,11 +442,9 @@ static void delete_cal_block(struct cal_block_data *cal_block) cal_block->client_info = NULL; kfree(cal_block->cal_info); cal_block->cal_info = NULL; - if (cal_block->map_data.ion_client != NULL) { - msm_audio_ion_free(cal_block->map_data.ion_client, - cal_block->map_data.ion_handle); - cal_block->map_data.ion_client = NULL; - cal_block->map_data.ion_handle = NULL; + if (cal_block->map_data.dma_buf != NULL) { + msm_audio_ion_free(cal_block->map_data.dma_buf); + cal_block->map_data.dma_buf = NULL; } kfree(cal_block); done: @@ -604,9 +602,7 @@ static int cal_block_ion_alloc(struct cal_block_data *cal_block) goto done; } - ret = msm_audio_ion_import("audio_cal_client", - &cal_block->map_data.ion_client, - &cal_block->map_data.ion_handle, + ret = msm_audio_ion_import(&cal_block->map_data.dma_buf, cal_block->map_data.ion_map_handle, NULL, 0, &cal_block->cal_data.paddr, @@ -736,10 +732,8 @@ static int realloc_memory(struct cal_block_data *cal_block) { int ret = 0; - msm_audio_ion_free(cal_block->map_data.ion_client, - cal_block->map_data.ion_handle); - cal_block->map_data.ion_client = NULL; - cal_block->map_data.ion_handle = NULL; + msm_audio_ion_free(cal_block->map_data.dma_buf); + cal_block->map_data.dma_buf = NULL; cal_block->cal_data.size = 0; ret = cal_block_ion_alloc(cal_block); diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index e8f22e79f8cb..7f332f4f7aa6 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -420,7 +420,7 @@ void audio_aio_reset_ion_region(struct q6audio_aio *audio) list_for_each_safe(ptr, next, &audio->ion_region_queue) { region = list_entry(ptr, struct audio_aio_ion_region, list); list_del(®ion->list); - msm_audio_ion_free_legacy(audio->client, region->handle); + msm_audio_ion_free(region->dma_buf); kfree(region); } } @@ -614,7 +614,6 @@ int audio_aio_release(struct inode *inode, struct file *file) audio_aio_disable(audio); audio_aio_unmap_ion_region(audio); audio_aio_reset_ion_region(audio); - msm_audio_ion_client_destroy(audio->client); audio->event_abort = 1; wake_up(&audio->event_wait); audio_aio_reset_event_queue(audio); @@ -960,11 +959,11 @@ static int audio_aio_ion_check(struct q6audio_aio *audio, static int audio_aio_ion_add(struct q6audio_aio *audio, struct msm_audio_ion_info *info) { - ion_phys_addr_t paddr = 0; + dma_addr_t paddr = 0; size_t len = 0; struct audio_aio_ion_region *region; int rc = -EINVAL; - struct ion_handle *handle = NULL; + struct dma_buf *dma_buf = NULL; unsigned long ionflag; void *kvaddr = NULL; @@ -976,8 +975,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, goto end; } - rc = msm_audio_ion_import_legacy("Audio_Dec_Client", audio->client, - &handle, info->fd, &ionflag, + rc = msm_audio_ion_import(&dma_buf, info->fd, &ionflag, 0, &paddr, &len, &kvaddr); if (rc) { pr_err("%s: msm audio ion alloc failed\n", __func__); @@ -990,7 +988,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, goto ion_error; } - region->handle = handle; + region->dma_buf = dma_buf; region->vaddr = info->vaddr; region->fd = info->fd; region->paddr = paddr; @@ -1012,7 +1010,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, mmap_error: list_del(®ion->list); ion_error: - msm_audio_ion_free_legacy(audio->client, handle); + msm_audio_ion_free(dma_buf); import_error: kfree(region); end: @@ -1049,8 +1047,7 @@ static int audio_aio_ion_remove(struct q6audio_aio *audio, __func__, audio); list_del(®ion->list); - msm_audio_ion_free_legacy(audio->client, - region->handle); + msm_audio_ion_free(region->dma_buf); kfree(region); rc = 0; break; @@ -1378,22 +1375,12 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) goto cleanup; } } - audio->client = msm_audio_ion_client_create("Audio_Dec_Client"); - if (IS_ERR_OR_NULL(audio->client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto cleanup; - } - pr_debug("Ion client create in audio_aio_open %pK", audio->client); rc = register_volume_listener(audio); if (rc < 0) - goto ion_cleanup; + goto cleanup; return 0; -ion_cleanup: - msm_audio_ion_client_destroy(audio->client); - audio->client = NULL; cleanup: list_for_each_safe(ptr, next, &audio->free_event_queue) { e_node = list_first_entry(&audio->free_event_queue, diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h index e44f9d9c642a..1993f6047ef1 100644 --- a/dsp/codecs/audio_utils_aio.h +++ b/dsp/codecs/audio_utils_aio.h @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -119,7 +119,7 @@ struct ws_mgr { struct audio_aio_ion_region { struct list_head list; - struct ion_handle *handle; + struct dma_buf *dma_buf; int fd; void *vaddr; phys_addr_t paddr; @@ -182,7 +182,6 @@ struct q6audio_aio { struct list_head free_event_queue; struct list_head event_queue; struct list_head ion_region_queue; /* protected by lock */ - struct ion_client *client; struct audio_aio_drv_operations drv_ops; union msm_audio_event_payload eos_write_payload; uint32_t device_events; diff --git a/dsp/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c index cd3da4d642d9..fff98b57287c 100644 --- a/dsp/msm-dts-srs-tm-config.c +++ b/dsp/msm-dts-srs-tm-config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,8 +25,7 @@ static int srs_port_id[AFE_MAX_PORTS] = {-1}; static int srs_copp_idx[AFE_MAX_PORTS] = {-1}; static union srs_trumedia_params_u msm_srs_trumedia_params; -static struct ion_client *ion_client; -static struct ion_handle *ion_handle; +struct dma_buf *dma_buf; static struct param_outband po; static atomic_t ref_cnt; #define ION_MEM_SIZE (8 * 1024) @@ -299,13 +298,13 @@ static int reg_ion_mem(void) { int rc; - rc = msm_audio_ion_alloc("SRS_TRUMEDIA", &ion_client, &ion_handle, - ION_MEM_SIZE, &po.paddr, (size_t *)&po.size, + rc = msm_audio_ion_alloc(&dma_buf, ION_MEM_SIZE, + &po.paddr, (size_t *)&po.size, &po.kvaddr); if (rc != 0) pr_err("%s: failed to allocate memory.\n", __func__); - pr_debug("%s: exited ion_client = %pK, ion_handle = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n", - __func__, ion_client, ion_handle, (long)po.paddr, + pr_debug("%s: exited dma_buf = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n", + __func__, dma_buf, (long)po.paddr, (unsigned int)po.size, po.kvaddr, rc); return rc; } @@ -323,7 +322,8 @@ void msm_dts_srs_tm_ion_memmap(struct param_outband *po_) static void unreg_ion_mem(void) { - msm_audio_ion_free(ion_client, ion_handle); + msm_audio_ion_free(dma_buf); + dma_buf = NULL; po.kvaddr = NULL; po.paddr = 0; po.size = 0; diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 113829057aff..c0879218515b 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,9 +23,10 @@ #include <linux/dma-buf.h> #include <linux/iommu.h> #include <linux/platform_device.h> -#include <ipc/apr.h> #include <linux/of_device.h> #include <linux/export.h> +#include <linux/ion_kernel.h> +#include <ipc/apr.h> #include <asm/dma-iommu.h> #include <dsp/msm_audio_ion.h> @@ -40,7 +41,6 @@ #define MSM_AUDIO_SMMU_SID_OFFSET 32 struct msm_audio_ion_private { - bool smmu_enabled; bool audioheap_enabled; struct device *cb_dev; struct dma_iommu_mapping *mapping; @@ -52,9 +52,8 @@ struct msm_audio_ion_private { }; struct msm_audio_alloc_data { - struct ion_client *client; - struct ion_handle *handle; size_t len; + void *vaddr; struct dma_buf *dma_buf; struct dma_buf_attachment *attach; struct sg_table *table; @@ -63,17 +62,6 @@ struct msm_audio_alloc_data { static struct msm_audio_ion_private msm_audio_ion_data = {0,}; -static int msm_audio_ion_get_phys(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len); - -static int msm_audio_dma_buf_map(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len); - -static int msm_audio_dma_buf_unmap(struct ion_client *client, - struct ion_handle *handle); - static void msm_audio_ion_add_allocation( struct msm_audio_ion_private *msm_audio_ion_data, struct msm_audio_alloc_data *alloc_data) @@ -89,196 +77,408 @@ static void msm_audio_ion_add_allocation( mutex_unlock(&(msm_audio_ion_data->list_mutex)); } +static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, + dma_addr_t *addr, size_t *len) +{ + + struct msm_audio_alloc_data *alloc_data; + struct device *cb_dev; + int rc = 0; + + cb_dev = msm_audio_ion_data.cb_dev; + + /* Data required per buffer mapping */ + alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); + if (!alloc_data) + return -ENOMEM; + + alloc_data->dma_buf = dma_buf; + alloc_data->len = dma_buf->size; + *len = dma_buf->size; + + /* Attach the dma_buf to context bank device */ + alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, + cb_dev); + if (IS_ERR(alloc_data->attach)) { + rc = PTR_ERR(alloc_data->attach); + dev_err(cb_dev, + "%s: Fail to attach dma_buf to CB, rc = %d\n", + __func__, rc); + goto err_attach; + } + + /* + * Get the scatter-gather list. + * There is no info as this is a write buffer or + * read buffer, hence the request is bi-directional + * to accommodate both read and write mappings. + */ + alloc_data->table = dma_buf_map_attachment(alloc_data->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(alloc_data->table)) { + rc = PTR_ERR(alloc_data->table); + dev_err(cb_dev, + "%s: Fail to map attachment, rc = %d\n", + __func__, rc); + goto err_map_attach; + } + + /* physical address from mapping */ + *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); + + msm_audio_ion_add_allocation(&msm_audio_ion_data, + alloc_data); + return rc; + +err_map_attach: + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); +err_attach: + kfree(alloc_data); + + return rc; +} + +static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf) +{ + int rc = 0; + struct msm_audio_alloc_data *alloc_data = NULL; + struct list_head *ptr, *next; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + bool found = false; + + /* + * Though list_for_each_safe is delete safe, lock + * should be explicitly acquired to avoid race condition + * on adding elements to the list. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_safe(ptr, next, + &(msm_audio_ion_data.alloc_list)) { + + alloc_data = list_entry(ptr, struct msm_audio_alloc_data, + list); + + if (alloc_data->dma_buf == dma_buf) { + found = true; + dma_buf_unmap_attachment(alloc_data->attach, + alloc_data->table, + DMA_BIDIRECTIONAL); + + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); + + dma_buf_put(alloc_data->dma_buf); + + list_del(&(alloc_data->list)); + kfree(alloc_data); + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, dma_buf %pK", + __func__, dma_buf); + rc = -EINVAL; + } + + return rc; +} + +static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, + dma_addr_t *addr, size_t *len) +{ + int rc = 0; + + rc = msm_audio_dma_buf_map(dma_buf, addr, len); + if (rc) { + pr_err("%s: failed to map DMA buf, err = %d\n", + __func__, rc); + goto err; + } + /* Append the SMMU SID information to the IOVA address */ + *addr |= msm_audio_ion_data.smmu_sid_bits; + + pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); +err: + return rc; +} + +static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) +{ + int i = 0; + int rc = 0; + void *addr = NULL; + unsigned int pg_cnt = 0; + struct msm_audio_alloc_data *alloc_data = NULL; + + rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + if (rc) { + pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__); + goto exit; + } + + pg_cnt = dma_buf->size / PAGE_SIZE; + if (dma_buf->size % PAGE_SIZE) + pg_cnt++; + + if (pg_cnt == 0) { + pr_err("%s: Page count is NULL\n", __func__); + goto exit; + } + + /* Map the first page, and store the address to addr */ + addr = dma_buf_kmap(dma_buf, 0); + if (!addr) { + pr_err("%s: mapping kernel buffer failed for page 0\n", + __func__); + goto exit; + } + /* Map remaining pages */ + for (i = 1; i < pg_cnt; i++) { + if (!dma_buf_kmap(dma_buf, i)) { + pr_err("%s: mapping kernel buffer failed for page %d\n", + __func__, i); + goto err; + } + } + + /* + * TBD: remove the below section once new API + * for mapping kernel virtual address is available. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + alloc_data->vaddr = addr; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + return addr; + +err: + for (; i > 0; i--) + dma_buf_kunmap(dma_buf, i - 1, addr); + addr = NULL; +exit: + return addr; +} + +static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) +{ + int i, rc = 0; + unsigned int pg_cnt = 0; + void *vaddr = NULL; + struct msm_audio_alloc_data *alloc_data = NULL; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + + /* + * TBD: remove the below section once new API + * for unmapping kernel virtual address is available. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + vaddr = alloc_data->vaddr; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!vaddr) { + dev_err(cb_dev, + "%s: cannot find allocation for dma_buf %pK", + __func__, dma_buf); + goto err; + } + + pg_cnt = dma_buf->size / PAGE_SIZE; + if (dma_buf->size % PAGE_SIZE) + pg_cnt++; + + for (i = 0; i < pg_cnt; i++) + dma_buf_kunmap(dma_buf, i, vaddr); + + rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + if (rc) { + dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n", + __func__); + goto err; + } + +err: + return; +} + +static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, + size_t *plen, void *vaddr) +{ + int rc = 0; + + rc = msm_audio_ion_get_phys(dma_buf, paddr, plen); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + goto err; + } + + vaddr = msm_audio_ion_map_kernel(dma_buf); + if (IS_ERR_OR_NULL((void *)vaddr)) { + pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); + rc = -ENOMEM; + goto err; + } + +err: + return rc; +} + /** * msm_audio_ion_alloc - * Allocs ION memory for given client name * - * @name: Name of audio ION client - * @client: ION client to be assigned - * @handle: ION handle to be assigned + * @dma_buf: dma_buf for the ION memory * @bufsz: buffer size * @paddr: Physical address to be assigned with allocated region - * @pa_len: length of allocated region to be assigned + * @plen: length of allocated region to be assigned * vaddr: virtual address to be assigned * * Returns 0 on success or error on failure */ -int msm_audio_ion_alloc(const char *name, struct ion_client **client, - struct ion_handle **handle, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) +int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, + dma_addr_t *paddr, size_t *plen, void **vaddr) { int rc = -EINVAL; unsigned long err_ion_ptr = 0; - if ((msm_audio_ion_data.smmu_enabled == true) && - !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } - if (!name || !client || !handle || !paddr || !vaddr - || !bufsz || !pa_len) { + if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) { pr_err("%s: Invalid params\n", __func__); return -EINVAL; } - *client = msm_audio_ion_client_create(name); - if (IS_ERR_OR_NULL((void *)(*client))) { - pr_err("%s: ION create client for AUDIO failed\n", __func__); + + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + if (IS_ERR((void *)(*dma_buf))) + err_ion_ptr = PTR_ERR((int *)(*dma_buf)); + pr_err("%s:ION alloc fail err ptr=%ld\n", + __func__, err_ion_ptr); + rc = -ENOMEM; goto err; } - *handle = ion_alloc(*client, bufsz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL((void *) (*handle))) { - if (msm_audio_ion_data.smmu_enabled == true) { - pr_debug("system heap is used"); - msm_audio_ion_data.audioheap_enabled = 0; - *handle = ion_alloc(*client, bufsz, SZ_4K, - ION_HEAP(ION_SYSTEM_HEAP_ID), 0); - } - if (IS_ERR_OR_NULL((void *) (*handle))) { - if (IS_ERR((void *)(*handle))) - err_ion_ptr = PTR_ERR((int *)(*handle)); - pr_err("%s:ION alloc fail err ptr=%ld, smmu_enabled=%d\n", - __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); - rc = -ENOMEM; - goto err_ion_client; - } - } else { - pr_debug("audio heap is used"); - msm_audio_ion_data.audioheap_enabled = 1; - } - - rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len); + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); if (rc) { - pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - goto err_ion_handle; - } - - *vaddr = ion_map_kernel(*client, *handle); - if (IS_ERR_OR_NULL((void *)*vaddr)) { - pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); - goto err_ion_handle; + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); + goto err_dma_buf; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); - if (bufsz != 0) { - pr_debug("%s: memset to 0 %pK %zd\n", __func__, *vaddr, bufsz); - memset((void *)*vaddr, 0, bufsz); - } + memset((void *)*vaddr, 0, bufsz); return rc; -err_ion_handle: - ion_free(*client, *handle); -err_ion_client: - msm_audio_ion_client_destroy(*client); - *handle = NULL; - *client = NULL; +err_dma_buf: + dma_buf_put(*dma_buf); err: return rc; } EXPORT_SYMBOL(msm_audio_ion_alloc); -int msm_audio_ion_import(const char *name, struct ion_client **client, - struct ion_handle **handle, int fd, +/** + * msm_audio_ion_import- + * Import ION buffer with given file descriptor + * + * @dma_buf: dma_buf for the ION memory + * @fd: file descriptor for the ION memory + * @ionflag: flags associated with ION buffer + * @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 + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) + dma_addr_t *paddr, size_t *plen, void **vaddr) { int rc = 0; - if ((msm_audio_ion_data.smmu_enabled == true) && - !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } - if (!name || !client || !handle || !paddr || !vaddr || !pa_len) { + if (!dma_buf || !paddr || !vaddr || !plen) { pr_err("%s: Invalid params\n", __func__); rc = -EINVAL; goto err; } - *client = msm_audio_ion_client_create(name); - if (IS_ERR_OR_NULL((void *)(*client))) { - pr_err("%s: ION create client for AUDIO failed\n", __func__); + /* bufsz should be 0 and fd shouldn't be 0 as of now */ + *dma_buf = dma_buf_get(fd); + pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd); + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + pr_err("%s: dma_buf_get failed\n", __func__); rc = -EINVAL; goto err; } - /* name should be audio_acdb_client or Audio_Dec_Client, - * bufsz should be 0 and fd shouldn't be 0 as of now - */ - *handle = ion_import_dma_buf_fd(*client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, - name, fd, *handle); - if (IS_ERR_OR_NULL((void *) (*handle))) { - pr_err("%s: ion import dma buffer failed\n", - __func__); - rc = -EINVAL; - goto err_destroy_client; - } - if (ionflag != NULL) { - rc = ion_handle_get_flags(*client, *handle, ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", - __func__); - goto err_ion_handle; - } + pr_err("%s: could not get flags for the dma_buf\n", + __func__); + rc = -EOPNOTSUPP; + goto err_ion_flag; } - rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len); + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); if (rc) { - pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - goto err_ion_handle; - } - - *vaddr = ion_map_kernel(*client, *handle); - if (IS_ERR_OR_NULL((void *)*vaddr)) { - pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); - rc = -ENOMEM; - goto err_ion_handle; + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); + goto err_ion_flag; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); return 0; -err_ion_handle: - ion_free(*client, *handle); -err_destroy_client: - msm_audio_ion_client_destroy(*client); - *client = NULL; - *handle = NULL; +err_ion_flag: + dma_buf_put(*dma_buf); err: + *dma_buf = NULL; return rc; } +EXPORT_SYMBOL(msm_audio_ion_import); /** * msm_audio_ion_free - * fress ION memory for given client and handle * - * @client: ION client - * @handle: ION handle + * @dma_buf: dma_buf for the ION memory * * Returns 0 on success or error on failure */ -int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) +int msm_audio_ion_free(struct dma_buf *dma_buf) { - if (!client || !handle) { - pr_err("%s Invalid params\n", __func__); + if (!dma_buf) { + pr_err("%s: dma_buf invalid\n", __func__); return -EINVAL; } - if (msm_audio_ion_data.smmu_enabled) - msm_audio_dma_buf_unmap(client, handle); - ion_unmap_kernel(client, handle); + msm_audio_ion_unmap_kernel(dma_buf); + + msm_audio_dma_buf_unmap(dma_buf); - ion_free(client, handle); - msm_audio_ion_client_destroy(client); return 0; } EXPORT_SYMBOL(msm_audio_ion_free); @@ -287,35 +487,42 @@ EXPORT_SYMBOL(msm_audio_ion_free); * msm_audio_ion_mmap - * Audio ION memory map * - * @ab: audio buf pointer + * @abuff: audio buf pointer * @vma: virtual mem area * * Returns 0 on success or error on failure */ -int msm_audio_ion_mmap(struct audio_buffer *ab, +int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma) { + struct msm_audio_alloc_data *alloc_data = NULL; struct sg_table *table; unsigned long addr = vma->vm_start; unsigned long offset = vma->vm_pgoff * PAGE_SIZE; struct scatterlist *sg; unsigned int i; struct page *page; - int ret; + int ret = 0; + bool found = false; + struct device *cb_dev = msm_audio_ion_data.cb_dev; - pr_debug("%s\n", __func__); + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == abuff->dma_buf) { + found = true; + table = alloc_data->table; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); - table = ion_sg_table(ab->client, ab->handle); - - if (IS_ERR(table)) { - pr_err("%s: Unable to get sg_table from ion: %ld\n", - __func__, PTR_ERR(table)); - return PTR_ERR(table); - } else if (!table) { - pr_err("%s: sg_list is NULL\n", __func__); + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, dma_buf %pK", + __func__, abuff->dma_buf); return -EINVAL; } - /* uncached */ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); @@ -354,383 +561,29 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, return 0; } } else { - ion_phys_addr_t phys_addr; - size_t phys_len; - size_t va_len = 0; - pr_debug("%s: page is NULL\n", __func__); - ret = ion_phys(ab->client, ab->handle, &phys_addr, &phys_len); - if (ret) { - pr_err("%s: Unable to get phys address from ION buffer: %d\n" - , __func__, ret); - return ret; - } - pr_debug("phys=%pKK len=%zd\n", &phys_addr, phys_len); - pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%lu\n", - vma, (unsigned int)vma->vm_start, - (unsigned int)vma->vm_end, vma->vm_pgoff, - (unsigned long)pgprot_val(vma->vm_page_prot)); - va_len = vma->vm_end - vma->vm_start; - if ((offset > phys_len) || (va_len > phys_len-offset)) { - pr_err("wrong offset size %ld, lens= %zd, va_len=%zd\n", - offset, phys_len, va_len); - return -EINVAL; - } - ret = remap_pfn_range(vma, vma->vm_start, - __phys_to_pfn(phys_addr) + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); + ret = -EINVAL; } - return 0; + + return ret; } EXPORT_SYMBOL(msm_audio_ion_mmap); - -bool msm_audio_ion_is_smmu_available(void) -{ - return msm_audio_ion_data.smmu_enabled; -} - -/* move to static section again */ -struct ion_client *msm_audio_ion_client_create(const char *name) -{ - struct ion_client *pclient = NULL; - - pclient = msm_ion_client_create(name); - return pclient; -} -EXPORT_SYMBOL(msm_audio_ion_client_create); - /** - * msm_audio_ion_client_destroy - - * Removes ION client handle + * msm_audio_populate_upper_32_bits - + * retrieve upper 32bits of 64bit address * - * @client: ION client + * @pa: 64bit physical address * */ -void msm_audio_ion_client_destroy(struct ion_client *client) +u32 msm_audio_populate_upper_32_bits(dma_addr_t pa) { - pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__, - client, msm_audio_ion_data.smmu_enabled); - - ion_client_destroy(client); -} -EXPORT_SYMBOL(msm_audio_ion_client_destroy); - -/** - * msm_audio_ion_import_legacy - - * Alloc ION memory for given size - * - * @name: ION client name - * @client: ION client - * @handle: ION handle to be updated - * @fd: ION fd - * @ionflag: Flags for ION handle - * @bufsz: buffer size - * @paddr: pointer to be updated with physical address of allocated ION memory - * @pa_len: pointer to be updated with size of physical memory - * @vaddr: pointer to be updated with virtual address - * - * Returns 0 on success or error on failure - */ -int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, - struct ion_handle **handle, int fd, - unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) -{ - int rc = 0; - - if (!name || !client || !handle || !paddr || !vaddr || !pa_len) { - pr_err("%s: Invalid params\n", __func__); - rc = -EINVAL; - goto err; - } - /* client is already created for legacy and given - * name should be audio_acdb_client or Audio_Dec_Client, - * bufsz should be 0 and fd shouldn't be 0 as of now - */ - *handle = ion_import_dma_buf_fd(client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, - name, fd, *handle); - if (IS_ERR_OR_NULL((void *)(*handle))) { - pr_err("%s: ion import dma buffer failed\n", - __func__); - rc = -EINVAL; - goto err; - } - - if (ionflag != NULL) { - rc = ion_handle_get_flags(client, *handle, ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", - __func__); - rc = -EINVAL; - goto err_ion_handle; - } - } - - rc = msm_audio_ion_get_phys(client, *handle, paddr, pa_len); - if (rc) { - pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - rc = -EINVAL; - goto err_ion_handle; - } - - /*Need to add condition SMMU enable or not */ - *vaddr = ion_map_kernel(client, *handle); - if (IS_ERR_OR_NULL((void *)*vaddr)) { - pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); - rc = -EINVAL; - goto err_ion_handle; - } - - if (bufsz != 0) - memset((void *)*vaddr, 0, bufsz); - - return 0; - -err_ion_handle: - ion_free(client, *handle); -err: - return rc; -} -EXPORT_SYMBOL(msm_audio_ion_import_legacy); - -/** - * msm_audio_ion_free_legacy - - * Frees ION memory for given handle - * - * @client: ION client - * @handle: ION handle - * - */ -int msm_audio_ion_free_legacy(struct ion_client *client, - struct ion_handle *handle) -{ - if (msm_audio_ion_data.smmu_enabled) - msm_audio_dma_buf_unmap(client, handle); - - ion_unmap_kernel(client, handle); - - ion_free(client, handle); - /* no client_destrody in legacy*/ - return 0; -} -EXPORT_SYMBOL(msm_audio_ion_free_legacy); - -int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) -{ - unsigned long ionflag = 0; - int rc = 0; - int msm_cache_ops = 0; - - if (!abuff) { - pr_err("%s: Invalid params: %pK\n", __func__, abuff); - return -EINVAL; - } - rc = ion_handle_get_flags(abuff->client, abuff->handle, - &ionflag); - if (rc) { - pr_err("ion_handle_get_flags failed: %d\n", rc); - goto cache_op_failed; - } - - /* has to be CACHED */ - if (ION_IS_CACHED(ionflag)) { - /* ION_IOC_INV_CACHES or ION_IOC_CLEAN_CACHES */ - msm_cache_ops = cache_op; - rc = msm_ion_do_cache_op(abuff->client, - abuff->handle, - (unsigned long *) abuff->data, - (unsigned long)abuff->size, - msm_cache_ops); - if (rc) { - pr_err("cache operation failed %d\n", rc); - goto cache_op_failed; - } - } -cache_op_failed: - return rc; -} - - -static int msm_audio_dma_buf_map(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len) -{ - - struct msm_audio_alloc_data *alloc_data; - struct device *cb_dev; - int rc = 0; - - cb_dev = msm_audio_ion_data.cb_dev; - - /* Data required per buffer mapping */ - alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); - if (!alloc_data) - return -ENOMEM; - - /* Get the ION handle size */ - ion_handle_get_size(client, handle, len); - - alloc_data->client = client; - alloc_data->handle = handle; - alloc_data->len = *len; - - /* Get the dma_buf handle from ion_handle */ - alloc_data->dma_buf = ion_share_dma_buf(client, handle); - if (IS_ERR(alloc_data->dma_buf)) { - rc = PTR_ERR(alloc_data->dma_buf); - dev_err(cb_dev, - "%s: Fail to get dma_buf handle, rc = %d\n", - __func__, rc); - goto err_dma_buf; - } - - /* Attach the dma_buf to context bank device */ - alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, - cb_dev); - if (IS_ERR(alloc_data->attach)) { - rc = PTR_ERR(alloc_data->attach); - dev_err(cb_dev, - "%s: Fail to attach dma_buf to CB, rc = %d\n", - __func__, rc); - goto err_attach; - } - - /* - * Get the scatter-gather list. - * There is no info as this is a write buffer or - * read buffer, hence the request is bi-directional - * to accommodate both read and write mappings. - */ - alloc_data->table = dma_buf_map_attachment(alloc_data->attach, - DMA_BIDIRECTIONAL); - if (IS_ERR(alloc_data->table)) { - rc = PTR_ERR(alloc_data->table); - dev_err(cb_dev, - "%s: Fail to map attachment, rc = %d\n", - __func__, rc); - goto err_map_attach; - } - - rc = dma_map_sg(cb_dev, alloc_data->table->sgl, - alloc_data->table->nents, - DMA_BIDIRECTIONAL); - if (rc != alloc_data->table->nents) { - dev_err(cb_dev, - "%s: Fail to map SG, rc = %d, nents = %d\n", - __func__, rc, alloc_data->table->nents); - goto err_map_sg; - } - /* Make sure not to return rc from dma_map_sg, as it can be nonzero */ - rc = 0; - - /* physical address from mapping */ - *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); - - msm_audio_ion_add_allocation(&msm_audio_ion_data, - alloc_data); - return rc; - -err_map_sg: - dma_buf_unmap_attachment(alloc_data->attach, - alloc_data->table, - DMA_BIDIRECTIONAL); -err_map_attach: - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); -err_attach: - dma_buf_put(alloc_data->dma_buf); - -err_dma_buf: - kfree(alloc_data); - - return rc; -} - -static int msm_audio_dma_buf_unmap(struct ion_client *client, - struct ion_handle *handle) -{ - int rc = 0; - struct msm_audio_alloc_data *alloc_data = NULL; - struct list_head *ptr, *next; - struct device *cb_dev = msm_audio_ion_data.cb_dev; - bool found = false; - - /* - * Though list_for_each_safe is delete safe, lock - * should be explicitly acquired to avoid race condition - * on adding elements to the list. - */ - mutex_lock(&(msm_audio_ion_data.list_mutex)); - list_for_each_safe(ptr, next, - &(msm_audio_ion_data.alloc_list)) { - - alloc_data = list_entry(ptr, struct msm_audio_alloc_data, - list); - - if (alloc_data->handle == handle && - alloc_data->client == client) { - found = true; - dma_unmap_sg(cb_dev, - alloc_data->table->sgl, - alloc_data->table->nents, - DMA_BIDIRECTIONAL); - - dma_buf_unmap_attachment(alloc_data->attach, - alloc_data->table, - DMA_BIDIRECTIONAL); - - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); - - dma_buf_put(alloc_data->dma_buf); - - list_del(&(alloc_data->list)); - kfree(alloc_data); - break; - } - } - mutex_unlock(&(msm_audio_ion_data.list_mutex)); - - if (!found) { - dev_err(cb_dev, - "%s: cannot find allocation, ion_handle %pK, ion_client %pK", - __func__, handle, client); - rc = -EINVAL; - } - - return rc; -} - -static int msm_audio_ion_get_phys(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len) -{ - int rc = 0; - - pr_debug("%s: smmu_enabled = %d\n", __func__, - msm_audio_ion_data.smmu_enabled); - - if (msm_audio_ion_data.smmu_enabled) { - rc = msm_audio_dma_buf_map(client, handle, addr, len); - if (rc) { - pr_err("%s: failed to map DMA buf, err = %d\n", - __func__, rc); - goto err; - } - /* Append the SMMU SID information to the IOVA address */ - *addr |= msm_audio_ion_data.smmu_sid_bits; - } else { - rc = ion_phys(client, handle, addr, len); - } - - pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); -err: - return rc; + if (sizeof(dma_addr_t) == sizeof(u32)) + return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); + else + return upper_32_bits(pa); } +EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); static int msm_audio_smmu_init(struct device *dev) { @@ -768,115 +621,75 @@ static const struct of_device_id msm_audio_ion_dt_match[] = { }; MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match); - -u32 msm_audio_ion_get_smmu_sid_mode32(void) -{ - if (msm_audio_ion_data.smmu_enabled) - return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); - else - return 0; -} - -/** - * msm_audio_populate_upper_32_bits - - * retrieve upper 32bits of 64bit address - * - * @pa: 64bit physical address - * - */ -u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa) -{ - if (sizeof(ion_phys_addr_t) == sizeof(u32)) - return msm_audio_ion_get_smmu_sid_mode32(); - else - return upper_32_bits(pa); -} -EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); - static int msm_audio_ion_probe(struct platform_device *pdev) { int rc = 0; - const char *msm_audio_ion_dt = "qcom,smmu-enabled"; const char *msm_audio_ion_smmu = "qcom,smmu-version"; const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask"; - bool smmu_enabled; enum apr_subsys_state q6_state; struct device *dev = &pdev->dev; + u64 smmu_sid = 0; + u64 smmu_sid_mask = 0; + struct of_phandle_args iommuspec; if (dev->of_node == NULL) { dev_err(dev, "%s: device tree is not found\n", __func__); - msm_audio_ion_data.smmu_enabled = 0; return 0; } - smmu_enabled = of_property_read_bool(dev->of_node, - msm_audio_ion_dt); - msm_audio_ion_data.smmu_enabled = smmu_enabled; - - if (smmu_enabled) { - rc = of_property_read_u32(dev->of_node, - msm_audio_ion_smmu, - &msm_audio_ion_data.smmu_version); - if (rc) { - dev_err(dev, - "%s: qcom,smmu_version missing in DT node\n", - __func__); - return rc; - } - dev_dbg(dev, "%s: SMMU version is (%d)", __func__, - msm_audio_ion_data.smmu_version); - q6_state = apr_get_q6_state(); - if (q6_state == APR_SUBSYS_DOWN) { - dev_dbg(dev, - "defering %s, adsp_state %d\n", - __func__, q6_state); - return -EPROBE_DEFER; - } - dev_dbg(dev, "%s: adsp is ready\n", __func__); + rc = of_property_read_u32(dev->of_node, + msm_audio_ion_smmu, + &msm_audio_ion_data.smmu_version); + if (rc) { + dev_err(dev, + "%s: qcom,smmu_version missing in DT node\n", + __func__); + return rc; } - - dev_dbg(dev, "%s: SMMU is %s\n", __func__, - (smmu_enabled) ? "Enabled" : "Disabled"); - - if (smmu_enabled) { - u64 smmu_sid = 0; - u64 smmu_sid_mask = 0; - struct of_phandle_args iommuspec; - - /* Get SMMU SID information from Devicetree */ - rc = of_property_read_u64(dev->of_node, - msm_audio_ion_smmu_sid_mask, - &smmu_sid_mask); - if (rc) { - dev_err(dev, - "%s: qcom,smmu-sid-mask missing in DT node, using default\n", - __func__); - smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; - } - rc = of_parse_phandle_with_args(dev->of_node, "iommus", - "#iommu-cells", 0, &iommuspec); - if (rc) - dev_err(dev, "%s: could not get smmu SID, ret = %d\n", - __func__, rc); - else - smmu_sid = (iommuspec.args[0] & smmu_sid_mask); - - msm_audio_ion_data.smmu_sid_bits = - smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; - - if (msm_audio_ion_data.smmu_version == 0x2) { - rc = msm_audio_smmu_init(dev); - } else { - dev_err(dev, "%s: smmu version invalid %d\n", - __func__, msm_audio_ion_data.smmu_version); - rc = -EINVAL; - } - if (rc) - dev_err(dev, "%s: smmu init failed, err = %d\n", - __func__, rc); + dev_dbg(dev, "%s: SMMU version is (%d)", __func__, + msm_audio_ion_data.smmu_version); + q6_state = apr_get_q6_state(); + if (q6_state == APR_SUBSYS_DOWN) { + dev_dbg(dev, + "defering %s, adsp_state %d\n", + __func__, q6_state); + return -EPROBE_DEFER; } + dev_dbg(dev, "%s: adsp is ready\n", __func__); + + /* Get SMMU SID information from Devicetree */ + rc = of_property_read_u64(dev->of_node, + msm_audio_ion_smmu_sid_mask, + &smmu_sid_mask); + if (rc) { + dev_err(dev, + "%s: qcom,smmu-sid-mask missing in DT node, using default\n", + __func__); + smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; + } + rc = of_parse_phandle_with_args(dev->of_node, "iommus", + "#iommu-cells", 0, &iommuspec); + if (rc) + dev_err(dev, "%s: could not get smmu SID, ret = %d\n", + __func__, rc); + else + smmu_sid = (iommuspec.args[0] & smmu_sid_mask); + + msm_audio_ion_data.smmu_sid_bits = + smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; + + if (msm_audio_ion_data.smmu_version == 0x2) { + rc = msm_audio_smmu_init(dev); + } else { + dev_err(dev, "%s: smmu version invalid %d\n", + __func__, msm_audio_ion_data.smmu_version); + rc = -EINVAL; + } + if (rc) + dev_err(dev, "%s: smmu init failed, err = %d\n", + __func__, rc); if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; @@ -897,7 +710,6 @@ static int msm_audio_ion_remove(struct platform_device *pdev) arm_iommu_release_mapping(mapping); } - msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; return 0; } diff --git a/dsp/q6adm.c b/dsp/q6adm.c index d5dc960de4a0..dc900edbce4d 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -74,8 +74,7 @@ struct adm_copp { }; struct source_tracking_data { - struct ion_client *ion_client; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; struct param_outband memmap; int apr_cmd_status; }; @@ -1500,10 +1499,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) */ if (this_adm.sourceTrackingData.memmap.paddr != 0) { msm_audio_ion_free( - this_adm.sourceTrackingData.ion_client, - this_adm.sourceTrackingData.ion_handle); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; @@ -1918,7 +1915,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) { int ret = 0; - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for cal index %d!\n", __func__, cal_index); ret = -EINVAL; @@ -3211,10 +3208,8 @@ int adm_close(int port_id, int perf_mode, int copp_idx) __func__, ret); } msm_audio_ion_free( - this_adm.sourceTrackingData.ion_client, - this_adm.sourceTrackingData.ion_handle); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; @@ -5021,9 +5016,7 @@ static int adm_source_tracking_alloc_map_memory(void) pr_debug("%s: Enter\n", __func__); - ret = msm_audio_ion_alloc("SOURCE_TRACKING", - &this_adm.sourceTrackingData.ion_client, - &this_adm.sourceTrackingData.ion_handle, + ret = msm_audio_ion_alloc(&this_adm.sourceTrackingData.dma_buf, AUD_PROC_BLOCK_SIZE, &this_adm.sourceTrackingData.memmap.paddr, &this_adm.sourceTrackingData.memmap.size, @@ -5046,10 +5039,8 @@ static int adm_source_tracking_alloc_map_memory(void) (void *)this_adm.sourceTrackingData.memmap.paddr, (uint32_t)this_adm.sourceTrackingData.memmap.size); - msm_audio_ion_free(this_adm.sourceTrackingData.ion_client, - this_adm.sourceTrackingData.ion_handle); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + msm_audio_ion_free(this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; @@ -5251,8 +5242,7 @@ int __init adm_init(void) if (adm_init_cal_data()) pr_err("%s: could not init cal data!\n", __func__); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 391a7f776551..f926efbdc16b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1515,7 +1515,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) { int ret = 0; - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for cal index %d!\n", __func__, cal_index); ret = -EINVAL; @@ -4502,8 +4502,8 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, ac->port[dir].buf = buf; - rc = msm_audio_ion_alloc("afe_client", &buf[0].client, - &buf[0].handle, bufsz*bufcnt, + rc = msm_audio_ion_alloc(&buf[0].dma_buf, + bufsz * bufcnt, &buf[0].phys, &len, &buf[0].data); if (rc) { @@ -4777,16 +4777,13 @@ int q6afe_audio_client_buf_free_contiguous(unsigned int dir, cnt = port->max_buf_cnt - 1; if (port->buf[0].data) { - pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", + pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, - &port->buf[0].phys, - port->buf[0].client, - port->buf[0].handle); - msm_audio_ion_free(port->buf[0].client, port->buf[0].handle); - port->buf[0].client = NULL; - port->buf[0].handle = NULL; + port->buf[0].dma_buf); + msm_audio_ion_free(port->buf[0].dma_buf); + port->buf[0].dma_buf = NULL; } while (cnt >= 0) { diff --git a/dsp/q6asm.c b/dsp/q6asm.c index caf7df1dce6f..4f61fbec5df2 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Author: Brian Swetland <swetland@google.com> * * This software is licensed under the terms of the GNU General Public @@ -661,7 +661,7 @@ static int remap_cal_data(int32_t cal_type, struct cal_block_data *cal_block) { int ret = 0; - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for cal type %d!\n", __func__, cal_type); ret = -EINVAL; @@ -982,11 +982,9 @@ int q6asm_audio_client_buf_free(unsigned int dir, if (port->buf[cnt].data) { if (!rc || atomic_read(&ac->reset)) msm_audio_ion_free( - port->buf[cnt].client, - port->buf[cnt].handle); + port->buf[cnt].dma_buf); - port->buf[cnt].client = NULL; - port->buf[cnt].handle = NULL; + port->buf[cnt].dma_buf = NULL; port->buf[cnt].data = NULL; port->buf[cnt].phys = 0; --(port->max_buf_cnt); @@ -1033,18 +1031,14 @@ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, } if (port->buf[0].data) { - pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", + pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, - &port->buf[0].phys, - port->buf[0].client, - port->buf[0].handle); + port->buf[0].dma_buf); if (!rc || atomic_read(&ac->reset)) - msm_audio_ion_free(port->buf[0].client, - port->buf[0].handle); - port->buf[0].client = NULL; - port->buf[0].handle = NULL; + msm_audio_ion_free(port->buf[0].dma_buf); + port->buf[0].dma_buf = NULL; } while (cnt >= 0) { @@ -1438,10 +1432,10 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, while (cnt < bufcnt) { if (bufsz > 0) { if (!buf[cnt].data) { - rc = msm_audio_ion_alloc("asm_client", - &buf[cnt].client, &buf[cnt].handle, + rc = msm_audio_ion_alloc( + &buf[cnt].dma_buf, bufsz, - (ion_phys_addr_t *)&buf[cnt].phys, + &buf[cnt].phys, &len, &buf[cnt].data); if (rc) { @@ -1544,9 +1538,9 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, /* The size to allocate should be multiple of 4K bytes */ bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); - rc = msm_audio_ion_alloc("asm_client", &buf[0].client, &buf[0].handle, + rc = msm_audio_ion_alloc(&buf[0].dma_buf, bytes_to_alloc, - (ion_phys_addr_t *)&buf[0].phys, &len, + &buf[0].phys, &len, &buf[0].data); if (rc) { pr_err("%s: Audio ION alloc is failed, rc = %d\n", @@ -3615,9 +3609,9 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, bytes_to_alloc = bufsz * bufcnt; bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); - rc = msm_audio_ion_alloc("audio_client", &buf_circ->client, - &buf_circ->handle, bytes_to_alloc, - (ion_phys_addr_t *)&buf_circ->phys, + rc = msm_audio_ion_alloc(&buf_circ->dma_buf, + bytes_to_alloc, + &buf_circ->phys, &len, &buf_circ->data); if (rc) { @@ -3669,9 +3663,9 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac, bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); - rc = msm_audio_ion_alloc("audio_client", &buf_pos->client, - &buf_pos->handle, bytes_to_alloc, - (ion_phys_addr_t *)&buf_pos->phys, &len, + rc = msm_audio_ion_alloc(&buf_pos->dma_buf, + bytes_to_alloc, + &buf_pos->phys, &len, &buf_pos->data); if (rc) { @@ -3900,18 +3894,15 @@ int q6asm_shared_io_free(struct audio_client *ac, int dir) port = &ac->port[dir]; mutex_lock(&ac->cmd_lock); if (port->buf && port->buf->data) { - msm_audio_ion_free(port->buf->client, port->buf->handle); - port->buf->client = NULL; - port->buf->handle = NULL; + msm_audio_ion_free(port->buf->dma_buf); + port->buf->dma_buf = NULL; port->max_buf_cnt = 0; kfree(port->buf); port->buf = NULL; } if (ac->shared_pos_buf.data) { - msm_audio_ion_free(ac->shared_pos_buf.client, - ac->shared_pos_buf.handle); - ac->shared_pos_buf.client = NULL; - ac->shared_pos_buf.handle = NULL; + msm_audio_ion_free(ac->shared_pos_buf.dma_buf); + ac->shared_pos_buf.dma_buf = NULL; } mutex_unlock(&ac->cmd_lock); return 0; @@ -7764,9 +7755,8 @@ EXPORT_SYMBOL(q6asm_set_aptx_dec_bt_addr); */ int q6asm_send_ion_fd(struct audio_client *ac, int fd) { - struct ion_client *client; - struct ion_handle *handle; - ion_phys_addr_t paddr; + struct dma_buf *dma_buf; + dma_addr_t paddr; size_t pa_len = 0; void *vaddr; int ret; @@ -7784,9 +7774,7 @@ int q6asm_send_ion_fd(struct audio_client *ac, int fd) goto fail_cmd; } - ret = msm_audio_ion_import("audio_mem_client", - &client, - &handle, + ret = msm_audio_ion_import(&dma_buf, fd, NULL, 0, diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 2a98dc719965..0dd6dbddce23 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1413,10 +1413,8 @@ int q6lsm_snd_model_buf_free(struct lsm_client *client) __func__, rc); if (client->sound_model.data) { - msm_audio_ion_free(client->sound_model.client, - client->sound_model.handle); - client->sound_model.client = NULL; - client->sound_model.handle = NULL; + msm_audio_ion_free(client->sound_model.dma_buf); + client->sound_model.dma_buf = NULL; client->sound_model.data = NULL; client->sound_model.phys = 0; client->lsm_cal_phy_addr = 0; @@ -1594,9 +1592,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, cal_block->cal_data.size); pr_debug("%s: Pad zeros sound model %zd Total mem %zd\n", __func__, pad_zero, total_mem); - rc = msm_audio_ion_alloc("lsm_client", - &client->sound_model.client, - &client->sound_model.handle, + rc = msm_audio_ion_alloc(&client->sound_model.dma_buf, total_mem, &client->sound_model.phys, &len, @@ -2138,9 +2134,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) client->hw_params.period_count); return -ENOMEM; } - ret = msm_audio_ion_alloc("lsm_lab", - &client->lab_buffer[0].client, - &client->lab_buffer[0].handle, + ret = msm_audio_ion_alloc(&client->lab_buffer[0].dma_buf, allocate_size, &client->lab_buffer[0].phys, &len, &client->lab_buffer[0].data); @@ -2155,8 +2149,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) pr_err("%s: memory map filed ret %d size %zd\n", __func__, ret, len); msm_audio_ion_free( - client->lab_buffer[0].client, - client->lab_buffer[0].handle); + client->lab_buffer[0].dma_buf); } } if (ret) { @@ -2187,9 +2180,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) ret = q6lsm_memory_unmap_regions(client, client->lab_buffer[0].mem_map_handle); if (!ret) - msm_audio_ion_free( - client->lab_buffer[0].client, - client->lab_buffer[0].handle); + msm_audio_ion_free(client->lab_buffer[0].dma_buf); else pr_err("%s: unmap failed not freeing memory\n", __func__); diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 1ed74a9c2b1d..3c335a841995 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -209,14 +209,13 @@ static int q6usm_us_client_buf_free(unsigned int dir, pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); - msm_audio_ion_free(port->client, port->handle); + msm_audio_ion_free(port->dma_buf); port->data = NULL; port->phys = 0; port->buf_size = 0; port->buf_cnt = 0; - port->client = NULL; - port->handle = NULL; + port->dma_buf = NULL; mutex_unlock(&usc->cmd_lock); return rc; @@ -250,13 +249,12 @@ int q6usm_us_param_buf_free(unsigned int dir, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); - msm_audio_ion_free(port->param_client, port->param_handle); + msm_audio_ion_free(port->param_dma_buf); port->param_buf = NULL; port->param_phys = 0; port->param_buf_size = 0; - port->param_client = NULL; - port->param_handle = NULL; + port->param_dma_buf = NULL; mutex_unlock(&usc->cmd_lock); return rc; @@ -398,8 +396,7 @@ int q6usm_us_client_buf_alloc(unsigned int dir, /* The size to allocate should be multiple of 4K bytes */ size = PAGE_ALIGN(size); - rc = msm_audio_ion_alloc("ultrasound_client", - &port->client, &port->handle, + rc = msm_audio_ion_alloc(&port->dma_buf, size, &port->phys, &len, &port->data); @@ -464,8 +461,7 @@ int q6usm_us_param_buf_alloc(unsigned int dir, /* The size to allocate should be multiple of 4K bytes */ size = PAGE_ALIGN(size); - rc = msm_audio_ion_alloc("ultrasound_client", - &port->param_client, &port->param_handle, + rc = msm_audio_ion_alloc(&port->param_dma_buf, size, &port->param_phys, &len, &port->param_buf); @@ -725,8 +721,7 @@ uint32_t q6usm_get_virtual_address(int dir, ab.used = 1; ab.size = size; ab.actual_size = size; - ab.handle = port->handle; - ab.client = port->client; + ab.dma_buf = port->dma_buf; ret = msm_audio_ion_mmap(&ab, vms); diff --git a/dsp/q6usm.h b/dsp/q6usm.h index fa2cd627c91d..ba4f9a9a84a7 100644 --- a/dsp/q6usm.h +++ b/dsp/q6usm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -63,10 +63,8 @@ struct us_port_data { /* read or write locks */ struct mutex lock; spinlock_t dsp_lock; - /* ION memory handle */ - struct ion_handle *handle; - /* ION memory client */ - struct ion_client *client; + /* ION dma_buf memory */ + struct dma_buf *dma_buf; /* extended parameters, related to q6 variants */ void *ext; /* physical address of parameter buffer */ @@ -77,10 +75,8 @@ struct us_port_data { uint32_t param_buf_size; /* parameter buffer memory handle */ void *param_buf_mem_handle; - /* ION memory handle for parameter buffer */ - struct ion_handle *param_handle; - /* ION memory client for parameter buffer */ - struct ion_client *param_client; + /* ION dma_buf memory for parameter buffer */ + struct dma_buf *param_dma_buf; }; struct us_client { diff --git a/dsp/q6voice.c b/dsp/q6voice.c index d5f280e3b0af..e26d156b57d3 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1944,8 +1944,7 @@ static int is_cal_memory_allocated(void) { bool ret; - if (common.cal_mem_map_table.client != NULL && - common.cal_mem_map_table.handle != NULL) + if (common.cal_mem_map_table.dma_buf != NULL) ret = true; else ret = false; @@ -1958,18 +1957,15 @@ static int free_cal_map_table(void) { int ret = 0; - if ((common.cal_mem_map_table.client == NULL) || - (common.cal_mem_map_table.handle == NULL)) + if (common.cal_mem_map_table.dma_buf == NULL) goto done; - ret = msm_audio_ion_free(common.cal_mem_map_table.client, - common.cal_mem_map_table.handle); + ret = msm_audio_ion_free(common.cal_mem_map_table.dma_buf); if (ret < 0) pr_err("%s: msm_audio_ion_free failed:\n", __func__); done: - common.cal_mem_map_table.client = NULL; - common.cal_mem_map_table.handle = NULL; + common.cal_mem_map_table.dma_buf = NULL; return ret; } @@ -1977,8 +1973,7 @@ static int is_rtac_memory_allocated(void) { bool ret; - if (common.rtac_mem_map_table.client != NULL && - common.rtac_mem_map_table.handle != NULL) + if (common.rtac_mem_map_table.dma_buf != NULL) ret = true; else ret = false; @@ -1990,18 +1985,15 @@ static int free_rtac_map_table(void) { int ret = 0; - if ((common.rtac_mem_map_table.client == NULL) || - (common.rtac_mem_map_table.handle == NULL)) + if (common.rtac_mem_map_table.dma_buf == NULL) goto done; - ret = msm_audio_ion_free(common.rtac_mem_map_table.client, - common.rtac_mem_map_table.handle); + ret = msm_audio_ion_free(common.rtac_mem_map_table.dma_buf); if (ret < 0) pr_err("%s: msm_audio_ion_free failed:\n", __func__); done: - common.rtac_mem_map_table.client = NULL; - common.rtac_mem_map_table.handle = NULL; + common.rtac_mem_map_table.dma_buf = NULL; return ret; } @@ -2021,8 +2013,7 @@ static int is_voip_memory_allocated(void) } mutex_lock(&common.common_lock); - if (v->shmem_info.sh_buf.client != NULL && - v->shmem_info.sh_buf.handle != NULL) + if (v->shmem_info.sh_buf.dma_buf != NULL) ret = true; else ret = false; @@ -3575,7 +3566,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, pr_debug("%s\n", __func__); - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for session_id %d!\n", __func__, session_id); ret = -EINVAL; @@ -7257,12 +7248,9 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) /* Free the ION memory and clear handles for Source Tracking */ if (is_source_tracking_shared_memomry_allocated()) { msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = - NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; } /* clean up srvcc rec flag */ @@ -7465,12 +7453,9 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) /* Free the ION memory and clear handles for Source Tracking */ if (is_source_tracking_shared_memomry_allocated()) { msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = - NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; } voc_set_error_state(data->reset_proc); @@ -7743,12 +7728,9 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) */ if (is_source_tracking_shared_memomry_allocated()) { msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = - NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; } voc_set_error_state(data->reset_proc); @@ -7958,10 +7940,8 @@ static int voice_free_oob_shared_mem(void) goto done; } - rc = msm_audio_ion_free(v->shmem_info.sh_buf.client, - v->shmem_info.sh_buf.handle); - v->shmem_info.sh_buf.client = NULL; - v->shmem_info.sh_buf.handle = NULL; + rc = msm_audio_ion_free(v->shmem_info.sh_buf.dma_buf); + v->shmem_info.sh_buf.dma_buf = NULL; if (rc < 0) { pr_err("%s: Error:%d freeing memory\n", __func__, rc); @@ -7975,8 +7955,7 @@ static int voice_free_oob_shared_mem(void) cnt++; } - v->shmem_info.sh_buf.client = NULL; - v->shmem_info.sh_buf.handle = NULL; + v->shmem_info.sh_buf.dma_buf = NULL; done: mutex_unlock(&common.common_lock); @@ -8003,9 +7982,8 @@ static int voice_alloc_oob_shared_mem(void) goto done; } - rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.sh_buf.client), - &(v->shmem_info.sh_buf.handle), - bufsz*bufcnt, + rc = msm_audio_ion_alloc(&(v->shmem_info.sh_buf.dma_buf), + bufsz * bufcnt, &phys, &len, &mem_addr); if (rc < 0) { @@ -8055,8 +8033,7 @@ static int voice_alloc_oob_mem_table(void) goto done; } - rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.memtbl.client), - &(v->shmem_info.memtbl.handle), + rc = msm_audio_ion_alloc(&(v->shmem_info.memtbl.dma_buf), sizeof(struct vss_imemory_table_t), &v->shmem_info.memtbl.phys, &len, @@ -8442,9 +8419,7 @@ static int voice_alloc_cal_mem_map_table(void) int ret = 0; size_t len; - ret = msm_audio_ion_alloc("voc_cal", - &(common.cal_mem_map_table.client), - &(common.cal_mem_map_table.handle), + ret = msm_audio_ion_alloc(&(common.cal_mem_map_table.dma_buf), sizeof(struct vss_imemory_table_t), &common.cal_mem_map_table.phys, &len, @@ -8469,9 +8444,8 @@ static int voice_alloc_rtac_mem_map_table(void) int ret = 0; size_t len; - ret = msm_audio_ion_alloc("voc_rtac_cal", - &(common.rtac_mem_map_table.client), - &(common.rtac_mem_map_table.handle), + ret = msm_audio_ion_alloc( + &(common.rtac_mem_map_table.dma_buf), sizeof(struct vss_imemory_table_t), &common.rtac_mem_map_table.phys, &len, @@ -9181,8 +9155,7 @@ static int is_source_tracking_shared_memomry_allocated(void) pr_debug("%s: Enter\n", __func__); - if (common.source_tracking_sh_mem.sh_mem_block.client != NULL && - common.source_tracking_sh_mem.sh_mem_block.handle != NULL) + if (common.source_tracking_sh_mem.sh_mem_block.dma_buf != NULL) ret = true; else ret = false; @@ -9198,9 +9171,8 @@ static int voice_alloc_source_tracking_shared_memory(void) pr_debug("%s: Enter\n", __func__); - ret = msm_audio_ion_alloc("source_tracking_sh_mem_block", - &(common.source_tracking_sh_mem.sh_mem_block.client), - &(common.source_tracking_sh_mem.sh_mem_block.handle), + ret = msm_audio_ion_alloc( + &(common.source_tracking_sh_mem.sh_mem_block.dma_buf), BUFFER_BLOCK_SIZE, &(common.source_tracking_sh_mem.sh_mem_block.phys), (size_t *)&(common.source_tracking_sh_mem.sh_mem_block.size), @@ -9221,9 +9193,8 @@ static int voice_alloc_source_tracking_shared_memory(void) (void *)(common.source_tracking_sh_mem.sh_mem_block.data), (size_t)(common.source_tracking_sh_mem.sh_mem_block.size)); - ret = msm_audio_ion_alloc("source_tracking_sh_mem_table", - &(common.source_tracking_sh_mem.sh_mem_table.client), - &(common.source_tracking_sh_mem.sh_mem_table.handle), + ret = msm_audio_ion_alloc( + &(common.source_tracking_sh_mem.sh_mem_table.dma_buf), sizeof(struct vss_imemory_table_t), &(common.source_tracking_sh_mem.sh_mem_table.phys), (size_t *)&(common.source_tracking_sh_mem.sh_mem_table.size), @@ -9233,10 +9204,8 @@ static int voice_alloc_source_tracking_shared_memory(void) __func__, ret); ret = msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); - common.source_tracking_sh_mem.sh_mem_block.client = NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = NULL; + common.source_tracking_sh_mem.sh_mem_block.dma_buf); + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; if (ret < 0) pr_err("%s: Error:%d freeing memory\n", __func__, ret); @@ -9312,13 +9281,11 @@ static int voice_unmap_and_free_source_tracking_shared_memory( } } - if ((common.source_tracking_sh_mem.sh_mem_block.client == NULL) || - (common.source_tracking_sh_mem.sh_mem_block.handle == NULL)) + if (common.source_tracking_sh_mem.sh_mem_block.dma_buf == NULL) goto done; ret = msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); if (ret < 0) { pr_err("%s: Error:%d freeing memory\n", __func__, ret); @@ -9328,8 +9295,7 @@ static int voice_unmap_and_free_source_tracking_shared_memory( done: common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = NULL; + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; pr_debug("%s: Exit, ret=%d\n", __func__, ret); return ret; diff --git a/dsp/rtac.c b/dsp/rtac.c index 43c69ccab394..0785f5621f69 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,13 +41,13 @@ struct rtac_cal_block_data rtac_cal[MAX_RTAC_BLOCKS] = { /* ADM_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }, /* ASM_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }, /* VOICE_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }, /* AFE_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} } + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} } }; struct rtac_common_data { @@ -164,9 +164,7 @@ int rtac_allocate_cal_buffer(uint32_t cal_type) goto done; } - result = msm_audio_ion_alloc("rtac_client", - &rtac_cal[cal_type].map_data.ion_client, - &rtac_cal[cal_type].map_data.ion_handle, + result = msm_audio_ion_alloc(&rtac_cal[cal_type].map_data.dma_buf, rtac_cal[cal_type].map_data.map_size, &rtac_cal[cal_type].cal_data.paddr, &len, @@ -199,14 +197,13 @@ int rtac_free_cal_buffer(uint32_t cal_type) goto done; } - if (rtac_cal[cal_type].map_data.ion_client == NULL) { + if (rtac_cal[cal_type].map_data.dma_buf == NULL) { pr_debug("%s: cal_type %d not allocated!\n", __func__, cal_type); goto done; } - result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client, - rtac_cal[cal_type].map_data.ion_handle); + result = msm_audio_ion_free(rtac_cal[cal_type].map_data.dma_buf); if (result < 0) { pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); @@ -214,8 +211,7 @@ int rtac_free_cal_buffer(uint32_t cal_type) } rtac_cal[cal_type].map_data.map_handle = 0; - rtac_cal[cal_type].map_data.ion_client = NULL; - rtac_cal[cal_type].map_data.ion_handle = NULL; + rtac_cal[cal_type].map_data.dma_buf = NULL; rtac_cal[cal_type].cal_data.size = 0; rtac_cal[cal_type].cal_data.kvaddr = 0; rtac_cal[cal_type].cal_data.paddr = 0; @@ -754,7 +750,7 @@ int send_adm_apr(void *buf, u32 opcode) pr_debug("%s\n", __func__); - if (rtac_cal[ADM_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[ADM_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(ADM_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", @@ -983,7 +979,7 @@ int send_rtac_asm_apr(void *buf, u32 opcode) pr_debug("%s\n", __func__); - if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[ASM_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(ASM_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", @@ -1232,7 +1228,7 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) pr_debug("%s\n", __func__); - if (rtac_cal[AFE_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[AFE_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(AFE_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed! ret = %d\n", @@ -1482,7 +1478,7 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) pr_debug("%s\n", __func__); - if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[VOICE_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index e12d8c1a9890..a4aa4e45d200 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,8 +28,7 @@ struct mem_map_data { size_t map_size; int32_t q6map_handle; int32_t ion_map_handle; - struct ion_client *ion_client; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; }; struct cal_block_data { diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index 8a2fb6e34b99..a4cd3867774b 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,28 +18,14 @@ #include <linux/msm_ion.h> -int msm_audio_ion_alloc(const char *name, struct ion_client **client, - struct ion_handle **handle, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, + dma_addr_t *paddr, size_t *pa_len, void **vaddr); -int msm_audio_ion_import(const char *name, struct ion_client **client, - struct ion_handle **handle, int fd, +int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); -int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle); -int msm_audio_ion_mmap(struct audio_buffer *substream, - struct vm_area_struct *vma); + dma_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free(struct dma_buf *dma_buf); +int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma); -bool msm_audio_ion_is_smmu_available(void); -int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); - -struct ion_client *msm_audio_ion_client_create(const char *name); -void msm_audio_ion_client_destroy(struct ion_client *client); -int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, - struct ion_handle **handle, int fd, - unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); -int msm_audio_ion_free_legacy(struct ion_client *client, - struct ion_handle *handle); -u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa); +u32 msm_audio_populate_upper_32_bits(dma_addr_t pa); #endif /* _LINUX_MSM_AUDIO_ION_H */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 6fb9c442ec30..ade124952236 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -246,8 +246,7 @@ struct afe_audio_buffer { uint32_t used; uint32_t size;/* size of buffer */ uint32_t actual_size; /* actual number of bytes read by DSP */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; }; struct afe_audio_port_data { diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 157c243185b6..27b360f376c5 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -165,8 +165,7 @@ struct audio_buffer { uint32_t used; uint32_t size;/* size of buffer */ uint32_t actual_size; /* actual number of bytes read by DSP */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; }; struct audio_aio_write_param { diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index efce3a6d2076..9050a7ca86c6 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,8 +33,7 @@ struct lsm_sound_model { void *data; size_t size; /* size of buffer */ uint32_t actual_size; /* actual number of bytes read by DSP */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; uint32_t mem_map_handle; }; @@ -48,8 +47,7 @@ struct lsm_lab_buffer { dma_addr_t phys; void *data; size_t size; - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; uint32_t mem_map_handle; }; diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index a41a2db8f868..5dfdccf84420 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -156,8 +156,7 @@ struct mem_buffer { }; struct share_mem_buf { - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; struct mem_buffer buf[NUM_OF_BUFFERS]; }; @@ -165,8 +164,7 @@ struct mem_map_table { dma_addr_t phys; void *data; size_t size; /* size of buffer */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; }; /* Common */ @@ -1874,12 +1872,6 @@ struct voice_data { struct voice_rec_route_state rec_route_state; }; -struct cal_mem { - struct ion_handle *handle; - uint32_t phy; - void *buf; -}; - #define MAX_VOC_SESSIONS 8 struct common_data { @@ -1909,9 +1901,6 @@ struct common_data { uint32_t voice_host_pcm_mem_handle; - struct cal_mem cvp_cal; - struct cal_mem cvs_cal; - struct mutex common_lock; struct mvs_driver_info mvs_info; diff --git a/include/dsp/rtac.h b/include/dsp/rtac.h index f8c5556c5455..05dd82a7fcab 100644 --- a/include/dsp/rtac.h +++ b/include/dsp/rtac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013-2015, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,8 +38,7 @@ enum { struct rtac_cal_mem_map_data { uint32_t map_size; uint32_t map_handle; - struct ion_client *ion_client; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; }; struct rtac_cal_data {