Loading drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c +297 −41 Original line number Diff line number Diff line Loading @@ -20,22 +20,251 @@ #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/msm_audio_ion.h> #include <linux/habmm.h> #include "../../../staging/android/ion/ion_priv.h" #include "../../../staging/android/ion/ion_hvenv_driver.h" #define MSM_AUDIO_ION_PROBED (1 << 0) #define MSM_AUDIO_SMMU_VM_CMD_MAP 0x00000001 #define MSM_AUDIO_SMMU_VM_CMD_UNMAP 0x00000002 #define MSM_AUDIO_SMMU_VM_HAB_MINOR_ID 1 struct msm_audio_ion_private { bool smmu_enabled; bool audioheap_enabled; u8 device_status; struct list_head smmu_map_list; struct mutex smmu_map_mutex; }; struct msm_audio_smmu_map_data { struct ion_client *client; struct ion_handle *handle; u32 export_id; struct list_head list; }; struct msm_audio_smmu_vm_map_cmd { int cmd_id; u32 export_id; u32 buf_size; }; struct msm_audio_smmu_vm_map_cmd_rsp { int status; u64 addr; }; struct msm_audio_smmu_vm_unmap_cmd { int cmd_id; u32 export_id; }; struct msm_audio_smmu_vm_unmap_cmd_rsp { int status; }; static struct msm_audio_ion_private msm_audio_ion_data = {0,}; static u32 msm_audio_ion_hab_handle; static int msm_audio_ion_get_phys(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len); ion_phys_addr_t *addr, size_t *len, void *vaddr); static int msm_audio_ion_smmu_map(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len, void *vaddr) { int rc; u32 export_id; u32 cmd_rsp_size; bool exported = false; struct msm_audio_smmu_vm_map_cmd_rsp cmd_rsp; struct msm_audio_smmu_map_data *map_data = NULL; struct msm_audio_smmu_vm_map_cmd smmu_map_cmd; rc = ion_handle_get_size(client, handle, len); if (rc) { pr_err("%s: ion_handle_get_size failed, client = %pK, handle = %pK, rc = %d\n", __func__, client, handle, rc); goto err; } /* Data required to track per buffer mapping */ map_data = kzalloc(sizeof(*map_data), GFP_KERNEL); if (!map_data) { rc = -ENOMEM; goto err; } /* Export the buffer to physical VM */ rc = habmm_export(msm_audio_ion_hab_handle, vaddr, *len, &export_id, 0); if (rc) { pr_err("%s: habmm_export failed vaddr = %pK, len = %zd, rc = %d\n", __func__, vaddr, *len, rc); goto err; } exported = true; smmu_map_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_MAP; smmu_map_cmd.export_id = export_id; smmu_map_cmd.buf_size = *len; mutex_lock(&(msm_audio_ion_data.smmu_map_mutex)); rc = habmm_socket_send(msm_audio_ion_hab_handle, (void *)&smmu_map_cmd, sizeof(smmu_map_cmd), 0); if (rc) { pr_err("%s: habmm_socket_send failed %d\n", __func__, rc); mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); goto err; } cmd_rsp_size = sizeof(cmd_rsp); rc = habmm_socket_recv(msm_audio_ion_hab_handle, (void *)&cmd_rsp, &cmd_rsp_size, 0xFFFFFFFF, 0); if (rc) { pr_err("%s: habmm_socket_recv failed %d\n", __func__, rc); mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); goto err; } mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); if (cmd_rsp_size != sizeof(cmd_rsp)) { pr_err("%s: invalid size for cmd rsp %lu, expected %lu\n", __func__, cmd_rsp_size, sizeof(cmd_rsp)); rc = -EIO; goto err; } if (cmd_rsp.status) { pr_err("%s: SMMU map command failed %d\n", __func__, cmd_rsp.status); rc = cmd_rsp.status; goto err; } *addr = (ion_phys_addr_t)cmd_rsp.addr; map_data->client = client; map_data->handle = handle; map_data->export_id = export_id; mutex_lock(&(msm_audio_ion_data.smmu_map_mutex)); list_add_tail(&(map_data->list), &(msm_audio_ion_data.smmu_map_list)); mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); return 0; err: if (exported) (void)habmm_unexport(msm_audio_ion_hab_handle, export_id, 0); kfree(map_data); return rc; } static int msm_audio_ion_smmu_unmap(struct ion_client *client, struct ion_handle *handle) { int rc; bool found = false; u32 cmd_rsp_size; struct msm_audio_smmu_vm_unmap_cmd_rsp cmd_rsp; struct msm_audio_smmu_map_data *map_data, *next; struct msm_audio_smmu_vm_unmap_cmd smmu_unmap_cmd; /* * Though list_for_each_entry_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.smmu_map_mutex)); list_for_each_entry_safe(map_data, next, &(msm_audio_ion_data.smmu_map_list), list) { if (map_data->handle == handle && map_data->client == client) { found = true; smmu_unmap_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_UNMAP; smmu_unmap_cmd.export_id = map_data->export_id; rc = habmm_socket_send(msm_audio_ion_hab_handle, (void *)&smmu_unmap_cmd, sizeof(smmu_unmap_cmd), 0); if (rc) { pr_err("%s: habmm_socket_send failed %d\n", __func__, rc); goto err; } cmd_rsp_size = sizeof(cmd_rsp); rc = habmm_socket_recv(msm_audio_ion_hab_handle, (void *)&cmd_rsp, &cmd_rsp_size, 0xFFFFFFFF, 0); if (rc) { pr_err("%s: habmm_socket_recv failed %d\n", __func__, rc); goto err; } if (cmd_rsp_size != sizeof(cmd_rsp)) { pr_err("%s: invalid size for cmd rsp %lu\n", __func__, cmd_rsp_size); rc = -EIO; goto err; } if (cmd_rsp.status) { pr_err("%s: SMMU unmap command failed %d\n", __func__, cmd_rsp.status); rc = cmd_rsp.status; goto err; } rc = habmm_unexport(msm_audio_ion_hab_handle, map_data->export_id, 0xFFFFFFFF); if (rc) { pr_err("%s: habmm_unexport failed export_id = %d, rc = %d\n", __func__, map_data->export_id, rc); } list_del(&(map_data->list)); kfree(map_data); break; } } mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); if (!found) { pr_err("%s: cannot find map_data ion_handle %pK, ion_client %pK\n", __func__, handle, client); rc = -EINVAL; } return rc; err: if (found) { (void)habmm_unexport(msm_audio_ion_hab_handle, map_data->export_id, 0xFFFFFFFF); list_del(&(map_data->list)); kfree(map_data); } mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); return rc; } int msm_audio_ion_alloc(const char *name, struct ion_client **client, struct ion_handle **handle, size_t bufsz, Loading Loading @@ -82,13 +311,6 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client, msm_audio_ion_data.audioheap_enabled = 1; } 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); 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__); Loading @@ -102,8 +324,17 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client, memset((void *)*vaddr, 0, bufsz); } rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len, *vaddr); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err_get_phys; } return rc; err_get_phys: ion_unmap_kernel(*client, *handle); err_ion_handle: ion_free(*client, *handle); err_ion_client: Loading Loading @@ -239,13 +470,6 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, } } 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); 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__); Loading @@ -255,8 +479,17 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len, *vaddr); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err_get_phys; } return 0; err_get_phys: ion_unmap_kernel(*client, *handle); err_ion_handle: ion_free(*client, *handle); err_destroy_client: Loading @@ -269,16 +502,25 @@ err: int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) { int ret = 0; if (!client || !handle) { pr_err("%s Invalid params\n", __func__); return -EINVAL; } if (msm_audio_ion_data.smmu_enabled) { ret = msm_audio_ion_smmu_unmap(client, handle); if (ret) pr_err("%s: smmu unmap failed with ret %d\n", __func__, ret); } ion_unmap_kernel(client, handle); ion_free(client, handle); msm_audio_ion_client_destroy(client); return 0; return ret; } EXPORT_SYMBOL(msm_audio_ion_free); Loading Loading @@ -435,14 +677,6 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, } } 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)) { Loading @@ -454,8 +688,17 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, if (bufsz != 0) memset((void *)*vaddr, 0, bufsz); rc = msm_audio_ion_get_phys(client, *handle, paddr, pa_len, *vaddr); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err_get_phys; } return 0; err_get_phys: ion_unmap_kernel(client, *handle); err_ion_handle: ion_free(client, *handle); err: Loading @@ -474,7 +717,7 @@ int msm_audio_ion_free_legacy(struct ion_client *client, static int msm_audio_ion_get_phys(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len) ion_phys_addr_t *addr, size_t *len, void *vaddr) { int rc = 0; Loading @@ -482,14 +725,12 @@ static int msm_audio_ion_get_phys(struct ion_client *client, msm_audio_ion_data.smmu_enabled); if (msm_audio_ion_data.smmu_enabled) { rc = ion_phys(client, handle, addr, len); rc = msm_audio_ion_smmu_map(client, handle, addr, len, vaddr); if (rc) { pr_err("%s: ion_phys failed, err = %d\n", pr_err("%s: failed to do smmu map, err = %d\n", __func__, rc); goto err; } /* Append the SMMU SID information to the IOVA address */ *addr |= (1 << 32); } else { rc = ion_phys(client, handle, addr, len); } Loading @@ -506,19 +747,8 @@ 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 1; else return 0; } 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); } Loading @@ -543,6 +773,25 @@ static int msm_audio_ion_probe(struct platform_device *pdev) pr_info("%s: SMMU is %s\n", __func__, (smmu_enabled) ? "Enabled" : "Disabled"); if (smmu_enabled) { rc = habmm_socket_open(&msm_audio_ion_hab_handle, HAB_MMID_CREATE(MM_AUD_3, MSM_AUDIO_SMMU_VM_HAB_MINOR_ID), 0xFFFFFFFF, HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE); if (rc) { pr_err("%s: habmm_socket_open failed %d\n", __func__, rc); return rc; } pr_info("%s: msm_audio_ion_hab_handle %x\n", __func__, msm_audio_ion_hab_handle); INIT_LIST_HEAD(&msm_audio_ion_data.smmu_map_list); mutex_init(&(msm_audio_ion_data.smmu_map_mutex)); } if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; Loading @@ -551,8 +800,15 @@ static int msm_audio_ion_probe(struct platform_device *pdev) static int msm_audio_ion_remove(struct platform_device *pdev) { if (msm_audio_ion_data.smmu_enabled) { if (msm_audio_ion_hab_handle) habmm_socket_close(msm_audio_ion_hab_handle); mutex_destroy(&(msm_audio_ion_data.smmu_map_mutex)); } msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; return 0; } Loading Loading
drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c +297 −41 Original line number Diff line number Diff line Loading @@ -20,22 +20,251 @@ #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/msm_audio_ion.h> #include <linux/habmm.h> #include "../../../staging/android/ion/ion_priv.h" #include "../../../staging/android/ion/ion_hvenv_driver.h" #define MSM_AUDIO_ION_PROBED (1 << 0) #define MSM_AUDIO_SMMU_VM_CMD_MAP 0x00000001 #define MSM_AUDIO_SMMU_VM_CMD_UNMAP 0x00000002 #define MSM_AUDIO_SMMU_VM_HAB_MINOR_ID 1 struct msm_audio_ion_private { bool smmu_enabled; bool audioheap_enabled; u8 device_status; struct list_head smmu_map_list; struct mutex smmu_map_mutex; }; struct msm_audio_smmu_map_data { struct ion_client *client; struct ion_handle *handle; u32 export_id; struct list_head list; }; struct msm_audio_smmu_vm_map_cmd { int cmd_id; u32 export_id; u32 buf_size; }; struct msm_audio_smmu_vm_map_cmd_rsp { int status; u64 addr; }; struct msm_audio_smmu_vm_unmap_cmd { int cmd_id; u32 export_id; }; struct msm_audio_smmu_vm_unmap_cmd_rsp { int status; }; static struct msm_audio_ion_private msm_audio_ion_data = {0,}; static u32 msm_audio_ion_hab_handle; static int msm_audio_ion_get_phys(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len); ion_phys_addr_t *addr, size_t *len, void *vaddr); static int msm_audio_ion_smmu_map(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len, void *vaddr) { int rc; u32 export_id; u32 cmd_rsp_size; bool exported = false; struct msm_audio_smmu_vm_map_cmd_rsp cmd_rsp; struct msm_audio_smmu_map_data *map_data = NULL; struct msm_audio_smmu_vm_map_cmd smmu_map_cmd; rc = ion_handle_get_size(client, handle, len); if (rc) { pr_err("%s: ion_handle_get_size failed, client = %pK, handle = %pK, rc = %d\n", __func__, client, handle, rc); goto err; } /* Data required to track per buffer mapping */ map_data = kzalloc(sizeof(*map_data), GFP_KERNEL); if (!map_data) { rc = -ENOMEM; goto err; } /* Export the buffer to physical VM */ rc = habmm_export(msm_audio_ion_hab_handle, vaddr, *len, &export_id, 0); if (rc) { pr_err("%s: habmm_export failed vaddr = %pK, len = %zd, rc = %d\n", __func__, vaddr, *len, rc); goto err; } exported = true; smmu_map_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_MAP; smmu_map_cmd.export_id = export_id; smmu_map_cmd.buf_size = *len; mutex_lock(&(msm_audio_ion_data.smmu_map_mutex)); rc = habmm_socket_send(msm_audio_ion_hab_handle, (void *)&smmu_map_cmd, sizeof(smmu_map_cmd), 0); if (rc) { pr_err("%s: habmm_socket_send failed %d\n", __func__, rc); mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); goto err; } cmd_rsp_size = sizeof(cmd_rsp); rc = habmm_socket_recv(msm_audio_ion_hab_handle, (void *)&cmd_rsp, &cmd_rsp_size, 0xFFFFFFFF, 0); if (rc) { pr_err("%s: habmm_socket_recv failed %d\n", __func__, rc); mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); goto err; } mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); if (cmd_rsp_size != sizeof(cmd_rsp)) { pr_err("%s: invalid size for cmd rsp %lu, expected %lu\n", __func__, cmd_rsp_size, sizeof(cmd_rsp)); rc = -EIO; goto err; } if (cmd_rsp.status) { pr_err("%s: SMMU map command failed %d\n", __func__, cmd_rsp.status); rc = cmd_rsp.status; goto err; } *addr = (ion_phys_addr_t)cmd_rsp.addr; map_data->client = client; map_data->handle = handle; map_data->export_id = export_id; mutex_lock(&(msm_audio_ion_data.smmu_map_mutex)); list_add_tail(&(map_data->list), &(msm_audio_ion_data.smmu_map_list)); mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); return 0; err: if (exported) (void)habmm_unexport(msm_audio_ion_hab_handle, export_id, 0); kfree(map_data); return rc; } static int msm_audio_ion_smmu_unmap(struct ion_client *client, struct ion_handle *handle) { int rc; bool found = false; u32 cmd_rsp_size; struct msm_audio_smmu_vm_unmap_cmd_rsp cmd_rsp; struct msm_audio_smmu_map_data *map_data, *next; struct msm_audio_smmu_vm_unmap_cmd smmu_unmap_cmd; /* * Though list_for_each_entry_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.smmu_map_mutex)); list_for_each_entry_safe(map_data, next, &(msm_audio_ion_data.smmu_map_list), list) { if (map_data->handle == handle && map_data->client == client) { found = true; smmu_unmap_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_UNMAP; smmu_unmap_cmd.export_id = map_data->export_id; rc = habmm_socket_send(msm_audio_ion_hab_handle, (void *)&smmu_unmap_cmd, sizeof(smmu_unmap_cmd), 0); if (rc) { pr_err("%s: habmm_socket_send failed %d\n", __func__, rc); goto err; } cmd_rsp_size = sizeof(cmd_rsp); rc = habmm_socket_recv(msm_audio_ion_hab_handle, (void *)&cmd_rsp, &cmd_rsp_size, 0xFFFFFFFF, 0); if (rc) { pr_err("%s: habmm_socket_recv failed %d\n", __func__, rc); goto err; } if (cmd_rsp_size != sizeof(cmd_rsp)) { pr_err("%s: invalid size for cmd rsp %lu\n", __func__, cmd_rsp_size); rc = -EIO; goto err; } if (cmd_rsp.status) { pr_err("%s: SMMU unmap command failed %d\n", __func__, cmd_rsp.status); rc = cmd_rsp.status; goto err; } rc = habmm_unexport(msm_audio_ion_hab_handle, map_data->export_id, 0xFFFFFFFF); if (rc) { pr_err("%s: habmm_unexport failed export_id = %d, rc = %d\n", __func__, map_data->export_id, rc); } list_del(&(map_data->list)); kfree(map_data); break; } } mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); if (!found) { pr_err("%s: cannot find map_data ion_handle %pK, ion_client %pK\n", __func__, handle, client); rc = -EINVAL; } return rc; err: if (found) { (void)habmm_unexport(msm_audio_ion_hab_handle, map_data->export_id, 0xFFFFFFFF); list_del(&(map_data->list)); kfree(map_data); } mutex_unlock(&(msm_audio_ion_data.smmu_map_mutex)); return rc; } int msm_audio_ion_alloc(const char *name, struct ion_client **client, struct ion_handle **handle, size_t bufsz, Loading Loading @@ -82,13 +311,6 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client, msm_audio_ion_data.audioheap_enabled = 1; } 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); 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__); Loading @@ -102,8 +324,17 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client, memset((void *)*vaddr, 0, bufsz); } rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len, *vaddr); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err_get_phys; } return rc; err_get_phys: ion_unmap_kernel(*client, *handle); err_ion_handle: ion_free(*client, *handle); err_ion_client: Loading Loading @@ -239,13 +470,6 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, } } 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); 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__); Loading @@ -255,8 +479,17 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len, *vaddr); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err_get_phys; } return 0; err_get_phys: ion_unmap_kernel(*client, *handle); err_ion_handle: ion_free(*client, *handle); err_destroy_client: Loading @@ -269,16 +502,25 @@ err: int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) { int ret = 0; if (!client || !handle) { pr_err("%s Invalid params\n", __func__); return -EINVAL; } if (msm_audio_ion_data.smmu_enabled) { ret = msm_audio_ion_smmu_unmap(client, handle); if (ret) pr_err("%s: smmu unmap failed with ret %d\n", __func__, ret); } ion_unmap_kernel(client, handle); ion_free(client, handle); msm_audio_ion_client_destroy(client); return 0; return ret; } EXPORT_SYMBOL(msm_audio_ion_free); Loading Loading @@ -435,14 +677,6 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, } } 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)) { Loading @@ -454,8 +688,17 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, if (bufsz != 0) memset((void *)*vaddr, 0, bufsz); rc = msm_audio_ion_get_phys(client, *handle, paddr, pa_len, *vaddr); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err_get_phys; } return 0; err_get_phys: ion_unmap_kernel(client, *handle); err_ion_handle: ion_free(client, *handle); err: Loading @@ -474,7 +717,7 @@ int msm_audio_ion_free_legacy(struct ion_client *client, static int msm_audio_ion_get_phys(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len) ion_phys_addr_t *addr, size_t *len, void *vaddr) { int rc = 0; Loading @@ -482,14 +725,12 @@ static int msm_audio_ion_get_phys(struct ion_client *client, msm_audio_ion_data.smmu_enabled); if (msm_audio_ion_data.smmu_enabled) { rc = ion_phys(client, handle, addr, len); rc = msm_audio_ion_smmu_map(client, handle, addr, len, vaddr); if (rc) { pr_err("%s: ion_phys failed, err = %d\n", pr_err("%s: failed to do smmu map, err = %d\n", __func__, rc); goto err; } /* Append the SMMU SID information to the IOVA address */ *addr |= (1 << 32); } else { rc = ion_phys(client, handle, addr, len); } Loading @@ -506,19 +747,8 @@ 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 1; else return 0; } 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); } Loading @@ -543,6 +773,25 @@ static int msm_audio_ion_probe(struct platform_device *pdev) pr_info("%s: SMMU is %s\n", __func__, (smmu_enabled) ? "Enabled" : "Disabled"); if (smmu_enabled) { rc = habmm_socket_open(&msm_audio_ion_hab_handle, HAB_MMID_CREATE(MM_AUD_3, MSM_AUDIO_SMMU_VM_HAB_MINOR_ID), 0xFFFFFFFF, HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE); if (rc) { pr_err("%s: habmm_socket_open failed %d\n", __func__, rc); return rc; } pr_info("%s: msm_audio_ion_hab_handle %x\n", __func__, msm_audio_ion_hab_handle); INIT_LIST_HEAD(&msm_audio_ion_data.smmu_map_list); mutex_init(&(msm_audio_ion_data.smmu_map_mutex)); } if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; Loading @@ -551,8 +800,15 @@ static int msm_audio_ion_probe(struct platform_device *pdev) static int msm_audio_ion_remove(struct platform_device *pdev) { if (msm_audio_ion_data.smmu_enabled) { if (msm_audio_ion_hab_handle) habmm_socket_close(msm_audio_ion_hab_handle); mutex_destroy(&(msm_audio_ion_data.smmu_map_mutex)); } msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; return 0; } Loading