misc: fastrpc: separate fastrpc device from channel context

Currently fastrpc misc device instance is within channel context struct
with a kref. So we have 2 structs with refcount, both of them managing the
same channel context structure.

Separate fastrpc device from channel context and by adding a dedicated
fastrpc_device structure, this should clean the structures a bit and also help
when adding secure device node support.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20220214161002.6831-2-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Srinivas Kandagatla 2022-02-14 16:09:51 +00:00 committed by Greg Kroah-Hartman
parent 084973e944
commit 965602eabb
1 changed files with 37 additions and 9 deletions

View File

@ -78,7 +78,7 @@
#define USER_PD (1)
#define SENSORS_PD (2)
#define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev)
#define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev)
static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
"sdsp", "cdsp"};
@ -212,8 +212,13 @@ struct fastrpc_channel_ctx {
spinlock_t lock;
struct idr ctx_idr;
struct list_head users;
struct miscdevice miscdev;
struct kref refcount;
struct fastrpc_device *fdevice;
};
struct fastrpc_device {
struct fastrpc_channel_ctx *cctx;
struct miscdevice miscdev;
};
struct fastrpc_user {
@ -1220,10 +1225,14 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
static int fastrpc_device_open(struct inode *inode, struct file *filp)
{
struct fastrpc_channel_ctx *cctx = miscdev_to_cctx(filp->private_data);
struct fastrpc_channel_ctx *cctx;
struct fastrpc_device *fdevice;
struct fastrpc_user *fl = NULL;
unsigned long flags;
fdevice = miscdev_to_fdevice(filp->private_data);
cctx = fdevice->cctx;
fl = kzalloc(sizeof(*fl), GFP_KERNEL);
if (!fl)
return -ENOMEM;
@ -1615,6 +1624,27 @@ static struct platform_driver fastrpc_cb_driver = {
},
};
static int fastrpc_device_register(struct device *dev, struct fastrpc_channel_ctx *cctx,
const char *domain)
{
struct fastrpc_device *fdev;
int err;
fdev = devm_kzalloc(dev, sizeof(*fdev), GFP_KERNEL);
if (!fdev)
return -ENOMEM;
fdev->cctx = cctx;
fdev->miscdev.minor = MISC_DYNAMIC_MINOR;
fdev->miscdev.fops = &fastrpc_fops;
fdev->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "fastrpc-%s", domain);
err = misc_register(&fdev->miscdev);
if (!err)
cctx->fdevice = fdev;
return err;
}
static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
{
struct device *rdev = &rpdev->dev;
@ -1644,11 +1674,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
if (!data)
return -ENOMEM;
data->miscdev.minor = MISC_DYNAMIC_MINOR;
data->miscdev.name = devm_kasprintf(rdev, GFP_KERNEL, "fastrpc-%s",
domains[domain_id]);
data->miscdev.fops = &fastrpc_fops;
err = misc_register(&data->miscdev);
err = fastrpc_device_register(rdev, data, domains[domain_id]);
if (err) {
kfree(data);
return err;
@ -1688,7 +1714,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
fastrpc_notify_users(user);
spin_unlock_irqrestore(&cctx->lock, flags);
misc_deregister(&cctx->miscdev);
if (cctx->fdevice)
misc_deregister(&cctx->fdevice->miscdev);
of_platform_depopulate(&rpdev->dev);
cctx->rpdev = NULL;