forked from Minki/linux
misc: fastrpc: Add support to get DSP capabilities
Add support to get DSP capabilities. The capability information is cached on driver. Signed-off-by: Jeya R <jeyr@codeaurora.org> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Link: https://lore.kernel.org/r/20220214161002.6831-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
5c1b97c7d7
commit
6c16fd8bdd
@ -31,10 +31,15 @@
|
||||
#define FASTRPC_PHYS(p) ((p) & 0xffffffff)
|
||||
#define FASTRPC_CTX_MAX (256)
|
||||
#define FASTRPC_INIT_HANDLE 1
|
||||
#define FASTRPC_DSP_UTILITIES_HANDLE 2
|
||||
#define FASTRPC_CTXID_MASK (0xFF0)
|
||||
#define INIT_FILELEN_MAX (2 * 1024 * 1024)
|
||||
#define FASTRPC_DEVICE_NAME "fastrpc"
|
||||
#define ADSP_MMAP_ADD_PAGES 0x1000
|
||||
#define DSP_UNSUPPORTED_API (0x80000414)
|
||||
/* MAX NUMBER of DSP ATTRIBUTES SUPPORTED */
|
||||
#define FASTRPC_MAX_DSP_ATTRIBUTES (256)
|
||||
#define FASTRPC_MAX_DSP_ATTRIBUTES_LEN (sizeof(u32) * FASTRPC_MAX_DSP_ATTRIBUTES)
|
||||
|
||||
/* Retrives number of input buffers from the scalars parameter */
|
||||
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff)
|
||||
@ -233,6 +238,9 @@ struct fastrpc_channel_ctx {
|
||||
struct idr ctx_idr;
|
||||
struct list_head users;
|
||||
struct kref refcount;
|
||||
/* Flag if dsp attributes are cached */
|
||||
bool valid_attributes;
|
||||
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
|
||||
struct fastrpc_device *fdevice;
|
||||
};
|
||||
|
||||
@ -1378,6 +1386,107 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_get_info_from_dsp(struct fastrpc_user *fl, uint32_t *dsp_attr_buf,
|
||||
uint32_t dsp_attr_buf_len)
|
||||
{
|
||||
struct fastrpc_invoke_args args[2] = { 0 };
|
||||
|
||||
/* Capability filled in userspace */
|
||||
dsp_attr_buf[0] = 0;
|
||||
|
||||
args[0].ptr = (u64)(uintptr_t)&dsp_attr_buf_len;
|
||||
args[0].length = sizeof(dsp_attr_buf_len);
|
||||
args[0].fd = -1;
|
||||
args[1].ptr = (u64)(uintptr_t)&dsp_attr_buf[1];
|
||||
args[1].length = dsp_attr_buf_len;
|
||||
args[1].fd = -1;
|
||||
fl->pd = 1;
|
||||
|
||||
return fastrpc_internal_invoke(fl, true, FASTRPC_DSP_UTILITIES_HANDLE,
|
||||
FASTRPC_SCALARS(0, 1, 1), args);
|
||||
}
|
||||
|
||||
static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap,
|
||||
struct fastrpc_user *fl)
|
||||
{
|
||||
struct fastrpc_channel_ctx *cctx = fl->cctx;
|
||||
uint32_t attribute_id = cap->attribute_id;
|
||||
uint32_t *dsp_attributes;
|
||||
unsigned long flags;
|
||||
uint32_t domain = cap->domain;
|
||||
int err;
|
||||
|
||||
spin_lock_irqsave(&cctx->lock, flags);
|
||||
/* check if we already have queried dsp for attributes */
|
||||
if (cctx->valid_attributes) {
|
||||
spin_unlock_irqrestore(&cctx->lock, flags);
|
||||
goto done;
|
||||
}
|
||||
spin_unlock_irqrestore(&cctx->lock, flags);
|
||||
|
||||
dsp_attributes = kzalloc(FASTRPC_MAX_DSP_ATTRIBUTES_LEN, GFP_KERNEL);
|
||||
if (!dsp_attributes)
|
||||
return -ENOMEM;
|
||||
|
||||
err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES_LEN);
|
||||
if (err == DSP_UNSUPPORTED_API) {
|
||||
dev_info(&cctx->rpdev->dev,
|
||||
"Warning: DSP capabilities not supported on domain: %d\n", domain);
|
||||
kfree(dsp_attributes);
|
||||
return -EOPNOTSUPP;
|
||||
} else if (err) {
|
||||
dev_err(&cctx->rpdev->dev, "Error: dsp information is incorrect err: %d\n", err);
|
||||
kfree(dsp_attributes);
|
||||
return err;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&cctx->lock, flags);
|
||||
memcpy(cctx->dsp_attributes, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES_LEN);
|
||||
cctx->valid_attributes = true;
|
||||
spin_unlock_irqrestore(&cctx->lock, flags);
|
||||
kfree(dsp_attributes);
|
||||
done:
|
||||
cap->capability = cctx->dsp_attributes[attribute_id];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp)
|
||||
{
|
||||
struct fastrpc_ioctl_capability cap = {0};
|
||||
int err = 0;
|
||||
|
||||
if (copy_from_user(&cap, argp, sizeof(cap)))
|
||||
return -EFAULT;
|
||||
|
||||
cap.capability = 0;
|
||||
if (cap.domain >= FASTRPC_DEV_MAX) {
|
||||
dev_err(&fl->cctx->rpdev->dev, "Error: Invalid domain id:%d, err:%d\n",
|
||||
cap.domain, err);
|
||||
return -ECHRNG;
|
||||
}
|
||||
|
||||
/* Fastrpc Capablities does not support modem domain */
|
||||
if (cap.domain == MDSP_DOMAIN_ID) {
|
||||
dev_err(&fl->cctx->rpdev->dev, "Error: modem not supported %d\n", err);
|
||||
return -ECHRNG;
|
||||
}
|
||||
|
||||
if (cap.attribute_id >= FASTRPC_MAX_DSP_ATTRIBUTES) {
|
||||
dev_err(&fl->cctx->rpdev->dev, "Error: invalid attribute: %d, err: %d\n",
|
||||
cap.attribute_id, err);
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
err = fastrpc_get_info_from_kernel(&cap, fl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (copy_to_user(argp, &cap.capability, sizeof(cap.capability)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fastrpc_req_munmap_impl(struct fastrpc_user *fl,
|
||||
struct fastrpc_req_munmap *req)
|
||||
{
|
||||
@ -1683,6 +1792,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
|
||||
case FASTRPC_IOCTL_MEM_UNMAP:
|
||||
err = fastrpc_req_mem_unmap(fl, argp);
|
||||
break;
|
||||
case FASTRPC_IOCTL_GET_DSP_INFO:
|
||||
err = fastrpc_get_dsp_info(fl, argp);
|
||||
break;
|
||||
default:
|
||||
err = -ENOTTY;
|
||||
break;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8)
|
||||
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map)
|
||||
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap)
|
||||
#define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability)
|
||||
|
||||
/**
|
||||
* enum fastrpc_map_flags - control flags for mapping memory on DSP user process
|
||||
@ -105,4 +106,11 @@ struct fastrpc_mem_unmap {
|
||||
__s32 reserved[5];
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_capability {
|
||||
__u32 domain;
|
||||
__u32 attribute_id;
|
||||
__u32 capability; /* dsp capability */
|
||||
__u32 reserved[4];
|
||||
};
|
||||
|
||||
#endif /* __QCOM_FASTRPC_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user