From: Roman Kiryanov <r...@google.com>

This is the last patch in the series of patches to remove mutable
global variables to introduce another version of the pipe driver
for the older host interface. I don't want to have two driver
states where only one is used.

Signed-off-by: Roman Kiryanov <r...@google.com>
---
 drivers/platform/goldfish/goldfish_pipe.c | 66 +++++++++++++----------
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index 53832e46ad1a..c68035be4389 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -202,6 +202,9 @@ struct goldfish_pipe {
  * waiting to be awoken.
  */
 struct goldfish_pipe_dev {
+       /* A magic number to check if this is an instance of this struct */
+       void *magic;
+
        /*
         * Global device spinlock. Protects the following members:
         *  - pipes, pipes_capacity
@@ -251,8 +254,6 @@ struct goldfish_pipe_dev {
        size_t dma_alloc_total;
 };
 
-struct goldfish_pipe_dev goldfish_pipe_dev;
-
 static int goldfish_pipe_cmd_locked(struct goldfish_pipe *pipe,
                                    enum PipeCmdCode cmd)
 {
@@ -647,6 +648,9 @@ static void goldfish_interrupt_task(unsigned long dev_addr)
        }
 }
 
+static void goldfish_pipe_device_deinit(struct platform_device *pdev,
+                                       struct goldfish_pipe_dev *dev);
+
 /*
  * The general idea of the interrupt handling:
  *
@@ -667,7 +671,7 @@ static irqreturn_t goldfish_pipe_interrupt(int irq, void 
*dev_id)
        unsigned long flags;
        struct goldfish_pipe_dev *dev = dev_id;
 
-       if (dev != &goldfish_pipe_dev)
+       if (dev->magic != &goldfish_pipe_device_deinit)
                return IRQ_NONE;
 
        /* Request the signalled pipes from the device */
@@ -719,6 +723,14 @@ static int get_free_pipe_id_locked(struct 
goldfish_pipe_dev *dev)
        return id;
 }
 
+/* A helper function to get the instance of goldfish_pipe_dev from file */
+static struct goldfish_pipe_dev *to_goldfish_pipe_dev(struct file *file)
+{
+       struct miscdevice *miscdev = file->private_data;
+
+       return container_of(miscdev, struct goldfish_pipe_dev, miscdev);
+}
+
 /**
  *     goldfish_pipe_open - open a channel to the AVD
  *     @inode: inode of device
@@ -732,7 +744,7 @@ static int get_free_pipe_id_locked(struct goldfish_pipe_dev 
*dev)
  */
 static int goldfish_pipe_open(struct inode *inode, struct file *file)
 {
-       struct goldfish_pipe_dev *dev = &goldfish_pipe_dev;
+       struct goldfish_pipe_dev *dev = to_goldfish_pipe_dev(file);
        unsigned long flags;
        int id;
        int status;
@@ -1112,9 +1124,9 @@ static void write_pa_addr(void *addr, void __iomem 
*portl, void __iomem *porth)
        writel(lower_32_bits(paddr), portl);
 }
 
-static int goldfish_pipe_device_init(struct platform_device *pdev)
+static int goldfish_pipe_device_init(struct platform_device *pdev,
+                                    struct goldfish_pipe_dev *dev)
 {
-       struct goldfish_pipe_dev *dev = &goldfish_pipe_dev;
        int err;
 
        tasklet_init(&dev->irq_tasklet, &goldfish_interrupt_task,
@@ -1169,26 +1181,29 @@ static int goldfish_pipe_device_init(struct 
platform_device *pdev)
                      dev->base + PIPE_REG_OPEN_BUFFER,
                      dev->base + PIPE_REG_OPEN_BUFFER_HIGH);
 
+       platform_set_drvdata(pdev, dev);
        return 0;
 }
 
-static void goldfish_pipe_device_deinit(struct platform_device *pdev)
+static void goldfish_pipe_device_deinit(struct platform_device *pdev,
+                                       struct goldfish_pipe_dev *dev)
 {
-       misc_deregister(&goldfish_pipe_dev.miscdev);
-       tasklet_kill(&goldfish_pipe_dev.irq_tasklet);
-       kfree(goldfish_pipe_dev.pipes);
-       free_page((unsigned long)goldfish_pipe_dev.buffers);
+       misc_deregister(&dev->miscdev);
+       tasklet_kill(&dev->irq_tasklet);
+       kfree(dev->pipes);
+       free_page((unsigned long)dev->buffers);
 }
 
 static int goldfish_pipe_probe(struct platform_device *pdev)
 {
-       int err;
        struct resource *r;
-       struct goldfish_pipe_dev *dev = &goldfish_pipe_dev;
+       struct goldfish_pipe_dev *dev;
 
-       /* not thread safe, but this should not happen */
-       WARN_ON(dev->base);
+       dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
 
+       dev->magic = &goldfish_pipe_device_deinit;
        spin_lock_init(&dev->lock);
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1203,10 +1218,9 @@ static int goldfish_pipe_probe(struct platform_device 
*pdev)
        }
 
        r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!r) {
-               err = -EINVAL;
-               goto error;
-       }
+       if (!r)
+               return -EINVAL;
+
        dev->irq = r->start;
 
        /*
@@ -1221,20 +1235,14 @@ static int goldfish_pipe_probe(struct platform_device 
*pdev)
        if (WARN_ON(dev->version < PIPE_CURRENT_DEVICE_VERSION))
                return -EINVAL;
 
-       err = goldfish_pipe_device_init(pdev);
-       if (!err)
-               return 0;
-
-error:
-       dev->base = NULL;
-       return err;
+       return goldfish_pipe_device_init(pdev, dev);
 }
 
 static int goldfish_pipe_remove(struct platform_device *pdev)
 {
-       struct goldfish_pipe_dev *dev = &goldfish_pipe_dev;
-       goldfish_pipe_device_deinit(pdev);
-       dev->base = NULL;
+       struct goldfish_pipe_dev *dev = platform_get_drvdata(pdev);
+
+       goldfish_pipe_device_deinit(pdev, dev);
        return 0;
 }
 
-- 
2.19.0.397.gdd90340f6a-goog

Reply via email to