Commit 08360e26 authored by Roman Kiryanov's avatar Roman Kiryanov Committed by Greg Kroah-Hartman

platform: goldfish: pipe: Move the file-scope goldfish_pipe_dev variable into the driver state

This is the last patch in the series of patches to move file-scope
variables into the driver state. This change will help to introduce
another version of the pipe driver (with different state) for the
older host interface or having several instances of this device.
Signed-off-by: default avatarRoman Kiryanov <rkir@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 43c2cc28
......@@ -169,6 +169,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
......@@ -215,8 +218,6 @@ struct goldfish_pipe_dev {
struct miscdevice miscdev;
};
static struct goldfish_pipe_dev goldfish_pipe_dev;
static int goldfish_pipe_cmd_locked(struct goldfish_pipe *pipe,
enum PipeCmdCode cmd)
{
......@@ -611,6 +612,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:
*
......@@ -631,7 +635,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 */
......@@ -683,6 +687,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
......@@ -696,7 +708,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;
......@@ -804,9 +816,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,
......@@ -861,26 +873,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);
......@@ -895,10 +910,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;
/*
......@@ -913,20 +927,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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment