From 91b6878c2c2bb795268d9d96391c58f4ce8013ec Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 11 Sep 2025 00:25:01 +0300 Subject: [PATCH] dsp, ipc, include: drop unused sources The source files in dsp/, ipc/ and include/ subdirs are not used for module building. Drop them to reduce possible confusion. Signed-off-by: Dmitry Baryshkov --- dsp/msm_audio_mem.c | 853 ------------------------------------ dsp/spf-core.c | 285 ------------ include/dsp/msm_audio_mem.h | 14 - ipc/audio-pkt.c | 519 ---------------------- 4 files changed, 1671 deletions(-) delete mode 100644 dsp/msm_audio_mem.c delete mode 100644 dsp/spf-core.c delete mode 100644 include/dsp/msm_audio_mem.h delete mode 100644 ipc/audio-pkt.c diff --git a/dsp/msm_audio_mem.c b/dsp/msm_audio_mem.c deleted file mode 100644 index 123e55c..0000000 --- a/dsp/msm_audio_mem.c +++ /dev/null @@ -1,853 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_IMPORT_NS(DMA_BUF); - -#define MSM_AUDIO_MEM_PROBED (1 << 0) - -#define MSM_AUDIO_MEM_PHYS_ADDR(alloc_data) \ - alloc_data->table->sgl->dma_address - -#define MSM_AUDIO_SMMU_SID_OFFSET 32 -#define MSM_AUDIO_MEM_DRIVER_NAME "msm_audio_mem" -#define MINOR_NUMBER_COUNT 1 -struct msm_audio_mem_private { - bool smmu_enabled; - struct device *cb_dev; - u8 device_status; - struct list_head alloc_list; - struct mutex list_mutex; - u64 smmu_sid_bits; - char *driver_name; - /*char dev related data */ - dev_t mem_major; - struct class *mem_class; - struct device *chardev; - struct cdev cdev; -}; - -struct msm_audio_alloc_data { - size_t len; - struct iosys_map *vmap; - struct dma_buf *dma_buf; - struct dma_buf_attachment *attach; - struct sg_table *table; - struct list_head list; -}; - -struct msm_audio_mem_fd_list_private { - struct mutex list_mutex; - /*list to store fd, phy. addr and handle data */ - struct list_head fd_list; -}; - -static struct msm_audio_mem_fd_list_private msm_audio_mem_fd_list = {0,}; -static bool msm_audio_mem_fd_list_init = false; - -struct msm_audio_fd_data { - int fd; - size_t plen; - void *handle; - dma_addr_t paddr; - struct device *dev; - struct list_head list; - bool hyp_assign; -}; - -static void msm_audio_mem_add_allocation( - struct msm_audio_mem_private *msm_audio_mem_data, - struct msm_audio_alloc_data *alloc_data) -{ - /* - * Since these APIs can be invoked by multiple - * clients, there is need to make sure the list - * of allocations is always protected - */ - mutex_lock(&(msm_audio_mem_data->list_mutex)); - list_add_tail(&(alloc_data->list), - &(msm_audio_mem_data->alloc_list)); - mutex_unlock(&(msm_audio_mem_data->list_mutex)); -} - -static int msm_audio_mem_map_kernel(struct dma_buf *dma_buf, - struct msm_audio_mem_private *mem_data, struct iosys_map *iosys_vmap) -{ - int rc = 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; - } - - rc = dma_buf_vmap(dma_buf, iosys_vmap); - if (rc) { - pr_err("%s: kernel mapping of dma_buf failed\n", - __func__); - goto exit; - } - - /* - * TBD: remove the below section once new API - * for mapping kernel virtual address is available. - */ - mutex_lock(&(mem_data->list_mutex)); - list_for_each_entry(alloc_data, &(mem_data->alloc_list), - list) { - if (alloc_data->dma_buf == dma_buf) { - alloc_data->vmap = iosys_vmap; - break; - } - } - mutex_unlock(&(mem_data->list_mutex)); - -exit: - return rc; -} - -static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, - dma_addr_t *addr, size_t *len, bool is_iova, - struct msm_audio_mem_private *mem_data) -{ - - struct msm_audio_alloc_data *alloc_data = NULL; - int rc = 0; - struct iosys_map *iosys_vmap = NULL; - struct device *cb_dev = mem_data->cb_dev; - - iosys_vmap = kzalloc(sizeof(*iosys_vmap), GFP_KERNEL); - if (!iosys_vmap) - return -ENOMEM; - /* Data required per buffer mapping */ - alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); - if (!alloc_data) { - kfree(iosys_vmap); - 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 free_alloc_data; - } - - /* - * 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 detach_dma_buf; - } - - /* physical address from mapping */ - if (!is_iova) { - *addr = sg_phys(alloc_data->table->sgl); - rc = msm_audio_mem_map_kernel((void *)dma_buf, mem_data, iosys_vmap); - if (rc) { - pr_err("%s: MEM memory mapping for AUDIO failed, err:%d\n", - __func__, rc); - rc = -ENOMEM; - goto detach_dma_buf; - } - alloc_data->vmap = iosys_vmap; - } else { - *addr = MSM_AUDIO_MEM_PHYS_ADDR(alloc_data); - } - - msm_audio_mem_add_allocation(mem_data, alloc_data); - return rc; - -detach_dma_buf: - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); -free_alloc_data: - kfree(iosys_vmap); - kfree(alloc_data); - alloc_data = NULL; - - return rc; -} - -static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, struct msm_audio_mem_private *mem_data) -{ - int rc = 0; - struct msm_audio_alloc_data *alloc_data = NULL; - struct list_head *ptr, *next; - bool found = false; - struct device *cb_dev = mem_data->cb_dev; - - /* - * 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(&(mem_data->list_mutex)); - list_for_each_safe(ptr, next, - &(mem_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->vmap); - kfree(alloc_data); - alloc_data = NULL; - break; - } - } - mutex_unlock(&(mem_data->list_mutex)); - - if (!found) { - dev_err(cb_dev, - "%s: cannot find allocation, dma_buf %pK\n", - __func__, dma_buf); - rc = -EINVAL; - } - - return rc; -} - -static int msm_audio_mem_get_phys(struct dma_buf *dma_buf, - dma_addr_t *addr, size_t *len, bool is_iova, - struct msm_audio_mem_private *mem_data) -{ - int rc = 0; - - rc = msm_audio_dma_buf_map(dma_buf, addr, len, is_iova, mem_data); - if (rc) { - pr_err("%s: failed to map DMA buf, err = %d\n", - __func__, rc); - goto err; - } - if (mem_data->smmu_enabled && is_iova) { - /* Append the SMMU SID information to the IOVA address */ - *addr |= mem_data->smmu_sid_bits; - } - - pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); -err: - return rc; -} - -static int msm_audio_mem_unmap_kernel(struct dma_buf *dma_buf, - struct msm_audio_mem_private *mem_data) -{ - int rc = 0; - struct iosys_map *iosys_vmap = NULL; - struct msm_audio_alloc_data *alloc_data = NULL; - struct device *cb_dev = mem_data->cb_dev; - - /* - * TBD: remove the below section once new API - * for unmapping kernel virtual address is available. - */ - mutex_lock(&(mem_data->list_mutex)); - list_for_each_entry(alloc_data, &(mem_data->alloc_list), - list) { - if (alloc_data->dma_buf == dma_buf) { - iosys_vmap = alloc_data->vmap; - break; - } - } - mutex_unlock(&(mem_data->list_mutex)); - - if (!iosys_vmap) { - dev_err(cb_dev, - "%s: cannot find allocation for dma_buf %pK\n", - __func__, dma_buf); - rc = -EINVAL; - goto err; - } - - dma_buf_vunmap(dma_buf, iosys_vmap); - - 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 rc; -} - -static int msm_audio_mem_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, - size_t *plen, struct iosys_map *iosys_vmap, - struct msm_audio_mem_private *mem_data) -{ - int rc = 0; - bool is_iova = true; - - if (!dma_buf || !paddr || !plen) { - pr_err("%s: Invalid params\n", __func__); - return -EINVAL; - } - - rc = msm_audio_mem_get_phys(dma_buf, paddr, plen, is_iova, mem_data); - if (rc) { - pr_err("%s: MEM Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - dma_buf_put(dma_buf); - goto err; - } - - rc = msm_audio_mem_map_kernel(dma_buf, mem_data, iosys_vmap); - if (rc) { - pr_err("%s: MEM memory mapping for AUDIO failed, err:%d\n", - __func__, rc); - rc = -ENOMEM; - msm_audio_dma_buf_unmap(dma_buf, mem_data); - goto err; - } - -err: - return rc; -} - -void msm_audio_fd_list_debug(void) -{ - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - - list_for_each_entry(msm_audio_fd_data, - &msm_audio_mem_fd_list.fd_list, list) { - pr_debug("%s fd %d handle %pK phy. addr %pK\n", __func__, - msm_audio_fd_data->fd, msm_audio_fd_data->handle, - (void *)msm_audio_fd_data->paddr); - } -} - -void msm_audio_update_fd_list(struct msm_audio_fd_data *msm_audio_fd_data) -{ - struct msm_audio_fd_data *msm_audio_fd_data1 = NULL; - - mutex_lock(&(msm_audio_mem_fd_list.list_mutex)); - list_for_each_entry(msm_audio_fd_data1, - &msm_audio_mem_fd_list.fd_list, list) { - if (msm_audio_fd_data1->fd == msm_audio_fd_data->fd) { - pr_err("%s fd already present, not updating the list\n", - __func__); - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); - return; - } - } - list_add_tail(&msm_audio_fd_data->list, &msm_audio_mem_fd_list.fd_list); - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); -} - -void msm_audio_delete_fd_entry(void *handle) -{ - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - struct list_head *ptr, *next; - - mutex_lock(&(msm_audio_mem_fd_list.list_mutex)); - list_for_each_safe(ptr, next, - &msm_audio_mem_fd_list.fd_list) { - msm_audio_fd_data = list_entry(ptr, struct msm_audio_fd_data, - list); - if (msm_audio_fd_data->handle == handle) { - pr_debug("%s deleting handle %pK entry from list\n", - __func__, handle); - list_del(&(msm_audio_fd_data->list)); - kfree(msm_audio_fd_data); - break; - } - } - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); -} - -int msm_audio_get_phy_addr(int fd, dma_addr_t *paddr, size_t *pa_len) -{ - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - int status = -EINVAL; - - if (!paddr) { - pr_err("%s Invalid paddr param status %d\n", __func__, status); - return status; - } - pr_debug("%s, fd %d\n", __func__, fd); - mutex_lock(&(msm_audio_mem_fd_list.list_mutex)); - list_for_each_entry(msm_audio_fd_data, - &msm_audio_mem_fd_list.fd_list, list) { - if (msm_audio_fd_data->fd == fd) { - *paddr = msm_audio_fd_data->paddr; - *pa_len = msm_audio_fd_data->plen; - status = 0; - pr_debug("%s Found fd %d paddr %pK\n", - __func__, fd, paddr); - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); - return status; - } - } - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); - return status; -} -EXPORT_SYMBOL_GPL(msm_audio_get_phy_addr); - -int msm_audio_set_hyp_assign(int fd, bool assign) -{ - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - int status = -EINVAL; - - mutex_lock(&(msm_audio_mem_fd_list.list_mutex)); - list_for_each_entry(msm_audio_fd_data, - &msm_audio_mem_fd_list.fd_list, list) { - if (msm_audio_fd_data->fd == fd) { - status = 0; - pr_debug("%s Found fd %d\n", __func__, fd); - msm_audio_fd_data->hyp_assign = assign; - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); - return status; - } - } - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); - return status; -} - -void msm_audio_get_handle(int fd, void **handle) -{ - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - - pr_debug("%s fd %d\n", __func__, fd); - mutex_lock(&(msm_audio_mem_fd_list.list_mutex)); - list_for_each_entry(msm_audio_fd_data, - &msm_audio_mem_fd_list.fd_list, list) { - if (msm_audio_fd_data->fd == fd) { - *handle = (struct dma_buf *)msm_audio_fd_data->handle; - pr_debug("%s handle %pK\n", __func__, *handle); - break; - } - } - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); -} - -/** - * msm_audio_mem_import- - * Import MEM buffer with given file descriptor - * - * @dma_buf: dma_buf for the MEM memory - * @fd: file descriptor for the MEM memory - * @bufsz: buffer size - * @paddr: Physical address to be assigned with allocated region - * @plen: length of allocated region to be assigned - * @iosys_vmap: Virtual mapping vmap pointer to be assigned - * - * Returns 0 on success or error on failure - */ -static int msm_audio_mem_import(struct dma_buf **dma_buf, int fd, - size_t bufsz, dma_addr_t *paddr, - size_t *plen, struct iosys_map *iosys_vmap, - struct msm_audio_mem_private *mem_data) -{ - int rc = 0; - - if (!(mem_data->device_status & MSM_AUDIO_MEM_PROBED)) { - pr_debug("%s: probe is not done, deferred\n", __func__); - return -EPROBE_DEFER; - } - - if (!dma_buf || !paddr || !plen) { - pr_err("%s: Invalid params\n", __func__); - return -EINVAL; - } - - /* 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__); - return -EINVAL; - } - - if (mem_data->smmu_enabled) { - rc = msm_audio_mem_map_buf(*dma_buf, paddr, plen, iosys_vmap, mem_data); - if (rc) { - pr_err("%s: failed to map MEM buf, rc = %d\n", __func__, rc); - goto err; - } - pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, - iosys_vmap->vaddr, bufsz); - } else { - msm_audio_dma_buf_map(*dma_buf, paddr, plen, true, mem_data); - } - return 0; -err: - dma_buf_put(*dma_buf); - *dma_buf = NULL; - return rc; -} - -/** - * msm_audio_mem_free - - * fress MEM memory for given client and handle - * - * @dma_buf: dma_buf for the MEM memory - * - * Returns 0 on success or error on failure - */ -static int msm_audio_mem_free(struct dma_buf *dma_buf, struct msm_audio_mem_private *mem_data) -{ - int ret = 0; - - if (!dma_buf) { - pr_err("%s: dma_buf invalid\n", __func__); - return -EINVAL; - } - - if (mem_data->smmu_enabled) { - ret = msm_audio_mem_unmap_kernel(dma_buf, mem_data); - if (ret) - return ret; - } - - msm_audio_dma_buf_unmap(dma_buf, mem_data); - - return 0; -} - -/** - * msm_audio_mem_crash_handler - - * handles cleanup after userspace crashes. - * - * To be called from machine driver. - */ -void msm_audio_mem_crash_handler(void) -{ - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - struct list_head *ptr, *next; - void *handle = NULL; - struct msm_audio_mem_private *mem_data = NULL; - - mutex_lock(&(msm_audio_mem_fd_list.list_mutex)); - list_for_each_entry(msm_audio_fd_data, - &msm_audio_mem_fd_list.fd_list, list) { - handle = msm_audio_fd_data->handle; - mem_data = dev_get_drvdata(msm_audio_fd_data->dev); - /* clean if CMA was used*/ - msm_audio_mem_free(handle, mem_data); - } - list_for_each_safe(ptr, next, - &msm_audio_mem_fd_list.fd_list) { - msm_audio_fd_data = list_entry(ptr, struct msm_audio_fd_data, - list); - list_del(&(msm_audio_fd_data->list)); - kfree(msm_audio_fd_data); - } - mutex_unlock(&(msm_audio_mem_fd_list.list_mutex)); -} -EXPORT_SYMBOL_GPL(msm_audio_mem_crash_handler); - -static int msm_audio_mem_open(struct inode *inode, struct file *file) -{ - struct msm_audio_mem_private *mem_data = container_of(inode->i_cdev, - struct msm_audio_mem_private, - cdev); - struct device *dev = mem_data->chardev; - - get_device(dev); - return 0; -} - -static int msm_audio_mem_release(struct inode *inode, struct file *file) -{ - struct msm_audio_mem_private *mem_data = container_of(inode->i_cdev, - struct msm_audio_mem_private, - cdev); - struct device *dev = mem_data->chardev; - - put_device(dev); - return 0; -} - -static long msm_audio_mem_ioctl(struct file *file, unsigned int ioctl_num, - unsigned long __user ioctl_param) -{ - void *mem_handle; - dma_addr_t paddr; - size_t pa_len = 0; - struct iosys_map *iosys_vmap = NULL; - int ret = 0; - struct msm_audio_fd_data *msm_audio_fd_data = NULL; - struct msm_audio_mem_private *mem_data = - container_of(file->f_inode->i_cdev, struct msm_audio_mem_private, cdev); - - switch (ioctl_num) { - case IOCTL_MAP_PHYS_ADDR: - iosys_vmap = kzalloc(sizeof(struct msm_audio_fd_data), GFP_KERNEL); - if (!iosys_vmap) - return -ENOMEM; - msm_audio_fd_data = kzalloc((sizeof(struct msm_audio_fd_data)), - GFP_KERNEL); - if (!msm_audio_fd_data) { - kfree(iosys_vmap); - return -ENOMEM; - } - ret = msm_audio_mem_import((struct dma_buf **)&mem_handle, (int)ioctl_param, - 0, &paddr, &pa_len, iosys_vmap, mem_data); - if (ret < 0) { - pr_err("%s Memory map Failed %d\n", __func__, ret); - kfree(iosys_vmap); - kfree(msm_audio_fd_data); - return ret; - } - msm_audio_fd_data->fd = (int)ioctl_param; - msm_audio_fd_data->handle = mem_handle; - msm_audio_fd_data->paddr = paddr; - msm_audio_fd_data->plen = pa_len; - msm_audio_fd_data->dev = mem_data->cb_dev; - msm_audio_update_fd_list(msm_audio_fd_data); - break; - case IOCTL_UNMAP_PHYS_ADDR: - msm_audio_get_handle((int)ioctl_param, &mem_handle); - ret = msm_audio_mem_free(mem_handle, mem_data); - if (ret < 0) { - pr_err("%s Ion free failed %d\n", __func__, ret); - return ret; - } - msm_audio_delete_fd_entry(mem_handle); - break; - default: - pr_err("%s Entered default. Invalid ioctl num %u\n", - __func__, ioctl_num); - ret = -EINVAL; - break; - } - return ret; -} - -static const struct of_device_id msm_audio_mem_dt_match[] = { - { .compatible = "qcom,msm-audio-mem" }, - { .compatible = "qcom,msm-audio-mem-cma"}, - { } -}; -MODULE_DEVICE_TABLE(of, msm_audio_mem_dt_match); - -static const struct file_operations msm_audio_mem_fops = { - .owner = THIS_MODULE, - .open = msm_audio_mem_open, - .release = msm_audio_mem_release, - .unlocked_ioctl = msm_audio_mem_ioctl, -}; - -static int msm_audio_mem_reg_chrdev(struct msm_audio_mem_private *mem_data) -{ - int ret = 0; - - ret = alloc_chrdev_region(&mem_data->mem_major, 0, - MINOR_NUMBER_COUNT, mem_data->driver_name); - if (ret < 0) { - pr_err("%s alloc_chr_dev_region failed ret : %d\n", - __func__, ret); - return ret; - } - pr_debug("%s major number %d\n", __func__, MAJOR(mem_data->mem_major)); - mem_data->mem_class = class_create(THIS_MODULE, mem_data->driver_name); - if (IS_ERR(mem_data->mem_class)) { - ret = PTR_ERR(mem_data->mem_class); - pr_err("%s class create failed. ret : %d\n", __func__, ret); - goto err_class; - } - mem_data->chardev = device_create(mem_data->mem_class, NULL, - mem_data->mem_major, NULL, - mem_data->driver_name); - if (IS_ERR(mem_data->chardev)) { - ret = PTR_ERR(mem_data->chardev); - pr_err("%s device create failed ret : %d\n", __func__, ret); - goto err_device; - } - cdev_init(&mem_data->cdev, &msm_audio_mem_fops); - ret = cdev_add(&mem_data->cdev, mem_data->mem_major, 1); - if (ret) { - pr_err("%s cdev add failed, ret : %d\n", __func__, ret); - goto err_cdev; - } - return ret; - -err_cdev: - device_destroy(mem_data->mem_class, mem_data->mem_major); -err_device: - class_destroy(mem_data->mem_class); -err_class: - unregister_chrdev_region(0, MINOR_NUMBER_COUNT); - return ret; -} - -static int msm_audio_mem_unreg_chrdev(struct msm_audio_mem_private *mem_data) -{ - cdev_del(&mem_data->cdev); - device_destroy(mem_data->mem_class, mem_data->mem_major); - class_destroy(mem_data->mem_class); - unregister_chrdev_region(0, MINOR_NUMBER_COUNT); - return 0; -} -static int msm_audio_mem_probe(struct platform_device *pdev) -{ - int rc = 0; - u64 smmu_sid = 0; - u64 smmu_sid_mask = 0; - const char *msm_audio_mem_dt = "qcom,smmu-enabled"; - const char *msm_audio_mem_smmu_sid_mask = "qcom,smmu-sid-mask"; - bool smmu_enabled; - struct device *dev = &pdev->dev; - struct of_phandle_args iommuspec; - struct msm_audio_mem_private *msm_audio_mem_data = NULL; - - if (dev->of_node == NULL) { - dev_err(dev, - "%s: device tree is not found\n", - __func__); - return 0; - } - - msm_audio_mem_data = devm_kzalloc(&pdev->dev, (sizeof(struct msm_audio_mem_private)), - GFP_KERNEL); - if (!msm_audio_mem_data) - return -ENOMEM; - - smmu_enabled = of_property_read_bool(dev->of_node, - msm_audio_mem_dt); - msm_audio_mem_data->smmu_enabled = smmu_enabled; - - dev_dbg(dev, "%s: SMMU is %s\n", __func__, (!smmu_enabled) ? "Disabled" : "Enabled"); - - if (smmu_enabled) { - msm_audio_mem_data->driver_name = "msm_audio_mem"; - /* Get SMMU SID information from Devicetree */ - rc = of_property_read_u64(dev->of_node, - msm_audio_mem_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_mem_data->smmu_sid_bits = - smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; - } else { - msm_audio_mem_data->driver_name = "msm_audio_mem_cma"; - - rc = of_reserved_mem_device_init(dev); - if (rc) { - pr_err("%s: No reserved DMA memory, ret=%d\n", __func__, rc); - return -EINVAL; - } - } - - if (!rc) - msm_audio_mem_data->device_status |= MSM_AUDIO_MEM_PROBED; - - msm_audio_mem_data->cb_dev = dev; - dev_set_drvdata(dev, msm_audio_mem_data); - if (!msm_audio_mem_fd_list_init) { - INIT_LIST_HEAD(&msm_audio_mem_fd_list.fd_list); - mutex_init(&(msm_audio_mem_fd_list.list_mutex)); - msm_audio_mem_fd_list_init = true; - } - INIT_LIST_HEAD(&msm_audio_mem_data->alloc_list); - mutex_init(&(msm_audio_mem_data->list_mutex)); - rc = msm_audio_mem_reg_chrdev(msm_audio_mem_data); - if (rc) { - pr_err("%s register char dev failed, rc : %d\n", __func__, rc); - return rc; - } - return rc; -} - -static int msm_audio_mem_remove(struct platform_device *pdev) -{ - struct msm_audio_mem_private *mem_data = dev_get_drvdata(&pdev->dev); - - mem_data->smmu_enabled = false; - mem_data->device_status = 0; - msm_audio_mem_unreg_chrdev(mem_data); - return 0; -} - -static struct platform_driver msm_audio_mem_driver = { - .driver = { - .name = "msm-audio-mem", - .owner = THIS_MODULE, - .of_match_table = msm_audio_mem_dt_match, - .suppress_bind_attrs = true, - }, - .probe = msm_audio_mem_probe, - .remove = msm_audio_mem_remove, -}; - -int __init msm_audio_mem_init(void) -{ - return platform_driver_register(&msm_audio_mem_driver); -} - -void msm_audio_mem_exit(void) -{ - platform_driver_unregister(&msm_audio_mem_driver); -} - -module_init(msm_audio_mem_init); -module_exit(msm_audio_mem_exit); -MODULE_DESCRIPTION("MSM Audio MEM module"); -MODULE_LICENSE("GPL"); diff --git a/dsp/spf-core.c b/dsp/spf-core.c deleted file mode 100644 index e416ff1..0000000 --- a/dsp/spf-core.c +++ /dev/null @@ -1,285 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APM_STATE_READY_TIMEOUT_MS 10000 -#define Q6_READY_TIMEOUT_MS 1000 -#define APM_CMD_GET_SPF_STATE 0x01001021 -#define APM_CMD_RSP_GET_SPF_STATE 0x02001007 -#define APM_MODULE_INSTANCE_ID 0x00000001 -#define GPR_SVC_ADSP_CORE 0x3 - -struct spf_core { - gpr_device_t *adev; - wait_queue_head_t wait; - struct mutex lock; - bool resp_received; - bool is_ready; -}; - -struct spf_core_private { - struct device *dev; - struct mutex lock; - struct spf_core *spf_core_drv; - bool is_initial_boot; - struct work_struct add_chld_dev_work; -}; - -static struct spf_core_private *spf_core_priv; -struct apm_cmd_rsp_get_spf_status_t - -{ - /* Spf status - * @values - * 0 -> Not ready - * 1 -> Ready - */ - uint32_t status; - -}; - -static int spf_core_callback(struct gpr_resp_pkt *data, void *priv, int op) -{ - gpr_device_t *gdev = priv; - struct spf_core *core = dev_get_drvdata(&gdev->dev); - struct gpr_ibasic_rsp_result_t *result; - struct gpr_hdr *hdr = &data->hdr; - - result = data->payload; - - switch (hdr->opcode) { - case GPR_BASIC_RSP_RESULT: - dev_err(&gdev->dev, "%s: Failed response received\n", __func__); - core->resp_received = true; - break; - case APM_CMD_RSP_GET_SPF_STATE: - core->is_ready = result->opcode; - dev_err(&gdev->dev, "%s: success response received, core->is_ready=%d\n", - __func__, core->is_ready); - core->resp_received = true; - break; - default: - dev_err(&gdev->dev, "Message ID from apm: 0x%x\n", - hdr->opcode); - break; - } - if (core->resp_received) - wake_up(&core->wait); - - return 0; -} - -static bool __spf_core_is_apm_ready(struct spf_core *core) -{ - gpr_device_t *adev = core->adev; - struct gpr_pkt pkt; - int rc; - - pkt.hdr.version = GPR_PKT_VER; - pkt.hdr.hdr_size = GPR_PKT_HEADER_WORD_SIZE; - pkt.hdr.pkt_size = GPR_HDR_SIZE; - - pkt.hdr.opcode = APM_CMD_GET_SPF_STATE; - pkt.hdr.dest_port = APM_MODULE_INSTANCE_ID; - pkt.hdr.src_port = adev->svc_id; //1 - pkt.hdr.dest_domain = GPR_DOMAIN_ID_ADSP; - pkt.hdr.src_domain = GPR_DOMAIN_ID_APPS; - pkt.hdr.opcode = APM_CMD_GET_SPF_STATE; - - rc = gpr_send_pkt(adev, &pkt); - if (rc < 0) - return false; - - rc = wait_event_timeout(core->wait, - (core->resp_received), msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); - - if (rc > 0 && core->resp_received) { - core->resp_received = false; - - if (core->is_ready) - return true; - } else { - dev_err(spf_core_priv->dev, "%s: command timedout, ret\n", - __func__); - } - - return false; -} - -/** - * spf_core_is_apm_ready() - Get status of adsp - * - * Return: Will be an true if apm is ready and false if not. - */ -bool spf_core_is_apm_ready(void) -{ - unsigned long timeout; - bool ret = false; - struct spf_core *core; - - if (!spf_core_priv) - return ret; - - core = spf_core_priv->spf_core_drv; - if (!core) - return ret; - - mutex_lock(&core->lock); - timeout = jiffies + msecs_to_jiffies(APM_STATE_READY_TIMEOUT_MS); - for (;;) { - if (__spf_core_is_apm_ready(core)) { - ret = true; - break; - } - usleep_range(300000, 300050); - if (!time_after(timeout, jiffies)) { - ret = false; - break; - } - } - - mutex_unlock(&core->lock); - return ret; -} -EXPORT_SYMBOL_GPL(spf_core_is_apm_ready); - -static int spf_core_probe(gpr_device_t *adev) -{ - struct spf_core *core; - - if (!spf_core_priv) { - pr_err("%s: spf_core platform probe not yet done\n", __func__); - return -EPROBE_DEFER; - } - mutex_lock(&spf_core_priv->lock); - core = kzalloc(sizeof(*core), GFP_KERNEL); - if (!core) { - mutex_unlock(&spf_core_priv->lock); - return -ENOMEM; - } - dev_set_drvdata(&adev->dev, core); - - mutex_init(&core->lock); - core->adev = adev; - init_waitqueue_head(&core->wait); - spf_core_priv->spf_core_drv = core; - if (spf_core_priv->is_initial_boot) - schedule_work(&spf_core_priv->add_chld_dev_work); - mutex_unlock(&spf_core_priv->lock); - - return 0; -} - -static void spf_core_exit(gpr_device_t *adev) -{ - struct spf_core *core = dev_get_drvdata(&adev->dev); - - if (!spf_core_priv) { - pr_err("%s: spf_core platform probe not yet done\n", __func__); - return; - } - mutex_lock(&spf_core_priv->lock); - spf_core_priv->spf_core_drv = NULL; - kfree(core); - mutex_unlock(&spf_core_priv->lock); -} - -static const struct of_device_id spf_core_device_id[] = { - { .compatible = "qcom,spf_core" }, - {}, -}; -MODULE_DEVICE_TABLE(of, spf_core_device_id); - -static gpr_driver_t ar_spf_core_driver = { - .probe = spf_core_probe, - .remove = spf_core_exit, - .gpr_callback = spf_core_callback, - .driver = { - .name = "qcom-spf_core", - .of_match_table = of_match_ptr(spf_core_device_id), - }, -}; - -static void spf_core_add_child_devices(struct work_struct *work) -{ - int ret; - - if (spf_core_is_apm_ready()) { - dev_err(spf_core_priv->dev, "%s: apm is up\n", - __func__); - } else { - dev_err(spf_core_priv->dev, "%s: apm is not up\n", - __func__); - return; - } - - ret = of_platform_populate(spf_core_priv->dev->of_node, - NULL, NULL, spf_core_priv->dev); - if (ret) - dev_err(spf_core_priv->dev, "%s: failed to add child nodes, ret=%d\n", - __func__, ret); - - spf_core_priv->is_initial_boot = false; -} - -static int spf_core_platform_driver_probe(struct platform_device *pdev) -{ - int ret = 0; - - spf_core_priv = devm_kzalloc(&pdev->dev, sizeof(struct spf_core_private), GFP_KERNEL); - if (!spf_core_priv) - return -ENOMEM; - - spf_core_priv->dev = &pdev->dev; - - mutex_init(&spf_core_priv->lock); - - INIT_WORK(&spf_core_priv->add_chld_dev_work, spf_core_add_child_devices); - - spf_core_priv->is_initial_boot = true; - ret = apr_driver_register(&ar_spf_core_driver); - if (ret) { - pr_err("%s: gpr driver register failed = %d\n", - __func__, ret); - ret = 0; - } - - return ret; -} - -static int spf_core_platform_driver_remove(struct platform_device *pdev) -{ - apr_driver_unregister(&ar_spf_core_driver); - spf_core_priv = NULL; - return 0; -} - -static const struct of_device_id spf_core_of_match[] = { - { .compatible = "qcom,spf-core-platform", }, - {}, -}; - -static struct platform_driver spf_core_driver = { - .probe = spf_core_platform_driver_probe, - .remove = spf_core_platform_driver_remove, - .driver = { - .name = "spf-core-platform", - .of_match_table = spf_core_of_match, - } -}; - -module_platform_driver(spf_core_driver); - -MODULE_DESCRIPTION("qcom spf core"); -MODULE_LICENSE("GPL"); diff --git a/include/dsp/msm_audio_mem.h b/include/dsp/msm_audio_mem.h deleted file mode 100644 index cf9c6f8..0000000 --- a/include/dsp/msm_audio_mem.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#ifndef _MSM_AUDIO_MEM_H -#define _MSM_AUDIO_MEM_H - -#include -#include - -int msm_audio_get_phy_addr(int fd, dma_addr_t *paddr, size_t *pa_len); -void msm_audio_mem_crash_handler(void); -#endif /* _LINUX_MSM_AUDIO_MEM_H */ diff --git a/ipc/audio-pkt.c b/ipc/audio-pkt.c deleted file mode 100644 index 14dfd83..0000000 --- a/ipc/audio-pkt.c +++ /dev/null @@ -1,519 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APM_CMD_SHARED_MEM_MAP_REGIONS 0x0100100C -#define APM_MEMORY_MAP_BIT_MASK_IS_OFFSET_MODE 0x00000004UL - -static bool audio_pkt_probed; -/* Define Logging Macros */ -static int audio_pkt_debug_mask; -enum { - AUDIO_PKT_INFO = 1U << 0, -}; - -#define AUDIO_PKT_INFO(x, ...) \ -do { \ - if (audio_pkt_debug_mask & AUDIO_PKT_INFO) { \ - pr_info_ratelimited("[%s]: "x, __func__, ##__VA_ARGS__); \ - } \ -} while (0) - -#define AUDIO_PKT_ERR(x, ...) \ -{ \ - pr_err_ratelimited("[%s]: "x, __func__, ##__VA_ARGS__); \ -} - -#define MODULE_NAME "audio-pkt" -#define MINOR_NUMBER_COUNT 1 -#define AUDPKT_DRIVER_NAME "aud_pasthru_adsp" -#define CHANNEL_NAME "to_apps" - -/** - * struct audio_pkt - driver context, relates rpdev to cdev - * @adev: gpr device node - * @dev: audio pkt device - * @cdev: cdev for the audio pkt device - * @lock: synchronization of @rpdev - * @queue_lock: synchronization of @queue operations - * @queue: incoming message queue - * @readq: wait object for incoming queue - * @dev_name: /dev/@dev_name for audio_pkt device - * @ch_name: audio channel to match to - * @audio_pkt_major: Major number of audio pkt driver - * @audio_pkt_class: audio pkt class pointer - */ -struct audio_pkt_device { - gpr_device_t *adev; - struct device *dev; - struct cdev cdev; - - struct mutex lock; - - spinlock_t queue_lock; - struct sk_buff_head queue; - wait_queue_head_t readq; - - char dev_name[20]; - char ch_name[20]; - - dev_t audio_pkt_major; - struct class *audio_pkt_class; -}; - -struct audio_pkt_apm_cmd_shared_mem_map_regions_t { - uint16_t mem_pool_id; - uint16_t num_regions; - uint32_t property_flag; - -}; - -struct audio_pkt_apm_shared_map_region_payload_t { - uint32_t shm_addr_lsw; - uint32_t shm_addr_msw; - uint32_t mem_size_bytes; -}; - -struct audio_pkt_apm_mem_map { - struct audio_pkt_apm_cmd_shared_mem_map_regions_t mmap_header; - struct audio_pkt_apm_shared_map_region_payload_t mmap_payload; -}; - -struct audio_gpr_pkt { - struct gpr_hdr audpkt_hdr; - struct audio_pkt_apm_mem_map audpkt_mem_map; -}; - -typedef void (*audio_pkt_clnt_cb_fn)(void *buf, int len, void *priv); - -struct audio_pkt_clnt_ch { - int client_id; - audio_pkt_clnt_cb_fn func; -}; - -#define dev_to_audpkt_dev(_dev) container_of(_dev, struct audio_pkt_device, dev) -#define cdev_to_audpkt_dev(_cdev) container_of(_cdev, struct audio_pkt_device, cdev) - -/** - * audio_pkt_open() - open() syscall for the audio_pkt device - * inode: Pointer to the inode structure. - * file: Pointer to the file structure. - * - * This function is used to open the audio pkt device when - * userspace client do a open() system call. All input arguments are - * validated by the virtual file system before calling this function. - */ -int audio_pkt_open(struct inode *inode, struct file *file) -{ - struct audio_pkt_device *audpkt_dev = cdev_to_audpkt_dev(inode->i_cdev); - struct device *dev = audpkt_dev->dev; - - AUDIO_PKT_ERR("for %s\n", audpkt_dev->ch_name); - - get_device(dev); - file->private_data = audpkt_dev; - - return 0; -} - -/** - * audio_pkt_release() - release operation on audio_pkt device - * inode: Pointer to the inode structure. - * file: Pointer to the file structure. - * - * This function is used to release the audio pkt device when - * userspace client do a close() system call. All input arguments are - * validated by the virtual file system before calling this function. - */ -int audio_pkt_release(struct inode *inode, struct file *file) -{ - struct audio_pkt_device *audpkt_dev = cdev_to_audpkt_dev(inode->i_cdev); - struct device *dev = audpkt_dev->dev; - struct sk_buff *skb; - unsigned long flags; - - spin_lock_irqsave(&audpkt_dev->queue_lock, flags); - - /* Discard all SKBs */ - while (!skb_queue_empty(&audpkt_dev->queue)) { - skb = skb_dequeue(&audpkt_dev->queue); - kfree_skb(skb); - } - wake_up_interruptible(&audpkt_dev->readq); - spin_unlock_irqrestore(&audpkt_dev->queue_lock, flags); - - put_device(dev); - file->private_data = NULL; - - return 0; -} - -/** - * audio_pkt_read() - read() syscall for the audio_pkt device - * file: Pointer to the file structure. - * buf: Pointer to the userspace buffer. - * count: Number bytes to read from the file. - * ppos: Pointer to the position into the file. - * - * This function is used to Read the data from audio pkt device when - * userspace client do a read() system call. All input arguments are - * validated by the virtual file system before calling this function. - */ -ssize_t audio_pkt_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct audio_pkt_device *audpkt_dev = file->private_data; - unsigned long flags; - struct sk_buff *skb; - int use; - uint32_t *temp; - - if (!audpkt_dev) { - AUDIO_PKT_ERR("invalid device handle\n"); - return -EINVAL; - } - - spin_lock_irqsave(&audpkt_dev->queue_lock, flags); - /* Wait for data in the queue */ - if (skb_queue_empty(&audpkt_dev->queue)) { - spin_unlock_irqrestore(&audpkt_dev->queue_lock, flags); - - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - - /* Wait until we get data or the endpoint goes away */ - if (wait_event_interruptible(audpkt_dev->readq, - !skb_queue_empty(&audpkt_dev->queue))) - return -ERESTARTSYS; - - spin_lock_irqsave(&audpkt_dev->queue_lock, flags); - } - - skb = skb_dequeue(&audpkt_dev->queue); - spin_unlock_irqrestore(&audpkt_dev->queue_lock, flags); - if (!skb) - return -EFAULT; - - use = min_t(size_t, count, skb->len); - if (copy_to_user(buf, skb->data, use)) - use = -EFAULT; - temp = (uint32_t *) skb->data; - kfree_skb(skb); - - return use; -} - -/** - * audpkt_update_physical_addr - Update physical address - * audpkt_hdr: Pointer to the file structure. - */ -int audpkt_chk_and_update_physical_addr(struct audio_gpr_pkt *gpr_pkt) -{ - size_t pa_len = 0; - dma_addr_t paddr = 0; - int ret = 0; - - if (gpr_pkt->audpkt_mem_map.mmap_header.property_flag & - APM_MEMORY_MAP_BIT_MASK_IS_OFFSET_MODE) { - - /* TODO: move physical address mapping to use DMA-BUF heaps */ - ret = msm_audio_get_phy_addr( - (int) gpr_pkt->audpkt_mem_map.mmap_payload.shm_addr_lsw, - &paddr, &pa_len); - if (ret < 0) { - AUDIO_PKT_ERR("%s Get phy. address failed, ret %d\n", - __func__, ret); - return ret; - } - - AUDIO_PKT_INFO("%s physical address %pK", __func__, - (void *) paddr); - gpr_pkt->audpkt_mem_map.mmap_payload.shm_addr_lsw = (uint32_t) paddr; - gpr_pkt->audpkt_mem_map.mmap_payload.shm_addr_msw = (uint64_t) paddr >> 32; - } - return ret; -} - -/** - * audio_pkt_write() - write() syscall for the audio_pkt device - * file: Pointer to the file structure. - * buf: Pointer to the userspace buffer. - * count: Number bytes to read from the file. - * ppos: Pointer to the position into the file. - * - * This function is used to write the data to audio pkt device when - * userspace client do a write() system call. All input arguments are - * validated by the virtual file system before calling this function. - */ -ssize_t audio_pkt_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct audio_pkt_device *audpkt_dev = file->private_data; - struct gpr_hdr *audpkt_hdr = NULL; - void *kbuf; - int ret; - - if (!audpkt_dev) { - AUDIO_PKT_ERR("invalid device handle\n"); - return -EINVAL; - } - - kbuf = memdup_user(buf, count); - if (IS_ERR(kbuf)) - return PTR_ERR(kbuf); - - audpkt_hdr = (struct gpr_hdr *) kbuf; - if (audpkt_hdr->opcode == APM_CMD_SHARED_MEM_MAP_REGIONS) { - ret = audpkt_chk_and_update_physical_addr((struct audio_gpr_pkt *) audpkt_hdr); - if (ret < 0) { - AUDIO_PKT_ERR("Update Physical Address Failed -%d\n", ret); - return ret; - } - } - - if (mutex_lock_interruptible(&audpkt_dev->lock)) { - ret = -ERESTARTSYS; - goto free_kbuf; - } - ret = gpr_send_pkt(audpkt_dev->adev, (struct gpr_pkt *) kbuf); - if (ret < 0) { - AUDIO_PKT_ERR("APR Send Packet Failed ret -%d\n", ret); - return ret; - } - mutex_unlock(&audpkt_dev->lock); - -free_kbuf: - kfree(kbuf); - return ret < 0 ? ret : count; -} - -/** - * audio_pkt_poll() - poll() syscall for the audio_pkt device - * file: Pointer to the file structure. - * wait: pointer to Poll table. - * - * This function is used to poll on the audio pkt device when - * userspace client do a poll() system call. All input arguments are - * validated by the virtual file system before calling this function. - */ -static unsigned int audio_pkt_poll(struct file *file, poll_table *wait) -{ - struct audio_pkt_device *audpkt_dev = file->private_data; - unsigned int mask = 0; - unsigned long flags; - - audpkt_dev = file->private_data; - if (!audpkt_dev) { - AUDIO_PKT_ERR("invalid device handle\n"); - return POLLERR; - } - - poll_wait(file, &audpkt_dev->readq, wait); - - mutex_lock(&audpkt_dev->lock); - - spin_lock_irqsave(&audpkt_dev->queue_lock, flags); - if (!skb_queue_empty(&audpkt_dev->queue)) - mask |= POLLIN | POLLRDNORM; - - spin_unlock_irqrestore(&audpkt_dev->queue_lock, flags); - - mutex_unlock(&audpkt_dev->lock); - - return mask; -} - -static const struct file_operations audio_pkt_fops = { - .owner = THIS_MODULE, - .open = audio_pkt_open, - .release = audio_pkt_release, - .read = audio_pkt_read, - .write = audio_pkt_write, - .poll = audio_pkt_poll, -}; - -/** - * audio_pkt_srvc_callback() - Callback from gpr driver - * adev: pointer to the gpr device of this audio packet device - * data: APR response data packet - * - * return: 0 for success, Standard Linux errors - */ -static int audio_pkt_srvc_callback(struct gpr_resp_pkt *data, void *priv, int op) -{ - gpr_device_t *gdev = priv; - struct audio_pkt_device *audpkt_dev = dev_get_drvdata(&gdev->dev); - unsigned long flags; - struct sk_buff *skb; - struct gpr_hdr *hdr = &data->hdr; - uint8_t *pkt = NULL; - uint16_t hdr_size, pkt_size; - - hdr_size = hdr->hdr_size * 4; - pkt_size = hdr->pkt_size; - - pkt = kmalloc(pkt_size, GFP_KERNEL); - if (!pkt) - return -ENOMEM; - - memcpy(pkt, (uint8_t *)data, hdr_size); - memcpy(pkt + hdr_size, (uint8_t *)data->payload, pkt_size - hdr_size); - - skb = alloc_skb(pkt_size, GFP_ATOMIC); - if (!skb) - return -ENOMEM; - - skb_put_data(skb, (void *)pkt, pkt_size); - - kfree(pkt); - spin_lock_irqsave(&audpkt_dev->queue_lock, flags); - skb_queue_tail(&audpkt_dev->queue, skb); - spin_unlock_irqrestore(&audpkt_dev->queue_lock, flags); - - /* wake up any blocking processes, waiting for new data */ - wake_up_interruptible(&audpkt_dev->readq); - return 0; -} - -/** - * audio_pkt_probe() - Probe a AUDIO packet device - * - * adev: Pointer to gpr device. - * - * return: 0 on success, standard Linux error codes on error. - * - * This function is called when the underlying device tree driver registers - * a gpr device, mapped to a Audio packet device. - */ -static int audio_pkt_probe(gpr_device_t *adev) -{ - struct audio_pkt_device *audpkt_dev; - struct device *dev = &adev->dev; - int ret; - - if (audio_pkt_probed) { - AUDIO_PKT_ERR("audio packet probe already done, ssr unsupported\n"); - return -EINVAL; - } - - audpkt_dev = devm_kzalloc(dev, sizeof(*audpkt_dev), GFP_KERNEL); - if (!audpkt_dev) - return -ENOMEM; - - ret = alloc_chrdev_region(&audpkt_dev->audio_pkt_major, 0, - MINOR_NUMBER_COUNT, AUDPKT_DRIVER_NAME); - if (ret < 0) { - AUDIO_PKT_ERR("alloc_chrdev_region failed ret:%d\n", ret); - goto err_chrdev; - } - - audpkt_dev->audio_pkt_class = class_create(THIS_MODULE, AUDPKT_DRIVER_NAME); - if (IS_ERR(audpkt_dev->audio_pkt_class)) { - ret = PTR_ERR(audpkt_dev->audio_pkt_class); - AUDIO_PKT_ERR("class_create failed ret:%ld\n", - PTR_ERR(audpkt_dev->audio_pkt_class)); - goto err_class; - } - - audpkt_dev->dev = device_create(audpkt_dev->audio_pkt_class, NULL, - audpkt_dev->audio_pkt_major, NULL, - AUDPKT_DRIVER_NAME); - if (IS_ERR(audpkt_dev->dev)) { - ret = PTR_ERR(audpkt_dev->dev); - AUDIO_PKT_ERR("device_create failed ret:%ld\n", - PTR_ERR(audpkt_dev->dev)); - goto err_device; - } - strscpy(audpkt_dev->dev_name, CHANNEL_NAME, 20); - strscpy(audpkt_dev->ch_name, CHANNEL_NAME, 20); - dev_set_name(audpkt_dev->dev, audpkt_dev->dev_name); - - mutex_init(&audpkt_dev->lock); - - spin_lock_init(&audpkt_dev->queue_lock); - skb_queue_head_init(&audpkt_dev->queue); - init_waitqueue_head(&audpkt_dev->readq); - - audpkt_dev->adev = adev; - dev_set_drvdata(dev, audpkt_dev); - - cdev_init(&audpkt_dev->cdev, &audio_pkt_fops); - audpkt_dev->cdev.owner = THIS_MODULE; - - ret = cdev_add(&audpkt_dev->cdev, audpkt_dev->audio_pkt_major, - MINOR_NUMBER_COUNT); - if (ret) { - AUDIO_PKT_ERR("cdev_add failed for %s ret:%d\n", - audpkt_dev->dev_name, ret); - goto free_dev; - } - - AUDIO_PKT_INFO("Audio Packet Port Driver Initialized\n"); - audio_pkt_probed = true; - return of_platform_populate(dev->of_node, NULL, NULL, dev); - -free_dev: - put_device(dev); - device_destroy(audpkt_dev->audio_pkt_class, audpkt_dev->audio_pkt_major); -err_device: - class_destroy(audpkt_dev->audio_pkt_class); -err_class: - unregister_chrdev_region(MAJOR(audpkt_dev->audio_pkt_major), - MINOR_NUMBER_COUNT); -err_chrdev: - return ret; - -} - -/** - * audio_pkt_remove() - Remove a AUDIO packet device - * - * adev: Pointer to gpr device. - * - * return: 0 on success, standard Linux error codes on error. - * - * This function is called when the underlying device tree driver - * removeds a gpr device, mapped to a Audio packet device. - */ -static void audio_pkt_remove(gpr_device_t *adev) -{ - of_platform_depopulate(&adev->dev); - AUDIO_PKT_INFO("Audio Packet Port Driver Removed\n"); -} - -static const struct of_device_id audio_pkt_match_table[] = { - { .compatible = "qcom,audio-pkt" }, - {}, -}; -MODULE_DEVICE_TABLE(of, audio_pkt_match_table); - -static gpr_driver_t audio_pkt_driver = { - .probe = audio_pkt_probe, - .remove = audio_pkt_remove, - .gpr_callback = audio_pkt_srvc_callback, - .driver = { - .name = MODULE_NAME, - .of_match_table = of_match_ptr(audio_pkt_match_table), - }, -}; - -module_gpr_driver(audio_pkt_driver); -MODULE_DESCRIPTION("MSM Audio Packet Driver"); -MODULE_LICENSE("GPL");