misc: fastrpc: separate fastrpc device from channel context
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Mon, 14 Feb 2022 16:09:51 +0000 (16:09 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 Mar 2022 13:11:00 +0000 (14:11 +0100)
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>
drivers/misc/fastrpc.c

index aa1682b..ee5eb87 100644 (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;