goldfish patches
diff --git a/0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch b/0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch
new file mode 100644
index 0000000..248bf0a
--- /dev/null
+++ b/0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch
@@ -0,0 +1,1927 @@
+From c53b6059ba261505317a4d8de63832846c9c92fb Mon Sep 17 00:00:00 2001
+From: Jin Qian <jinqian@android.com>
+Date: Mon, 27 Feb 2017 12:06:21 -0800
+Subject: [PATCH 1/3] goldfish_pipe: An implementation of more parallel pipe
+
+This is a driver code for a redesigned android pipe.
+Currently it works for x86 and x64 emulators with the following
+performance results:
+  ADB push to /dev/null,
+  Ubuntu,
+  400 MB file,
+  times are for (1 / 10 / 100) parallel adb commands
+x86 adb push: (4.4s / 11.5s / 2m10s) -> (2.8s / 6s / 51s)
+x64 adb push: (7s / 15s / (too long, 6m+) -> (2.7s / 6.2s / 52s)
+
+ADB pull and push to /data/ have the same %% of speedup
+More importantly, I don't see any signs of slowdowns when
+run in parallel with Antutu benchmark, so it is definitely
+making much better job at multithreading.
+
+Signed-off-by: Yurii Zubrytskyi <zyy@google.com>
+Signed-off-by: Jin Qian <jinqian@android.com>
+---
+ drivers/platform/goldfish/goldfish_pipe.c        |  976 +++++++++++++++--------
+ drivers/platform/goldfish/goldfish_pipe_legacy.c |  671 +++++++++++++++
+ 2 files changed, 1315 insertions(+), 332 deletions(-)
+ create mode 100644 drivers/platform/goldfish/goldfish_pipe_legacy.c
+
+--- a/drivers/platform/goldfish/goldfish_pipe.c
++++ b/drivers/platform/goldfish/goldfish_pipe.c
+@@ -1,8 +1,8 @@
+ /*
+- * Copyright (C) 2011 Google, Inc.
+  * Copyright (C) 2012 Intel, Inc.
+  * Copyright (C) 2013 Intel, Inc.
+  * Copyright (C) 2014 Linaro Limited
++ * Copyright (C) 2011-2016 Google, Inc.
+  *
+  * This software is licensed under the terms of the GNU General Public
+  * License version 2, as published by the Free Software Foundation, and
+@@ -46,6 +46,7 @@
+  * exchange is properly mapped during a transfer.
+  */
+ 
++
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+@@ -63,122 +64,232 @@
+ #include <linux/acpi.h>
+ 
+ /*
++ * Update this when something changes in the driver's behavior so the host
++ * can benefit from knowing it
++ */
++enum {
++	PIPE_DRIVER_VERSION = 2,
++	PIPE_CURRENT_DEVICE_VERSION = 2
++};
++
++/*
+  * IMPORTANT: The following constants must match the ones used and defined
+  * in external/qemu/hw/goldfish_pipe.c in the Android source tree.
+  */
+ 
+-/* pipe device registers */
+-#define PIPE_REG_COMMAND		0x00  /* write: value = command */
+-#define PIPE_REG_STATUS			0x04  /* read */
+-#define PIPE_REG_CHANNEL		0x08  /* read/write: channel id */
+-#define PIPE_REG_CHANNEL_HIGH	        0x30  /* read/write: channel id */
+-#define PIPE_REG_SIZE			0x0c  /* read/write: buffer size */
+-#define PIPE_REG_ADDRESS		0x10  /* write: physical address */
+-#define PIPE_REG_ADDRESS_HIGH	        0x34  /* write: physical address */
+-#define PIPE_REG_WAKES			0x14  /* read: wake flags */
+-#define PIPE_REG_PARAMS_ADDR_LOW	0x18  /* read/write: batch data address */
+-#define PIPE_REG_PARAMS_ADDR_HIGH	0x1c  /* read/write: batch data address */
+-#define PIPE_REG_ACCESS_PARAMS		0x20  /* write: batch access */
+-#define PIPE_REG_VERSION		0x24  /* read: device version */
+-
+-/* list of commands for PIPE_REG_COMMAND */
+-#define CMD_OPEN			1  /* open new channel */
+-#define CMD_CLOSE			2  /* close channel (from guest) */
+-#define CMD_POLL			3  /* poll read/write status */
+-
+ /* List of bitflags returned in status of CMD_POLL command */
+-#define PIPE_POLL_IN			(1 << 0)
+-#define PIPE_POLL_OUT			(1 << 1)
+-#define PIPE_POLL_HUP			(1 << 2)
+-
+-/* The following commands are related to write operations */
+-#define CMD_WRITE_BUFFER	4  /* send a user buffer to the emulator */
+-#define CMD_WAKE_ON_WRITE	5  /* tell the emulator to wake us when writing
+-				     is possible */
+-#define CMD_READ_BUFFER        6  /* receive a user buffer from the emulator */
+-#define CMD_WAKE_ON_READ       7  /* tell the emulator to wake us when reading
+-				   * is possible */
++enum PipePollFlags {
++	PIPE_POLL_IN	= 1 << 0,
++	PIPE_POLL_OUT	= 1 << 1,
++	PIPE_POLL_HUP	= 1 << 2
++};
+ 
+ /* Possible status values used to signal errors - see goldfish_pipe_error_convert */
+-#define PIPE_ERROR_INVAL       -1
+-#define PIPE_ERROR_AGAIN       -2
+-#define PIPE_ERROR_NOMEM       -3
+-#define PIPE_ERROR_IO          -4
++enum PipeErrors {
++	PIPE_ERROR_INVAL  = -1,
++	PIPE_ERROR_AGAIN  = -2,
++	PIPE_ERROR_NOMEM  = -3,
++	PIPE_ERROR_IO     = -4
++};
+ 
+ /* Bit-flags used to signal events from the emulator */
+-#define PIPE_WAKE_CLOSED       (1 << 0)  /* emulator closed pipe */
+-#define PIPE_WAKE_READ         (1 << 1)  /* pipe can now be read from */
+-#define PIPE_WAKE_WRITE        (1 << 2)  /* pipe can now be written to */
+-
+-struct access_params {
+-	unsigned long channel;
+-	u32 size;
+-	unsigned long address;
+-	u32 cmd;
+-	u32 result;
+-	/* reserved for future extension */
++enum PipeWakeFlags {
++	PIPE_WAKE_CLOSED = 1 << 0,  /* emulator closed pipe */
++	PIPE_WAKE_READ   = 1 << 1,  /* pipe can now be read from */
++	PIPE_WAKE_WRITE  = 1 << 2  /* pipe can now be written to */
++};
++
++/* Bit flags for the 'flags' field */
++enum PipeFlagsBits {
++	BIT_CLOSED_ON_HOST = 0,  /* pipe closed by host */
++	BIT_WAKE_ON_WRITE  = 1,  /* want to be woken on writes */
++	BIT_WAKE_ON_READ   = 2,  /* want to be woken on reads */
++};
++
++enum PipeRegs {
++	PIPE_REG_CMD = 0,
++
++	PIPE_REG_SIGNAL_BUFFER_HIGH = 4,
++	PIPE_REG_SIGNAL_BUFFER = 8,
++	PIPE_REG_SIGNAL_BUFFER_COUNT = 12,
++
++	PIPE_REG_OPEN_BUFFER_HIGH = 20,
++	PIPE_REG_OPEN_BUFFER = 24,
++
++	PIPE_REG_VERSION = 36,
++
++	PIPE_REG_GET_SIGNALLED = 48,
++};
++
++enum PipeCmdCode {
++	PIPE_CMD_OPEN = 1,	/* to be used by the pipe device itself */
++	PIPE_CMD_CLOSE,
++	PIPE_CMD_POLL,
++	PIPE_CMD_WRITE,
++	PIPE_CMD_WAKE_ON_WRITE,
++	PIPE_CMD_READ,
++	PIPE_CMD_WAKE_ON_READ,
++
++	/*
++	 * TODO(zyy): implement a deferred read/write execution to allow
++	 * parallel processing of pipe operations on the host.
++	 */
++	PIPE_CMD_WAKE_ON_DONE_IO,
++};
++
++enum {
++	MAX_BUFFERS_PER_COMMAND = 336,
++	MAX_SIGNALLED_PIPES = 64,
++	INITIAL_PIPES_CAPACITY = 64
++};
++
++struct goldfish_pipe_dev;
++struct goldfish_pipe;
++struct goldfish_pipe_command;
++
++/* A per-pipe command structure, shared with the host */
++struct goldfish_pipe_command {
++	s32 cmd;		/* PipeCmdCode, guest -> host */
++	s32 id;			/* pipe id, guest -> host */
++	s32 status;		/* command execution status, host -> guest */
++	s32 reserved;	/* to pad to 64-bit boundary */
++	union {
++		/* Parameters for PIPE_CMD_{READ,WRITE} */
++		struct {
++			/* number of buffers, guest -> host */
++			u32 buffers_count;
++			/* number of consumed bytes, host -> guest */
++			s32 consumed_size;
++			/* buffer pointers, guest -> host */
++			u64 ptrs[MAX_BUFFERS_PER_COMMAND];
++			/* buffer sizes, guest -> host */
++			u32 sizes[MAX_BUFFERS_PER_COMMAND];
++		} rw_params;
++	};
++};
++
++/* A single signalled pipe information */
++struct signalled_pipe_buffer {
++	u32 id;
+ 	u32 flags;
+ };
+ 
+-/* The global driver data. Holds a reference to the i/o page used to
+- * communicate with the emulator, and a wake queue for blocked tasks
+- * waiting to be awoken.
+- */
+-struct goldfish_pipe_dev {
+-	spinlock_t lock;
+-	unsigned char __iomem *base;
+-	struct access_params *aps;
+-	int irq;
+-	u32 version;
++/* Parameters for the PIPE_CMD_OPEN command */
++struct open_command_param {
++	u64 command_buffer_ptr;
++	u32 rw_params_max_count;
+ };
+ 
+-static struct goldfish_pipe_dev   pipe_dev[1];
++/* Device-level set of buffers shared with the host */
++struct goldfish_pipe_dev_buffers {
++	struct open_command_param open_command_params;
++	struct signalled_pipe_buffer signalled_pipe_buffers[
++		MAX_SIGNALLED_PIPES];
++};
+ 
+ /* This data type models a given pipe instance */
+ struct goldfish_pipe {
+-	struct goldfish_pipe_dev *dev;
+-	struct mutex lock;
++	/* pipe ID - index into goldfish_pipe_dev::pipes array */
++	u32 id;
++	/* The wake flags pipe is waiting for
++	 * Note: not protected with any lock, uses atomic operations
++	 *  and barriers to make it thread-safe.
++	 */
+ 	unsigned long flags;
++	/* wake flags host have signalled,
++	 *  - protected by goldfish_pipe_dev::lock
++	 */
++	unsigned long signalled_flags;
++
++	/* A pointer to command buffer */
++	struct goldfish_pipe_command *command_buffer;
++
++	/* doubly linked list of signalled pipes, protected by
++	 * goldfish_pipe_dev::lock
++	 */
++	struct goldfish_pipe *prev_signalled;
++	struct goldfish_pipe *next_signalled;
++
++	/*
++	 * A pipe's own lock. Protects the following:
++	 *  - *command_buffer - makes sure a command can safely write its
++	 *    parameters to the host and read the results back.
++	 */
++	struct mutex lock;
++
++	/* A wake queue for sleeping until host signals an event */
+ 	wait_queue_head_t wake_queue;
++	/* Pointer to the parent goldfish_pipe_dev instance */
++	struct goldfish_pipe_dev *dev;
+ };
+ 
++/* The global driver data. Holds a reference to the i/o page used to
++ * communicate with the emulator, and a wake queue for blocked tasks
++ * waiting to be awoken.
++ */
++struct goldfish_pipe_dev {
++	/*
++	 * Global device spinlock. Protects the following members:
++	 *  - pipes, pipes_capacity
++	 *  - [*pipes, *pipes + pipes_capacity) - array data
++	 *  - first_signalled_pipe,
++	 *      goldfish_pipe::prev_signalled,
++	 *      goldfish_pipe::next_signalled,
++	 *      goldfish_pipe::signalled_flags - all singnalled-related fields,
++	 *                                       in all allocated pipes
++	 *  - open_command_params - PIPE_CMD_OPEN-related buffers
++	 *
++	 * It looks like a lot of different fields, but the trick is that
++	 * the only operation that happens often is the signalled pipes array
++	 * manipulation. That's why it's OK for now to keep the rest of the
++	 * fields under the same lock. If we notice too much contention because
++	 * of PIPE_CMD_OPEN, then we should add a separate lock there.
++	 */
++	spinlock_t lock;
+ 
+-/* Bit flags for the 'flags' field */
+-enum {
+-	BIT_CLOSED_ON_HOST = 0,  /* pipe closed by host */
+-	BIT_WAKE_ON_WRITE  = 1,  /* want to be woken on writes */
+-	BIT_WAKE_ON_READ   = 2,  /* want to be woken on reads */
++	/*
++	 * Array of the pipes of |pipes_capacity| elements,
++	 * indexed by goldfish_pipe::id
++	 */
++	struct goldfish_pipe **pipes;
++	u32 pipes_capacity;
++
++	/* Pointers to the buffers host uses for interaction with this driver */
++	struct goldfish_pipe_dev_buffers *buffers;
++
++	/* Head of a doubly linked list of signalled pipes */
++	struct goldfish_pipe *first_signalled_pipe;
++
++	/* Some device-specific data */
++	int irq;
++	int version;
++	unsigned char __iomem *base;
+ };
+ 
++struct goldfish_pipe_dev pipe_dev[1] = {};
+ 
+-static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)
++static int goldfish_cmd_locked(struct goldfish_pipe *pipe, enum PipeCmdCode cmd)
+ {
+-	unsigned long flags;
+-	u32 status;
+-	struct goldfish_pipe_dev *dev = pipe->dev;
+-
+-	spin_lock_irqsave(&dev->lock, flags);
+-	gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
+-		     dev->base + PIPE_REG_CHANNEL_HIGH);
+-	writel(cmd, dev->base + PIPE_REG_COMMAND);
+-	status = readl(dev->base + PIPE_REG_STATUS);
+-	spin_unlock_irqrestore(&dev->lock, flags);
+-	return status;
++	pipe->command_buffer->cmd = cmd;
++	/* failure by default */
++	pipe->command_buffer->status = PIPE_ERROR_INVAL;
++	writel(pipe->id, pipe->dev->base + PIPE_REG_CMD);
++	return pipe->command_buffer->status;
+ }
+ 
+-static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)
++static int goldfish_cmd(struct goldfish_pipe *pipe, enum PipeCmdCode cmd)
+ {
+-	unsigned long flags;
+-	struct goldfish_pipe_dev *dev = pipe->dev;
++	int status;
+ 
+-	spin_lock_irqsave(&dev->lock, flags);
+-	gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
+-		     dev->base + PIPE_REG_CHANNEL_HIGH);
+-	writel(cmd, dev->base + PIPE_REG_COMMAND);
+-	spin_unlock_irqrestore(&dev->lock, flags);
++	if (mutex_lock_interruptible(&pipe->lock))
++		return PIPE_ERROR_IO;
++	status = goldfish_cmd_locked(pipe, cmd);
++	mutex_unlock(&pipe->lock);
++	return status;
+ }
+ 
+-/* This function converts an error code returned by the emulator through
++/*
++ * This function converts an error code returned by the emulator through
+  * the PIPE_REG_STATUS i/o register into a valid negative errno value.
+  */
+ static int goldfish_pipe_error_convert(int status)
+@@ -195,184 +306,202 @@ static int goldfish_pipe_error_convert(i
+ 	}
+ }
+ 
+-/*
+- * Notice: QEMU will return 0 for un-known register access, indicating
+- * param_acess is supported or not
+- */
+-static int valid_batchbuffer_addr(struct goldfish_pipe_dev *dev,
+-				  struct access_params *aps)
++static int pin_user_pages(unsigned long first_page, unsigned long last_page,
++	unsigned int last_page_size, int is_write,
++	struct page *pages[MAX_BUFFERS_PER_COMMAND],
++	unsigned int *iter_last_page_size)
++{
++	int ret;
++	int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1;
++
++	if (requested_pages > MAX_BUFFERS_PER_COMMAND) {
++		requested_pages = MAX_BUFFERS_PER_COMMAND;
++		*iter_last_page_size = PAGE_SIZE;
++	} else {
++		*iter_last_page_size = last_page_size;
++	}
++
++	ret = get_user_pages_fast(
++			first_page, requested_pages, !is_write, pages);
++	if (ret <= 0)
++		return -EFAULT;
++	if (ret < requested_pages)
++		*iter_last_page_size = PAGE_SIZE;
++	return ret;
++
++}
++
++static void release_user_pages(struct page **pages, int pages_count,
++	int is_write, s32 consumed_size)
+ {
+-	u32 aph, apl;
+-	u64 paddr;
+-	aph = readl(dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
+-	apl = readl(dev->base + PIPE_REG_PARAMS_ADDR_LOW);
++	int i;
+ 
+-	paddr = ((u64)aph << 32) | apl;
+-	if (paddr != (__pa(aps)))
+-		return 0;
+-	return 1;
++	for (i = 0; i < pages_count; i++) {
++		if (!is_write && consumed_size > 0)
++			set_page_dirty(pages[i]);
++		put_page(pages[i]);
++	}
++}
++
++/* Populate the call parameters, merging adjacent pages together */
++static void populate_rw_params(
++	struct page **pages, int pages_count,
++	unsigned long address, unsigned long address_end,
++	unsigned long first_page, unsigned long last_page,
++	unsigned int iter_last_page_size, int is_write,
++	struct goldfish_pipe_command *command)
++{
++	/*
++	 * Process the first page separately - it's the only page that
++	 * needs special handling for its start address.
++	 */
++	unsigned long xaddr = page_to_phys(pages[0]);
++	unsigned long xaddr_prev = xaddr;
++	int buffer_idx = 0;
++	int i = 1;
++	int size_on_page = first_page == last_page
++			? (int)(address_end - address)
++			: (PAGE_SIZE - (address & ~PAGE_MASK));
++	command->rw_params.ptrs[0] = (u64)(xaddr | (address & ~PAGE_MASK));
++	command->rw_params.sizes[0] = size_on_page;
++	for (; i < pages_count; ++i) {
++		xaddr = page_to_phys(pages[i]);
++		size_on_page = (i == pages_count - 1) ?
++			iter_last_page_size : PAGE_SIZE;
++		if (xaddr == xaddr_prev + PAGE_SIZE) {
++			command->rw_params.sizes[buffer_idx] += size_on_page;
++		} else {
++			++buffer_idx;
++			command->rw_params.ptrs[buffer_idx] = (u64)xaddr;
++			command->rw_params.sizes[buffer_idx] = size_on_page;
++		}
++		xaddr_prev = xaddr;
++	}
++	command->rw_params.buffers_count = buffer_idx + 1;
+ }
+ 
+-/* 0 on success */
+-static int setup_access_params_addr(struct platform_device *pdev,
+-					struct goldfish_pipe_dev *dev)
++static int transfer_max_buffers(struct goldfish_pipe *pipe,
++	unsigned long address, unsigned long address_end, int is_write,
++	unsigned long last_page, unsigned int last_page_size,
++	s32 *consumed_size, int *status)
+ {
+-	dma_addr_t dma_handle;
+-	struct access_params *aps;
++	struct page *pages[MAX_BUFFERS_PER_COMMAND];
++	unsigned long first_page = address & PAGE_MASK;
++	unsigned int iter_last_page_size;
++	int pages_count = pin_user_pages(first_page, last_page,
++			last_page_size, is_write,
++			pages, &iter_last_page_size);
+ 
+-	aps = dmam_alloc_coherent(&pdev->dev, sizeof(struct access_params),
+-				  &dma_handle, GFP_KERNEL);
+-	if (!aps)
+-		return -ENOMEM;
++	if (pages_count < 0)
++		return pages_count;
+ 
+-	writel(upper_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
+-	writel(lower_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_LOW);
++	/* Serialize access to the pipe command buffers */
++	if (mutex_lock_interruptible(&pipe->lock))
++		return -ERESTARTSYS;
+ 
+-	if (valid_batchbuffer_addr(dev, aps)) {
+-		dev->aps = aps;
+-		return 0;
+-	} else
+-		return -1;
++	populate_rw_params(pages, pages_count, address, address_end,
++		first_page, last_page, iter_last_page_size, is_write,
++		pipe->command_buffer);
++
++	/* Transfer the data */
++	*status = goldfish_cmd_locked(pipe,
++				is_write ? PIPE_CMD_WRITE : PIPE_CMD_READ);
++
++	*consumed_size = pipe->command_buffer->rw_params.consumed_size;
++
++	mutex_unlock(&pipe->lock);
++
++	release_user_pages(pages, pages_count, is_write, *consumed_size);
++
++	return 0;
+ }
+ 
+-/* A value that will not be set by qemu emulator */
+-#define INITIAL_BATCH_RESULT (0xdeadbeaf)
+-static int access_with_param(struct goldfish_pipe_dev *dev, const int cmd,
+-				unsigned long address, unsigned long avail,
+-				struct goldfish_pipe *pipe, int *status)
+-{
+-	struct access_params *aps = dev->aps;
+-
+-	if (aps == NULL)
+-		return -1;
+-
+-	aps->result = INITIAL_BATCH_RESULT;
+-	aps->channel = (unsigned long)pipe;
+-	aps->size = avail;
+-	aps->address = address;
+-	aps->cmd = cmd;
+-	writel(cmd, dev->base + PIPE_REG_ACCESS_PARAMS);
+-	/*
+-	 * If the aps->result has not changed, that means
+-	 * that the batch command failed
+-	 */
+-	if (aps->result == INITIAL_BATCH_RESULT)
+-		return -1;
+-	*status = aps->result;
++static int wait_for_host_signal(struct goldfish_pipe *pipe, int is_write)
++{
++	u32 wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ;
++
++	set_bit(wakeBit, &pipe->flags);
++
++	/* Tell the emulator we're going to wait for a wake event */
++	(void)goldfish_cmd(pipe,
++		is_write ? PIPE_CMD_WAKE_ON_WRITE : PIPE_CMD_WAKE_ON_READ);
++
++	while (test_bit(wakeBit, &pipe->flags)) {
++		if (wait_event_interruptible(
++				pipe->wake_queue,
++				!test_bit(wakeBit, &pipe->flags)))
++			return -ERESTARTSYS;
++
++		if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
++			return -EIO;
++	}
++
+ 	return 0;
+ }
+ 
+-static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
+-				       size_t bufflen, int is_write)
++static ssize_t goldfish_pipe_read_write(struct file *filp,
++	char __user *buffer, size_t bufflen, int is_write)
+ {
+-	unsigned long irq_flags;
+ 	struct goldfish_pipe *pipe = filp->private_data;
+-	struct goldfish_pipe_dev *dev = pipe->dev;
+-	unsigned long address, address_end;
+ 	int count = 0, ret = -EINVAL;
++	unsigned long address, address_end, last_page;
++	unsigned int last_page_size;
+ 
+ 	/* If the emulator already closed the pipe, no need to go further */
+-	if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
++	if (unlikely(test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)))
+ 		return -EIO;
+-
+ 	/* Null reads or writes succeeds */
+ 	if (unlikely(bufflen == 0))
+ 		return 0;
+-
+ 	/* Check the buffer range for access */
+-	if (!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ,
+-			buffer, bufflen))
++	if (unlikely(!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ,
++			buffer, bufflen)))
+ 		return -EFAULT;
+ 
+-	/* Serialize access to the pipe */
+-	if (mutex_lock_interruptible(&pipe->lock))
+-		return -ERESTARTSYS;
+-
+-	address = (unsigned long)(void *)buffer;
++	address = (unsigned long)buffer;
+ 	address_end = address + bufflen;
++	last_page = (address_end - 1) & PAGE_MASK;
++	last_page_size = ((address_end - 1) & ~PAGE_MASK) + 1;
+ 
+ 	while (address < address_end) {
+-		unsigned long page_end = (address & PAGE_MASK) + PAGE_SIZE;
+-		unsigned long next     = page_end < address_end ? page_end
+-								: address_end;
+-		unsigned long avail    = next - address;
+-		int status, wakeBit;
+-		struct page *page;
+-
+-		/* Either vaddr or paddr depending on the device version */
+-		unsigned long xaddr;
++		s32 consumed_size;
++		int status;
+ 
+-		/*
+-		 * We grab the pages on a page-by-page basis in case user
+-		 * space gives us a potentially huge buffer but the read only
+-		 * returns a small amount, then there's no need to pin that
+-		 * much memory to the process.
+-		 */
+-		ret = get_user_pages_unlocked(address, 1, &page,
+-				is_write ? 0 : FOLL_WRITE);
++		ret = transfer_max_buffers(pipe, address, address_end, is_write,
++				last_page, last_page_size, &consumed_size,
++				&status);
+ 		if (ret < 0)
+ 			break;
+ 
+-		if (dev->version) {
+-			/* Device version 1 or newer (qemu-android) expects the
+-			 * physical address.
++		if (consumed_size > 0) {
++			/* No matter what's the status, we've transferred
++			 * something.
+ 			 */
+-			xaddr = page_to_phys(page) | (address & ~PAGE_MASK);
+-		} else {
+-			/* Device version 0 (classic emulator) expects the
+-			 * virtual address.
+-			 */
+-			xaddr = address;
++			count += consumed_size;
++			address += consumed_size;
+ 		}
+-
+-		/* Now, try to transfer the bytes in the current page */
+-		spin_lock_irqsave(&dev->lock, irq_flags);
+-		if (access_with_param(dev,
+-				is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
+-				xaddr, avail, pipe, &status)) {
+-			gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
+-				     dev->base + PIPE_REG_CHANNEL_HIGH);
+-			writel(avail, dev->base + PIPE_REG_SIZE);
+-			gf_write_ptr((void *)xaddr,
+-				     dev->base + PIPE_REG_ADDRESS,
+-				     dev->base + PIPE_REG_ADDRESS_HIGH);
+-			writel(is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
+-					dev->base + PIPE_REG_COMMAND);
+-			status = readl(dev->base + PIPE_REG_STATUS);
+-		}
+-		spin_unlock_irqrestore(&dev->lock, irq_flags);
+-
+-		if (status > 0 && !is_write)
+-			set_page_dirty(page);
+-		put_page(page);
+-
+-		if (status > 0) { /* Correct transfer */
+-			count += status;
+-			address += status;
++		if (status > 0)
+ 			continue;
+-		} else if (status == 0) { /* EOF */
++		if (status == 0) {
++			/* EOF */
+ 			ret = 0;
+ 			break;
+-		} else if (status < 0 && count > 0) {
++		}
++		if (count > 0) {
+ 			/*
+-			 * An error occurred and we already transferred
+-			 * something on one of the previous pages.
++			 * An error occurred, but we already transferred
++			 * something on one of the previous iterations.
+ 			 * Just return what we already copied and log this
+ 			 * err.
+-			 *
+-			 * Note: This seems like an incorrect approach but
+-			 * cannot change it until we check if any user space
+-			 * ABI relies on this behavior.
+ 			 */
+ 			if (status != PIPE_ERROR_AGAIN)
+-				pr_info_ratelimited("goldfish_pipe: backend returned error %d on %s\n",
++				pr_info_ratelimited("goldfish_pipe: backend error %d on %s\n",
+ 					status, is_write ? "write" : "read");
+-			ret = 0;
+ 			break;
+ 		}
+ 
+ 		/*
+-		 * If the error is not PIPE_ERROR_AGAIN, or if we are not in
++		 * If the error is not PIPE_ERROR_AGAIN, or if we are in
+ 		 * non-blocking mode, just return the error code.
+ 		 */
+ 		if (status != PIPE_ERROR_AGAIN ||
+@@ -381,139 +510,214 @@ static ssize_t goldfish_pipe_read_write(
+ 			break;
+ 		}
+ 
+-		/*
+-		 * The backend blocked the read/write, wait until the backend
+-		 * tells us it's ready to process more data.
+-		 */
+-		wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ;
+-		set_bit(wakeBit, &pipe->flags);
+-
+-		/* Tell the emulator we're going to wait for a wake event */
+-		goldfish_cmd(pipe,
+-			is_write ? CMD_WAKE_ON_WRITE : CMD_WAKE_ON_READ);
+-
+-		/* Unlock the pipe, then wait for the wake signal */
+-		mutex_unlock(&pipe->lock);
+-
+-		while (test_bit(wakeBit, &pipe->flags)) {
+-			if (wait_event_interruptible(
+-					pipe->wake_queue,
+-					!test_bit(wakeBit, &pipe->flags)))
+-				return -ERESTARTSYS;
+-
+-			if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
+-				return -EIO;
+-		}
+-
+-		/* Try to re-acquire the lock */
+-		if (mutex_lock_interruptible(&pipe->lock))
+-			return -ERESTARTSYS;
++		status = wait_for_host_signal(pipe, is_write);
++		if (status < 0)
++			return status;
+ 	}
+-	mutex_unlock(&pipe->lock);
+ 
+-	if (ret < 0)
+-		return ret;
+-	else
++	if (count > 0)
+ 		return count;
++	return ret;
+ }
+ 
+ static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer,
+-			      size_t bufflen, loff_t *ppos)
++				size_t bufflen, loff_t *ppos)
+ {
+-	return goldfish_pipe_read_write(filp, buffer, bufflen, 0);
++	return goldfish_pipe_read_write(filp, buffer, bufflen,
++			/* is_write */ 0);
+ }
+ 
+ static ssize_t goldfish_pipe_write(struct file *filp,
+ 				const char __user *buffer, size_t bufflen,
+ 				loff_t *ppos)
+ {
+-	return goldfish_pipe_read_write(filp, (char __user *)buffer,
+-								bufflen, 1);
++	return goldfish_pipe_read_write(filp,
++			/* cast away the const */(char __user *)buffer, bufflen,
++			/* is_write */ 1);
+ }
+ 
+-
+ static unsigned int goldfish_pipe_poll(struct file *filp, poll_table *wait)
+ {
+ 	struct goldfish_pipe *pipe = filp->private_data;
+ 	unsigned int mask = 0;
+ 	int status;
+ 
+-	mutex_lock(&pipe->lock);
+-
+ 	poll_wait(filp, &pipe->wake_queue, wait);
+ 
+-	status = goldfish_cmd_status(pipe, CMD_POLL);
+-
+-	mutex_unlock(&pipe->lock);
++	status = goldfish_cmd(pipe, PIPE_CMD_POLL);
++	if (status < 0)
++		return -ERESTARTSYS;
+ 
+ 	if (status & PIPE_POLL_IN)
+ 		mask |= POLLIN | POLLRDNORM;
+-
+ 	if (status & PIPE_POLL_OUT)
+ 		mask |= POLLOUT | POLLWRNORM;
+-
+ 	if (status & PIPE_POLL_HUP)
+ 		mask |= POLLHUP;
+-
+ 	if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
+ 		mask |= POLLERR;
+ 
+ 	return mask;
+ }
+ 
+-static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id)
++static void signalled_pipes_add_locked(struct goldfish_pipe_dev *dev,
++	u32 id, u32 flags)
+ {
+-	struct goldfish_pipe_dev *dev = dev_id;
+-	unsigned long irq_flags;
+-	int count = 0;
++	struct goldfish_pipe *pipe;
+ 
+-	/*
+-	 * We're going to read from the emulator a list of (channel,flags)
+-	 * pairs corresponding to the wake events that occurred on each
+-	 * blocked pipe (i.e. channel).
+-	 */
+-	spin_lock_irqsave(&dev->lock, irq_flags);
+-	for (;;) {
+-		/* First read the channel, 0 means the end of the list */
+-		struct goldfish_pipe *pipe;
+-		unsigned long wakes;
+-		unsigned long channel = 0;
++	if (WARN_ON(id >= dev->pipes_capacity))
++		return;
+ 
+-#ifdef CONFIG_64BIT
+-		channel = (u64)readl(dev->base + PIPE_REG_CHANNEL_HIGH) << 32;
++	pipe = dev->pipes[id];
++	if (!pipe)
++		return;
++	pipe->signalled_flags |= flags;
++
++	if (pipe->prev_signalled || pipe->next_signalled
++		|| dev->first_signalled_pipe == pipe)
++		return;	/* already in the list */
++	pipe->next_signalled = dev->first_signalled_pipe;
++	if (dev->first_signalled_pipe)
++		dev->first_signalled_pipe->prev_signalled = pipe;
++	dev->first_signalled_pipe = pipe;
++}
++
++static void signalled_pipes_remove_locked(struct goldfish_pipe_dev *dev,
++	struct goldfish_pipe *pipe) {
++	if (pipe->prev_signalled)
++		pipe->prev_signalled->next_signalled = pipe->next_signalled;
++	if (pipe->next_signalled)
++		pipe->next_signalled->prev_signalled = pipe->prev_signalled;
++	if (pipe == dev->first_signalled_pipe)
++		dev->first_signalled_pipe = pipe->next_signalled;
++	pipe->prev_signalled = NULL;
++	pipe->next_signalled = NULL;
++}
+ 
+-		if (channel == 0)
+-			break;
+-#endif
+-		channel |= readl(dev->base + PIPE_REG_CHANNEL);
++static struct goldfish_pipe *signalled_pipes_pop_front(
++		struct goldfish_pipe_dev *dev, int *wakes)
++{
++	struct goldfish_pipe *pipe;
++	unsigned long flags;
+ 
+-		if (channel == 0)
+-			break;
++	spin_lock_irqsave(&dev->lock, flags);
+ 
+-		/* Convert channel to struct pipe pointer + read wake flags */
+-		wakes = readl(dev->base + PIPE_REG_WAKES);
+-		pipe  = (struct goldfish_pipe *)(ptrdiff_t)channel;
++	pipe = dev->first_signalled_pipe;
++	if (pipe) {
++		*wakes = pipe->signalled_flags;
++		pipe->signalled_flags = 0;
++		/*
++		 * This is an optimized version of
++		 * signalled_pipes_remove_locked()
++		 * - We want to make it as fast as possible to
++		 * wake the sleeping pipe operations faster.
++		 */
++		dev->first_signalled_pipe = pipe->next_signalled;
++		if (dev->first_signalled_pipe)
++			dev->first_signalled_pipe->prev_signalled = NULL;
++		pipe->next_signalled = NULL;
++	}
+ 
+-		/* Did the emulator just closed a pipe? */
++	spin_unlock_irqrestore(&dev->lock, flags);
++	return pipe;
++}
++
++static void goldfish_interrupt_task(unsigned long unused)
++{
++	struct goldfish_pipe_dev *dev = pipe_dev;
++	/* Iterate over the signalled pipes and wake them one by one */
++	struct goldfish_pipe *pipe;
++	int wakes;
++
++	while ((pipe = signalled_pipes_pop_front(dev, &wakes)) != NULL) {
+ 		if (wakes & PIPE_WAKE_CLOSED) {
+-			set_bit(BIT_CLOSED_ON_HOST, &pipe->flags);
+-			wakes |= PIPE_WAKE_READ | PIPE_WAKE_WRITE;
++			pipe->flags = 1 << BIT_CLOSED_ON_HOST;
++		} else {
++			if (wakes & PIPE_WAKE_READ)
++				clear_bit(BIT_WAKE_ON_READ, &pipe->flags);
++			if (wakes & PIPE_WAKE_WRITE)
++				clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags);
+ 		}
+-		if (wakes & PIPE_WAKE_READ)
+-			clear_bit(BIT_WAKE_ON_READ, &pipe->flags);
+-		if (wakes & PIPE_WAKE_WRITE)
+-			clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags);
+-
++		/*
++		 * wake_up_interruptible() implies a write barrier, so don't
++		 * explicitly add another one here.
++		 */
+ 		wake_up_interruptible(&pipe->wake_queue);
+-		count++;
+ 	}
+-	spin_unlock_irqrestore(&dev->lock, irq_flags);
++}
++DECLARE_TASKLET(goldfish_interrupt_tasklet, goldfish_interrupt_task, 0);
++
++/*
++ * The general idea of the interrupt handling:
++ *
++ *  1. device raises an interrupt if there's at least one signalled pipe
++ *  2. IRQ handler reads the signalled pipes and their count from the device
++ *  3. device writes them into a shared buffer and returns the count
++ *      it only resets the IRQ if it has returned all signalled pipes,
++ *      otherwise it leaves it raised, so IRQ handler will be called
++ *      again for the next chunk
++ *  4. IRQ handler adds all returned pipes to the device's signalled pipes list
++ *  5. IRQ handler launches a tasklet to process the signalled pipes from the
++ *      list in a separate context
++ */
++static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id)
++{
++	u32 count;
++	u32 i;
++	unsigned long flags;
++	struct goldfish_pipe_dev *dev = dev_id;
++
++	if (dev != pipe_dev)
++		return IRQ_NONE;
++
++	/* Request the signalled pipes from the device */
++	spin_lock_irqsave(&dev->lock, flags);
++
++	count = readl(dev->base + PIPE_REG_GET_SIGNALLED);
++	if (count == 0) {
++		spin_unlock_irqrestore(&dev->lock, flags);
++		return IRQ_NONE;
++	}
++	if (count > MAX_SIGNALLED_PIPES)
++		count = MAX_SIGNALLED_PIPES;
+ 
+-	return (count == 0) ? IRQ_NONE : IRQ_HANDLED;
++	for (i = 0; i < count; ++i)
++		signalled_pipes_add_locked(dev,
++			dev->buffers->signalled_pipe_buffers[i].id,
++			dev->buffers->signalled_pipe_buffers[i].flags);
++
++	spin_unlock_irqrestore(&dev->lock, flags);
++
++	tasklet_schedule(&goldfish_interrupt_tasklet);
++	return IRQ_HANDLED;
++}
++
++static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev)
++{
++	int id;
++
++	for (id = 0; id < dev->pipes_capacity; ++id)
++		if (!dev->pipes[id])
++			return id;
++
++	{
++		/* Reallocate the array */
++		u32 new_capacity = 2 * dev->pipes_capacity;
++		struct goldfish_pipe **pipes =
++			kcalloc(new_capacity, sizeof(*pipes), GFP_KERNEL);
++		if (!pipes)
++			return -ENOMEM;
++		memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity);
++		kfree(dev->pipes);
++		dev->pipes = pipes;
++		id = dev->pipes_capacity;
++		dev->pipes_capacity = new_capacity;
++	}
++	return id;
+ }
+ 
+ /**
+- *	goldfish_pipe_open	-	open a channel to the AVD
++ *	goldfish_pipe_open - open a channel to the AVD
+  *	@inode: inode of device
+  *	@file: file struct of opener
+  *
+@@ -525,12 +729,13 @@ static irqreturn_t goldfish_pipe_interru
+  */
+ static int goldfish_pipe_open(struct inode *inode, struct file *file)
+ {
+-	struct goldfish_pipe *pipe;
+ 	struct goldfish_pipe_dev *dev = pipe_dev;
+-	int32_t status;
++	unsigned long flags;
++	int id;
++	int status;
+ 
+ 	/* Allocate new pipe kernel object */
+-	pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
++	struct goldfish_pipe *pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
+ 	if (pipe == NULL)
+ 		return -ENOMEM;
+ 
+@@ -539,29 +744,69 @@ static int goldfish_pipe_open(struct ino
+ 	init_waitqueue_head(&pipe->wake_queue);
+ 
+ 	/*
+-	 * Now, tell the emulator we're opening a new pipe. We use the
+-	 * pipe object's address as the channel identifier for simplicity.
++	 * Command buffer needs to be allocated on its own page to make sure
++	 * it is physically contiguous in host's address space.
+ 	 */
++	pipe->command_buffer =
++		(struct goldfish_pipe_command *)__get_free_page(GFP_KERNEL);
++	if (!pipe->command_buffer) {
++		status = -ENOMEM;
++		goto err_pipe;
++	}
+ 
+-	status = goldfish_cmd_status(pipe, CMD_OPEN);
+-	if (status < 0) {
+-		kfree(pipe);
+-		return status;
++	spin_lock_irqsave(&dev->lock, flags);
++
++	id = get_free_pipe_id_locked(dev);
++	if (id < 0) {
++		status = id;
++		goto err_id_locked;
+ 	}
+ 
++	dev->pipes[id] = pipe;
++	pipe->id = id;
++	pipe->command_buffer->id = id;
++
++	/* Now tell the emulator we're opening a new pipe. */
++	dev->buffers->open_command_params.rw_params_max_count =
++			MAX_BUFFERS_PER_COMMAND;
++	dev->buffers->open_command_params.command_buffer_ptr =
++			(u64)(unsigned long)__pa(pipe->command_buffer);
++	status = goldfish_cmd_locked(pipe, PIPE_CMD_OPEN);
++	spin_unlock_irqrestore(&dev->lock, flags);
++	if (status < 0)
++		goto err_cmd;
+ 	/* All is done, save the pipe into the file's private data field */
+ 	file->private_data = pipe;
+ 	return 0;
++
++err_cmd:
++	spin_lock_irqsave(&dev->lock, flags);
++	dev->pipes[id] = NULL;
++err_id_locked:
++	spin_unlock_irqrestore(&dev->lock, flags);
++	free_page((unsigned long)pipe->command_buffer);
++err_pipe:
++	kfree(pipe);
++	return status;
+ }
+ 
+ static int goldfish_pipe_release(struct inode *inode, struct file *filp)
+ {
++	unsigned long flags;
+ 	struct goldfish_pipe *pipe = filp->private_data;
++	struct goldfish_pipe_dev *dev = pipe->dev;
+ 
+ 	/* The guest is closing the channel, so tell the emulator right now */
+-	goldfish_cmd(pipe, CMD_CLOSE);
+-	kfree(pipe);
++	(void)goldfish_cmd(pipe, PIPE_CMD_CLOSE);
++
++	spin_lock_irqsave(&dev->lock, flags);
++	dev->pipes[pipe->id] = NULL;
++	signalled_pipes_remove_locked(dev, pipe);
++	spin_unlock_irqrestore(&dev->lock, flags);
++
+ 	filp->private_data = NULL;
++	free_page((unsigned long)pipe->command_buffer);
++	kfree(pipe);
+ 	return 0;
+ }
+ 
+@@ -574,18 +819,91 @@ static const struct file_operations gold
+ 	.release = goldfish_pipe_release,
+ };
+ 
+-static struct miscdevice goldfish_pipe_device = {
++static struct miscdevice goldfish_pipe_dev = {
+ 	.minor = MISC_DYNAMIC_MINOR,
+ 	.name = "goldfish_pipe",
+ 	.fops = &goldfish_pipe_fops,
+ };
+ 
++static int goldfish_pipe_device_init(struct platform_device *pdev)
++{
++	char *page;
++	struct goldfish_pipe_dev *dev = pipe_dev;
++	int err = devm_request_irq(&pdev->dev, dev->irq,
++				goldfish_pipe_interrupt,
++				IRQF_SHARED, "goldfish_pipe", dev);
++	if (err) {
++		dev_err(&pdev->dev, "unable to allocate IRQ for v2\n");
++		return err;
++	}
++
++	err = misc_register(&goldfish_pipe_dev);
++	if (err) {
++		dev_err(&pdev->dev, "unable to register v2 device\n");
++		return err;
++	}
++
++	dev->first_signalled_pipe = NULL;
++	dev->pipes_capacity = INITIAL_PIPES_CAPACITY;
++	dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes),
++					GFP_KERNEL);
++	if (!dev->pipes)
++		return -ENOMEM;
++
++	/*
++	 * We're going to pass two buffers, open_command_params and
++	 * signalled_pipe_buffers, to the host. This means each of those buffers
++	 * needs to be contained in a single physical page. The easiest choice
++	 * is to just allocate a page and place the buffers in it.
++	 */
++	if (WARN_ON(sizeof(*dev->buffers) > PAGE_SIZE))
++		return -ENOMEM;
++
++	page = (char *)__get_free_page(GFP_KERNEL);
++	if (!page) {
++		kfree(dev->pipes);
++		return -ENOMEM;
++	}
++	dev->buffers = (struct goldfish_pipe_dev_buffers *)page;
++
++	/* Send the buffer addresses to the host */
++	{
++		u64 paddr = __pa(&dev->buffers->signalled_pipe_buffers);
++
++		writel((u32)(unsigned long)(paddr >> 32),
++			dev->base + PIPE_REG_SIGNAL_BUFFER_HIGH);
++		writel((u32)(unsigned long)paddr,
++			dev->base + PIPE_REG_SIGNAL_BUFFER);
++		writel((u32)MAX_SIGNALLED_PIPES,
++			dev->base + PIPE_REG_SIGNAL_BUFFER_COUNT);
++
++		paddr = __pa(&dev->buffers->open_command_params);
++		writel((u32)(unsigned long)(paddr >> 32),
++			dev->base + PIPE_REG_OPEN_BUFFER_HIGH);
++		writel((u32)(unsigned long)paddr,
++			dev->base + PIPE_REG_OPEN_BUFFER);
++	}
++	return 0;
++}
++
++static void goldfish_pipe_device_deinit(struct platform_device *pdev)
++{
++	struct goldfish_pipe_dev *dev = pipe_dev;
++
++	misc_deregister(&goldfish_pipe_dev);
++	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 = pipe_dev;
+ 
++	if (WARN_ON(sizeof(struct goldfish_pipe_command) > PAGE_SIZE))
++		return -ENOMEM;
++
+ 	/* not thread safe, but this should not happen */
+ 	WARN_ON(dev->base != NULL);
+ 
+@@ -609,26 +927,21 @@ static int goldfish_pipe_probe(struct pl
+ 	}
+ 	dev->irq = r->start;
+ 
+-	err = devm_request_irq(&pdev->dev, dev->irq, goldfish_pipe_interrupt,
+-				IRQF_SHARED, "goldfish_pipe", dev);
+-	if (err) {
+-		dev_err(&pdev->dev, "unable to allocate IRQ\n");
+-		goto error;
+-	}
+-
+-	err = misc_register(&goldfish_pipe_device);
+-	if (err) {
+-		dev_err(&pdev->dev, "unable to register device\n");
+-		goto error;
+-	}
+-	setup_access_params_addr(pdev, dev);
+-
+-	/* Although the pipe device in the classic Android emulator does not
+-	 * recognize the 'version' register, it won't treat this as an error
+-	 * either and will simply return 0, which is fine.
++	/*
++	 * Exchange the versions with the host device
++	 *
++	 * Note: v1 driver used to not report its version, so we write it before
++	 *  reading device version back: this allows the host implementation to
++	 *  detect the old driver (if there was no version write before read).
+ 	 */
++	writel((u32)PIPE_DRIVER_VERSION, dev->base + PIPE_REG_VERSION);
+ 	dev->version = readl(dev->base + PIPE_REG_VERSION);
+-	return 0;
++	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;
+@@ -638,7 +951,7 @@ error:
+ static int goldfish_pipe_remove(struct platform_device *pdev)
+ {
+ 	struct goldfish_pipe_dev *dev = pipe_dev;
+-	misc_deregister(&goldfish_pipe_device);
++	goldfish_pipe_device_deinit(pdev);
+ 	dev->base = NULL;
+ 	return 0;
+ }
+@@ -655,17 +968,16 @@ static const struct of_device_id goldfis
+ };
+ MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match);
+ 
+-static struct platform_driver goldfish_pipe = {
++static struct platform_driver goldfish_pipe_driver = {
+ 	.probe = goldfish_pipe_probe,
+ 	.remove = goldfish_pipe_remove,
+ 	.driver = {
+ 		.name = "goldfish_pipe",
+-		.owner = THIS_MODULE,
+ 		.of_match_table = goldfish_pipe_of_match,
+ 		.acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match),
+ 	}
+ };
+ 
+-module_platform_driver(goldfish_pipe);
++module_platform_driver(goldfish_pipe_driver);
+ MODULE_AUTHOR("David Turner <digit@google.com>");
+ MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/platform/goldfish/goldfish_pipe_legacy.c
+@@ -0,0 +1,671 @@
++/*
++ * Copyright (C) 2011 Google, Inc.
++ * Copyright (C) 2012 Intel, Inc.
++ * Copyright (C) 2013 Intel, Inc.
++ * Copyright (C) 2014 Linaro Limited
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++/* This source file contains the implementation of a special device driver
++ * that intends to provide a *very* fast communication channel between the
++ * guest system and the QEMU emulator.
++ *
++ * Usage from the guest is simply the following (error handling simplified):
++ *
++ *    int  fd = open("/dev/qemu_pipe",O_RDWR);
++ *    .... write() or read() through the pipe.
++ *
++ * This driver doesn't deal with the exact protocol used during the session.
++ * It is intended to be as simple as something like:
++ *
++ *    // do this _just_ after opening the fd to connect to a specific
++ *    // emulator service.
++ *    const char*  msg = "<pipename>";
++ *    if (write(fd, msg, strlen(msg)+1) < 0) {
++ *       ... could not connect to <pipename> service
++ *       close(fd);
++ *    }
++ *
++ *    // after this, simply read() and write() to communicate with the
++ *    // service. Exact protocol details left as an exercise to the reader.
++ *
++ * This driver is very fast because it doesn't copy any data through
++ * intermediate buffers, since the emulator is capable of translating
++ * guest user addresses into host ones.
++ *
++ * Note that we must however ensure that each user page involved in the
++ * exchange is properly mapped during a transfer.
++ */
++
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <linux/miscdevice.h>
++#include <linux/platform_device.h>
++#include <linux/poll.h>
++#include <linux/sched.h>
++#include <linux/bitops.h>
++#include <linux/slab.h>
++#include <linux/io.h>
++#include <linux/goldfish.h>
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <linux/acpi.h>
++
++/*
++ * IMPORTANT: The following constants must match the ones used and defined
++ * in external/qemu/hw/goldfish_pipe.c in the Android source tree.
++ */
++
++/* pipe device registers */
++#define PIPE_REG_COMMAND		0x00  /* write: value = command */
++#define PIPE_REG_STATUS			0x04  /* read */
++#define PIPE_REG_CHANNEL		0x08  /* read/write: channel id */
++#define PIPE_REG_CHANNEL_HIGH	        0x30  /* read/write: channel id */
++#define PIPE_REG_SIZE			0x0c  /* read/write: buffer size */
++#define PIPE_REG_ADDRESS		0x10  /* write: physical address */
++#define PIPE_REG_ADDRESS_HIGH	        0x34  /* write: physical address */
++#define PIPE_REG_WAKES			0x14  /* read: wake flags */
++#define PIPE_REG_PARAMS_ADDR_LOW	0x18  /* read/write: batch data address */
++#define PIPE_REG_PARAMS_ADDR_HIGH	0x1c  /* read/write: batch data address */
++#define PIPE_REG_ACCESS_PARAMS		0x20  /* write: batch access */
++#define PIPE_REG_VERSION		0x24  /* read: device version */
++
++/* list of commands for PIPE_REG_COMMAND */
++#define CMD_OPEN			1  /* open new channel */
++#define CMD_CLOSE			2  /* close channel (from guest) */
++#define CMD_POLL			3  /* poll read/write status */
++
++/* List of bitflags returned in status of CMD_POLL command */
++#define PIPE_POLL_IN			(1 << 0)
++#define PIPE_POLL_OUT			(1 << 1)
++#define PIPE_POLL_HUP			(1 << 2)
++
++/* The following commands are related to write operations */
++#define CMD_WRITE_BUFFER	4  /* send a user buffer to the emulator */
++#define CMD_WAKE_ON_WRITE	5  /* tell the emulator to wake us when writing
++				     is possible */
++#define CMD_READ_BUFFER        6  /* receive a user buffer from the emulator */
++#define CMD_WAKE_ON_READ       7  /* tell the emulator to wake us when reading
++				   * is possible */
++
++/* Possible status values used to signal errors - see goldfish_pipe_error_convert */
++#define PIPE_ERROR_INVAL       -1
++#define PIPE_ERROR_AGAIN       -2
++#define PIPE_ERROR_NOMEM       -3
++#define PIPE_ERROR_IO          -4
++
++/* Bit-flags used to signal events from the emulator */
++#define PIPE_WAKE_CLOSED       (1 << 0)  /* emulator closed pipe */
++#define PIPE_WAKE_READ         (1 << 1)  /* pipe can now be read from */
++#define PIPE_WAKE_WRITE        (1 << 2)  /* pipe can now be written to */
++
++struct access_params {
++	unsigned long channel;
++	u32 size;
++	unsigned long address;
++	u32 cmd;
++	u32 result;
++	/* reserved for future extension */
++	u32 flags;
++};
++
++/* The global driver data. Holds a reference to the i/o page used to
++ * communicate with the emulator, and a wake queue for blocked tasks
++ * waiting to be awoken.
++ */
++struct goldfish_pipe_dev {
++	spinlock_t lock;
++	unsigned char __iomem *base;
++	struct access_params *aps;
++	int irq;
++	u32 version;
++};
++
++static struct goldfish_pipe_dev   pipe_dev[1];
++
++/* This data type models a given pipe instance */
++struct goldfish_pipe {
++	struct goldfish_pipe_dev *dev;
++	struct mutex lock;
++	unsigned long flags;
++	wait_queue_head_t wake_queue;
++};
++
++
++/* Bit flags for the 'flags' field */
++enum {
++	BIT_CLOSED_ON_HOST = 0,  /* pipe closed by host */
++	BIT_WAKE_ON_WRITE  = 1,  /* want to be woken on writes */
++	BIT_WAKE_ON_READ   = 2,  /* want to be woken on reads */
++};
++
++
++static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)
++{
++	unsigned long flags;
++	u32 status;
++	struct goldfish_pipe_dev *dev = pipe->dev;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
++		     dev->base + PIPE_REG_CHANNEL_HIGH);
++	writel(cmd, dev->base + PIPE_REG_COMMAND);
++	status = readl(dev->base + PIPE_REG_STATUS);
++	spin_unlock_irqrestore(&dev->lock, flags);
++	return status;
++}
++
++static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)
++{
++	unsigned long flags;
++	struct goldfish_pipe_dev *dev = pipe->dev;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
++		     dev->base + PIPE_REG_CHANNEL_HIGH);
++	writel(cmd, dev->base + PIPE_REG_COMMAND);
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++/* This function converts an error code returned by the emulator through
++ * the PIPE_REG_STATUS i/o register into a valid negative errno value.
++ */
++static int goldfish_pipe_error_convert(int status)
++{
++	switch (status) {
++	case PIPE_ERROR_AGAIN:
++		return -EAGAIN;
++	case PIPE_ERROR_NOMEM:
++		return -ENOMEM;
++	case PIPE_ERROR_IO:
++		return -EIO;
++	default:
++		return -EINVAL;
++	}
++}
++
++/*
++ * Notice: QEMU will return 0 for un-known register access, indicating
++ * param_acess is supported or not
++ */
++static int valid_batchbuffer_addr(struct goldfish_pipe_dev *dev,
++				  struct access_params *aps)
++{
++	u32 aph, apl;
++	u64 paddr;
++	aph = readl(dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
++	apl = readl(dev->base + PIPE_REG_PARAMS_ADDR_LOW);
++
++	paddr = ((u64)aph << 32) | apl;
++	if (paddr != (__pa(aps)))
++		return 0;
++	return 1;
++}
++
++/* 0 on success */
++static int setup_access_params_addr(struct platform_device *pdev,
++					struct goldfish_pipe_dev *dev)
++{
++	dma_addr_t dma_handle;
++	struct access_params *aps;
++
++	aps = dmam_alloc_coherent(&pdev->dev, sizeof(struct access_params),
++				  &dma_handle, GFP_KERNEL);
++	if (!aps)
++		return -ENOMEM;
++
++	writel(upper_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
++	writel(lower_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_LOW);
++
++	if (valid_batchbuffer_addr(dev, aps)) {
++		dev->aps = aps;
++		return 0;
++	} else
++		return -1;
++}
++
++/* A value that will not be set by qemu emulator */
++#define INITIAL_BATCH_RESULT (0xdeadbeaf)
++static int access_with_param(struct goldfish_pipe_dev *dev, const int cmd,
++				unsigned long address, unsigned long avail,
++				struct goldfish_pipe *pipe, int *status)
++{
++	struct access_params *aps = dev->aps;
++
++	if (aps == NULL)
++		return -1;
++
++	aps->result = INITIAL_BATCH_RESULT;
++	aps->channel = (unsigned long)pipe;
++	aps->size = avail;
++	aps->address = address;
++	aps->cmd = cmd;
++	writel(cmd, dev->base + PIPE_REG_ACCESS_PARAMS);
++	/*
++	 * If the aps->result has not changed, that means
++	 * that the batch command failed
++	 */
++	if (aps->result == INITIAL_BATCH_RESULT)
++		return -1;
++	*status = aps->result;
++	return 0;
++}
++
++static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
++				       size_t bufflen, int is_write)
++{
++	unsigned long irq_flags;
++	struct goldfish_pipe *pipe = filp->private_data;
++	struct goldfish_pipe_dev *dev = pipe->dev;
++	unsigned long address, address_end;
++	int count = 0, ret = -EINVAL;
++
++	/* If the emulator already closed the pipe, no need to go further */
++	if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
++		return -EIO;
++
++	/* Null reads or writes succeeds */
++	if (unlikely(bufflen == 0))
++		return 0;
++
++	/* Check the buffer range for access */
++	if (!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ,
++			buffer, bufflen))
++		return -EFAULT;
++
++	/* Serialize access to the pipe */
++	if (mutex_lock_interruptible(&pipe->lock))
++		return -ERESTARTSYS;
++
++	address = (unsigned long)(void *)buffer;
++	address_end = address + bufflen;
++
++	while (address < address_end) {
++		unsigned long page_end = (address & PAGE_MASK) + PAGE_SIZE;
++		unsigned long next     = page_end < address_end ? page_end
++								: address_end;
++		unsigned long avail    = next - address;
++		int status, wakeBit;
++		struct page *page;
++
++		/* Either vaddr or paddr depending on the device version */
++		unsigned long xaddr;
++
++		/*
++		 * We grab the pages on a page-by-page basis in case user
++		 * space gives us a potentially huge buffer but the read only
++		 * returns a small amount, then there's no need to pin that
++		 * much memory to the process.
++		 */
++		ret = get_user_pages_unlocked(address, 1, &page,
++				is_write ? 0 : FOLL_WRITE);
++		if (ret < 0)
++			break;
++
++		if (dev->version) {
++			/* Device version 1 or newer (qemu-android) expects the
++			 * physical address.
++			 */
++			xaddr = page_to_phys(page) | (address & ~PAGE_MASK);
++		} else {
++			/* Device version 0 (classic emulator) expects the
++			 * virtual address.
++			 */
++			xaddr = address;
++		}
++
++		/* Now, try to transfer the bytes in the current page */
++		spin_lock_irqsave(&dev->lock, irq_flags);
++		if (access_with_param(dev,
++				is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
++				xaddr, avail, pipe, &status)) {
++			gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
++				     dev->base + PIPE_REG_CHANNEL_HIGH);
++			writel(avail, dev->base + PIPE_REG_SIZE);
++			gf_write_ptr((void *)xaddr,
++				     dev->base + PIPE_REG_ADDRESS,
++				     dev->base + PIPE_REG_ADDRESS_HIGH);
++			writel(is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
++					dev->base + PIPE_REG_COMMAND);
++			status = readl(dev->base + PIPE_REG_STATUS);
++		}
++		spin_unlock_irqrestore(&dev->lock, irq_flags);
++
++		if (status > 0 && !is_write)
++			set_page_dirty(page);
++		put_page(page);
++
++		if (status > 0) { /* Correct transfer */
++			count += status;
++			address += status;
++			continue;
++		} else if (status == 0) { /* EOF */
++			ret = 0;
++			break;
++		} else if (status < 0 && count > 0) {
++			/*
++			 * An error occurred and we already transferred
++			 * something on one of the previous pages.
++			 * Just return what we already copied and log this
++			 * err.
++			 *
++			 * Note: This seems like an incorrect approach but
++			 * cannot change it until we check if any user space
++			 * ABI relies on this behavior.
++			 */
++			if (status != PIPE_ERROR_AGAIN)
++				pr_info_ratelimited("goldfish_pipe: backend returned error %d on %s\n",
++					status, is_write ? "write" : "read");
++			ret = 0;
++			break;
++		}
++
++		/*
++		 * If the error is not PIPE_ERROR_AGAIN, or if we are not in
++		 * non-blocking mode, just return the error code.
++		 */
++		if (status != PIPE_ERROR_AGAIN ||
++			(filp->f_flags & O_NONBLOCK) != 0) {
++			ret = goldfish_pipe_error_convert(status);
++			break;
++		}
++
++		/*
++		 * The backend blocked the read/write, wait until the backend
++		 * tells us it's ready to process more data.
++		 */
++		wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ;
++		set_bit(wakeBit, &pipe->flags);
++
++		/* Tell the emulator we're going to wait for a wake event */
++		goldfish_cmd(pipe,
++			is_write ? CMD_WAKE_ON_WRITE : CMD_WAKE_ON_READ);
++
++		/* Unlock the pipe, then wait for the wake signal */
++		mutex_unlock(&pipe->lock);
++
++		while (test_bit(wakeBit, &pipe->flags)) {
++			if (wait_event_interruptible(
++					pipe->wake_queue,
++					!test_bit(wakeBit, &pipe->flags)))
++				return -ERESTARTSYS;
++
++			if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
++				return -EIO;
++		}
++
++		/* Try to re-acquire the lock */
++		if (mutex_lock_interruptible(&pipe->lock))
++			return -ERESTARTSYS;
++	}
++	mutex_unlock(&pipe->lock);
++
++	if (ret < 0)
++		return ret;
++	else
++		return count;
++}
++
++static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer,
++			      size_t bufflen, loff_t *ppos)
++{
++	return goldfish_pipe_read_write(filp, buffer, bufflen, 0);
++}
++
++static ssize_t goldfish_pipe_write(struct file *filp,
++				const char __user *buffer, size_t bufflen,
++				loff_t *ppos)
++{
++	return goldfish_pipe_read_write(filp, (char __user *)buffer,
++								bufflen, 1);
++}
++
++
++static unsigned int goldfish_pipe_poll(struct file *filp, poll_table *wait)
++{
++	struct goldfish_pipe *pipe = filp->private_data;
++	unsigned int mask = 0;
++	int status;
++
++	mutex_lock(&pipe->lock);
++
++	poll_wait(filp, &pipe->wake_queue, wait);
++
++	status = goldfish_cmd_status(pipe, CMD_POLL);
++
++	mutex_unlock(&pipe->lock);
++
++	if (status & PIPE_POLL_IN)
++		mask |= POLLIN | POLLRDNORM;
++
++	if (status & PIPE_POLL_OUT)
++		mask |= POLLOUT | POLLWRNORM;
++
++	if (status & PIPE_POLL_HUP)
++		mask |= POLLHUP;
++
++	if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
++		mask |= POLLERR;
++
++	return mask;
++}
++
++static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id)
++{
++	struct goldfish_pipe_dev *dev = dev_id;
++	unsigned long irq_flags;
++	int count = 0;
++
++	/*
++	 * We're going to read from the emulator a list of (channel,flags)
++	 * pairs corresponding to the wake events that occurred on each
++	 * blocked pipe (i.e. channel).
++	 */
++	spin_lock_irqsave(&dev->lock, irq_flags);
++	for (;;) {
++		/* First read the channel, 0 means the end of the list */
++		struct goldfish_pipe *pipe;
++		unsigned long wakes;
++		unsigned long channel = 0;
++
++#ifdef CONFIG_64BIT
++		channel = (u64)readl(dev->base + PIPE_REG_CHANNEL_HIGH) << 32;
++
++		if (channel == 0)
++			break;
++#endif
++		channel |= readl(dev->base + PIPE_REG_CHANNEL);
++
++		if (channel == 0)
++			break;
++
++		/* Convert channel to struct pipe pointer + read wake flags */
++		wakes = readl(dev->base + PIPE_REG_WAKES);
++		pipe  = (struct goldfish_pipe *)(ptrdiff_t)channel;
++
++		/* Did the emulator just closed a pipe? */
++		if (wakes & PIPE_WAKE_CLOSED) {
++			set_bit(BIT_CLOSED_ON_HOST, &pipe->flags);
++			wakes |= PIPE_WAKE_READ | PIPE_WAKE_WRITE;
++		}
++		if (wakes & PIPE_WAKE_READ)
++			clear_bit(BIT_WAKE_ON_READ, &pipe->flags);
++		if (wakes & PIPE_WAKE_WRITE)
++			clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags);
++
++		wake_up_interruptible(&pipe->wake_queue);
++		count++;
++	}
++	spin_unlock_irqrestore(&dev->lock, irq_flags);
++
++	return (count == 0) ? IRQ_NONE : IRQ_HANDLED;
++}
++
++/**
++ *	goldfish_pipe_open	-	open a channel to the AVD
++ *	@inode: inode of device
++ *	@file: file struct of opener
++ *
++ *	Create a new pipe link between the emulator and the use application.
++ *	Each new request produces a new pipe.
++ *
++ *	Note: we use the pipe ID as a mux. All goldfish emulations are 32bit
++ *	right now so this is fine. A move to 64bit will need this addressing
++ */
++static int goldfish_pipe_open(struct inode *inode, struct file *file)
++{
++	struct goldfish_pipe *pipe;
++	struct goldfish_pipe_dev *dev = pipe_dev;
++	int32_t status;
++
++	/* Allocate new pipe kernel object */
++	pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
++	if (pipe == NULL)
++		return -ENOMEM;
++
++	pipe->dev = dev;
++	mutex_init(&pipe->lock);
++	init_waitqueue_head(&pipe->wake_queue);
++
++	/*
++	 * Now, tell the emulator we're opening a new pipe. We use the
++	 * pipe object's address as the channel identifier for simplicity.
++	 */
++
++	status = goldfish_cmd_status(pipe, CMD_OPEN);
++	if (status < 0) {
++		kfree(pipe);
++		return status;
++	}
++
++	/* All is done, save the pipe into the file's private data field */
++	file->private_data = pipe;
++	return 0;
++}
++
++static int goldfish_pipe_release(struct inode *inode, struct file *filp)
++{
++	struct goldfish_pipe *pipe = filp->private_data;
++
++	/* The guest is closing the channel, so tell the emulator right now */
++	goldfish_cmd(pipe, CMD_CLOSE);
++	kfree(pipe);
++	filp->private_data = NULL;
++	return 0;
++}
++
++static const struct file_operations goldfish_pipe_fops = {
++	.owner = THIS_MODULE,
++	.read = goldfish_pipe_read,
++	.write = goldfish_pipe_write,
++	.poll = goldfish_pipe_poll,
++	.open = goldfish_pipe_open,
++	.release = goldfish_pipe_release,
++};
++
++static struct miscdevice goldfish_pipe_device = {
++	.minor = MISC_DYNAMIC_MINOR,
++	.name = "goldfish_pipe",
++	.fops = &goldfish_pipe_fops,
++};
++
++static int goldfish_pipe_probe(struct platform_device *pdev)
++{
++	int err;
++	struct resource *r;
++	struct goldfish_pipe_dev *dev = pipe_dev;
++
++	/* not thread safe, but this should not happen */
++	WARN_ON(dev->base != NULL);
++
++	spin_lock_init(&dev->lock);
++
++	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (r == NULL || resource_size(r) < PAGE_SIZE) {
++		dev_err(&pdev->dev, "can't allocate i/o page\n");
++		return -EINVAL;
++	}
++	dev->base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
++	if (dev->base == NULL) {
++		dev_err(&pdev->dev, "ioremap failed\n");
++		return -EINVAL;
++	}
++
++	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++	if (r == NULL) {
++		err = -EINVAL;
++		goto error;
++	}
++	dev->irq = r->start;
++
++	err = devm_request_irq(&pdev->dev, dev->irq, goldfish_pipe_interrupt,
++				IRQF_SHARED, "goldfish_pipe", dev);
++	if (err) {
++		dev_err(&pdev->dev, "unable to allocate IRQ\n");
++		goto error;
++	}
++
++	err = misc_register(&goldfish_pipe_device);
++	if (err) {
++		dev_err(&pdev->dev, "unable to register device\n");
++		goto error;
++	}
++	setup_access_params_addr(pdev, dev);
++
++	/* Although the pipe device in the classic Android emulator does not
++	 * recognize the 'version' register, it won't treat this as an error
++	 * either and will simply return 0, which is fine.
++	 */
++	dev->version = readl(dev->base + PIPE_REG_VERSION);
++	return 0;
++
++error:
++	dev->base = NULL;
++	return err;
++}
++
++static int goldfish_pipe_remove(struct platform_device *pdev)
++{
++	struct goldfish_pipe_dev *dev = pipe_dev;
++	misc_deregister(&goldfish_pipe_device);
++	dev->base = NULL;
++	return 0;
++}
++
++static const struct acpi_device_id goldfish_pipe_acpi_match[] = {
++	{ "GFSH0003", 0 },
++	{ },
++};
++MODULE_DEVICE_TABLE(acpi, goldfish_pipe_acpi_match);
++
++static const struct of_device_id goldfish_pipe_of_match[] = {
++	{ .compatible = "google,android-pipe", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match);
++
++static struct platform_driver goldfish_pipe = {
++	.probe = goldfish_pipe_probe,
++	.remove = goldfish_pipe_remove,
++	.driver = {
++		.name = "goldfish_pipe",
++		.owner = THIS_MODULE,
++		.of_match_table = goldfish_pipe_of_match,
++		.acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match),
++	}
++};
++
++module_platform_driver(goldfish_pipe);
++MODULE_AUTHOR("David Turner <digit@google.com>");
++MODULE_LICENSE("GPL");
diff --git a/0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch b/0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch
new file mode 100644
index 0000000..01b6e8d
--- /dev/null
+++ b/0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch
@@ -0,0 +1,76 @@
+From 384a2aaec210cc69d53cf9eec2cc7f15b10d7312 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dtor@chromium.org>
+Date: Tue, 8 Sep 2015 17:30:52 -0700
+Subject: [PATCH 2/3] CHROMIUM: android: fix warning when releasing active sync
+ point
+
+Userspace can close the sync device while there are still active fence
+points, in which case kernel produces the following warning:
+
+[   43.853176] ------------[ cut here ]------------
+[   43.857834] WARNING: CPU: 0 PID: 892 at /mnt/host/source/src/third_party/kernel/v3.18/drivers/staging/android/sync.c:439 android_fence_release+0x88/0x104()
+[   43.871741] CPU: 0 PID: 892 Comm: Binder_5 Tainted: G     U 3.18.0-07661-g0550ce9 #1
+[   43.880176] Hardware name: Google Tegra210 Smaug Rev 1+ (DT)
+[   43.885834] Call trace:
+[   43.888294] [<ffffffc000207464>] dump_backtrace+0x0/0x10c
+[   43.893697] [<ffffffc000207580>] show_stack+0x10/0x1c
+[   43.898756] [<ffffffc000ab1258>] dump_stack+0x74/0xb8
+[   43.903814] [<ffffffc00021d414>] warn_slowpath_common+0x84/0xb0
+[   43.909736] [<ffffffc00021d530>] warn_slowpath_null+0x14/0x20
+[   43.915482] [<ffffffc00088aefc>] android_fence_release+0x84/0x104
+[   43.921582] [<ffffffc000671cc4>] fence_release+0x104/0x134
+[   43.927066] [<ffffffc00088b0cc>] sync_fence_free+0x74/0x9c
+[   43.932552] [<ffffffc00088b128>] sync_fence_release+0x34/0x48
+[   43.938304] [<ffffffc000317bbc>] __fput+0x100/0x1b8
+[   43.943185] [<ffffffc000317cc8>] ____fput+0x8/0x14
+[   43.947982] [<ffffffc000237f38>] task_work_run+0xb0/0xe4
+[   43.953297] [<ffffffc000207074>] do_notify_resume+0x44/0x5c
+[   43.958867] ---[ end trace 5a2aa4027cc5d171 ]---
+
+Let's fix it by introducing a new optional callback (disable_signaling)
+to fence operations so that drivers can do proper clean ups when we
+remove last callback for given fence.
+
+Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
+Reviewed-on: https://chromium-review.googlesource.com/303409
+Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
+Signed-off-by: Jin Qian <jinqian@android.com>
+---
+ drivers/dma-buf/dma-fence.c |    6 +++++-
+ include/linux/dma-fence.h   |    2 ++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma-buf/dma-fence.c
++++ b/drivers/dma-buf/dma-fence.c
+@@ -332,8 +332,12 @@ dma_fence_remove_callback(struct dma_fen
+ 	spin_lock_irqsave(fence->lock, flags);
+ 
+ 	ret = !list_empty(&cb->node);
+-	if (ret)
++	if (ret) {
+ 		list_del_init(&cb->node);
++		if (list_empty(&fence->cb_list))
++			if (fence->ops->disable_signaling)
++				fence->ops->disable_signaling(fence);
++	}
+ 
+ 	spin_unlock_irqrestore(fence->lock, flags);
+ 
+--- a/include/linux/dma-fence.h
++++ b/include/linux/dma-fence.h
+@@ -109,6 +109,7 @@ struct dma_fence_cb {
+  * @get_driver_name: returns the driver name.
+  * @get_timeline_name: return the name of the context this fence belongs to.
+  * @enable_signaling: enable software signaling of fence.
++ * @disable_signaling: disable software signaling of fence (optional).
+  * @signaled: [optional] peek whether the fence is signaled, can be null.
+  * @wait: custom wait implementation, or dma_fence_default_wait.
+  * @release: [optional] called on destruction of fence, can be null
+@@ -168,6 +169,7 @@ struct dma_fence_ops {
+ 	const char * (*get_driver_name)(struct dma_fence *fence);
+ 	const char * (*get_timeline_name)(struct dma_fence *fence);
+ 	bool (*enable_signaling)(struct dma_fence *fence);
++	void (*disable_signaling)(struct dma_fence *fence);
+ 	bool (*signaled)(struct dma_fence *fence);
+ 	signed long (*wait)(struct dma_fence *fence,
+ 			    bool intr, signed long timeout);
diff --git a/0003-goldfish-Add-goldfish-sync-driver.patch b/0003-goldfish-Add-goldfish-sync-driver.patch
new file mode 100644
index 0000000..2bf7249
--- /dev/null
+++ b/0003-goldfish-Add-goldfish-sync-driver.patch
@@ -0,0 +1,1429 @@
+From c7f0d1bafcc183f23995c4757cf9ecc9e0bd1cc8 Mon Sep 17 00:00:00 2001
+From: Lingfeng Yang <lfy@google.com>
+Date: Mon, 13 Jun 2016 09:24:07 -0700
+Subject: [PATCH 3/3] goldfish: Add goldfish sync driver
+
+This is kernel driver for controlling the Goldfish sync
+device on the host. It is used to maintain ordering
+in critical OpenGL state changes while using
+GPU emulation.
+
+The guest open()'s the Goldfish sync device to create
+a context for possibly maintaining sync timeline and fences.
+There is a 1:1 correspondence between such sync contexts
+and OpenGL contexts in the guest that need synchronization
+(which in turn, is anything involving swapping buffers,
+SurfaceFlinger, or Hardware Composer).
+
+The ioctl QUEUE_WORK takes a handle to a sync object
+and attempts to tell the host GPU to wait on the sync object
+and deal with signaling it. It possibly outputs
+a fence FD on which the Android systems that use them
+(GLConsumer, SurfaceFlinger, anything employing
+EGL_ANDROID_native_fence_sync) can use to wait.
+
+Design decisions and work log:
+
+- New approach is to have the guest issue ioctls that
+  trigger host wait, and then host increments timeline.
+- We need the host's sync object handle and sync thread handle
+  as the necessary information for that.
+- ioctl() from guest can work simultaneously with the
+  interrupt handling for commands from host.
+- optimization: don't write back on timeline inc
+- Change spin lock design to be much more lightweight;
+  do not call sw_sync functions or loop too long
+  anywhere.
+- Send read/write commands in batches to minimize guest/host
+  transitions.
+- robustness: BUG if we will overrun the cmd buffer.
+- robustness: return fd -1 if we cannot get an unused fd.
+- correctness: remove global mutex
+- cleanup pass done, incl. but not limited to:
+    - removal of clear_upto and
+    - switching to devm_***
+
+Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
+Signed-off-by: Lingfeng Yang <lfy@google.com>
+Signed-off-by: Jin Qian <jinqian@android.com>
+---
+ Documentation/devicetree/bindings/goldfish/sync.txt     |   17 
+ drivers/staging/goldfish/Kconfig                        |    8 
+ drivers/staging/goldfish/Makefile                       |    6 
+ drivers/staging/goldfish/goldfish_sync_timeline.c       |  980 ++++++++++++++++
+ drivers/staging/goldfish/goldfish_sync_timeline_fence.c |  258 ++++
+ drivers/staging/goldfish/goldfish_sync_timeline_fence.h |   72 +
+ 6 files changed, 1341 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/goldfish/sync.txt
+ create mode 100644 drivers/staging/goldfish/goldfish_sync_timeline.c
+ create mode 100644 drivers/staging/goldfish/goldfish_sync_timeline_fence.c
+ create mode 100644 drivers/staging/goldfish/goldfish_sync_timeline_fence.h
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/goldfish/sync.txt
+@@ -0,0 +1,17 @@
++Android Goldfish QEMU Sync Device
++
++goldfish sync virtual device generated by android emulator.
++
++Required properties:
++
++- compatible : should contain "google,goldfish-sync" to match emulator
++- reg        : <registers mapping>
++- interrupts : <interrupt mapping>
++
++Example:
++
++	android_pipe@a010000 {
++		compatible = "google,goldfish-sync";
++		reg = <ff01D000 0x0100>;
++		interrupts = <0xb>;
++	};
+--- a/drivers/staging/goldfish/Kconfig
++++ b/drivers/staging/goldfish/Kconfig
+@@ -4,6 +4,14 @@ config GOLDFISH_AUDIO
+ 	---help---
+ 	  Emulated audio channel for the Goldfish Android Virtual Device
+ 
++config GOLDFISH_SYNC
++    tristate "Goldfish AVD Sync Driver"
++    depends on GOLDFISH
++    depends on SW_SYNC
++    depends on SYNC_FILE
++	---help---
++	  Emulated sync fences for the Goldfish Android Virtual Device
++
+ config MTD_GOLDFISH_NAND
+ 	tristate "Goldfish NAND device"
+ 	depends on GOLDFISH
+--- a/drivers/staging/goldfish/Makefile
++++ b/drivers/staging/goldfish/Makefile
+@@ -4,3 +4,9 @@
+ 
+ obj-$(CONFIG_GOLDFISH_AUDIO) += goldfish_audio.o
+ obj-$(CONFIG_MTD_GOLDFISH_NAND)	+= goldfish_nand.o
++
++# and sync
++
++ccflags-y := -Idrivers/staging/android
++goldfish_sync-objs := goldfish_sync_timeline_fence.o goldfish_sync_timeline.o
++obj-$(CONFIG_GOLDFISH_SYNC) += goldfish_sync.o
+--- /dev/null
++++ b/drivers/staging/goldfish/goldfish_sync_timeline.c
+@@ -0,0 +1,980 @@
++/*
++ * Copyright (C) 2016 Google, Inc.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/fdtable.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/miscdevice.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <linux/interrupt.h>
++#include <linux/kref.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++#include <linux/io.h>
++#include <linux/mm.h>
++#include <linux/acpi.h>
++
++#include <linux/string.h>
++
++#include <linux/fs.h>
++#include <linux/syscalls.h>
++#include <linux/sync_file.h>
++#include <linux/dma-fence.h>
++
++#include "goldfish_sync_timeline_fence.h"
++
++#define DTRACE() pr_debug("%s: enter", __func__)
++
++/* The Goldfish sync driver is designed to provide a interface
++ * between the underlying host's sync device and the kernel's
++ * fence sync framework..
++ * The purpose of the device/driver is to enable lightweight
++ * creation and signaling of timelines and fences
++ * in order to synchronize the guest with host-side graphics events.
++ *
++ * Each time the interrupt trips, the driver
++ * may perform a sync operation.
++ */
++
++/* The operations are: */
++
++/* Ready signal - used to mark when irq should lower */
++#define CMD_SYNC_READY            0
++
++/* Create a new timeline. writes timeline handle */
++#define CMD_CREATE_SYNC_TIMELINE  1
++
++/* Create a fence object. reads timeline handle and time argument.
++ * Writes fence fd to the SYNC_REG_HANDLE register.
++ */
++#define CMD_CREATE_SYNC_FENCE     2
++
++/* Increments timeline. reads timeline handle and time argument */
++#define CMD_SYNC_TIMELINE_INC     3
++
++/* Destroys a timeline. reads timeline handle */
++#define CMD_DESTROY_SYNC_TIMELINE 4
++
++/* Starts a wait on the host with
++ * the given glsync object and sync thread handle.
++ */
++#define CMD_TRIGGER_HOST_WAIT     5
++
++/* The register layout is: */
++
++/* host->guest batch commands */
++#define SYNC_REG_BATCH_COMMAND                0x00
++/* guest->host batch commands */
++#define SYNC_REG_BATCH_GUESTCOMMAND           0x04
++/* communicate physical address of host->guest batch commands */
++#define SYNC_REG_BATCH_COMMAND_ADDR           0x08
++/* 64-bit part */
++#define SYNC_REG_BATCH_COMMAND_ADDR_HIGH      0x0c
++/* communicate physical address of guest->host commands */
++#define SYNC_REG_BATCH_GUESTCOMMAND_ADDR      0x10
++/* 64-bit part */
++#define SYNC_REG_BATCH_GUESTCOMMAND_ADDR_HIGH 0x14
++/* signals that the device has been probed */
++#define SYNC_REG_INIT                         0x18
++
++/* There is an ioctl associated with goldfish sync driver.
++ * Make it conflict with ioctls that are not likely to be used
++ * in the emulator.
++ *
++ * '@'	00-0F	linux/radeonfb.h	conflict!
++ * '@'	00-0F	drivers/video/aty/aty128fb.c	conflict!
++ */
++#define GOLDFISH_SYNC_IOC_MAGIC	'@'
++
++#define GOLDFISH_SYNC_IOC_QUEUE_WORK \
++	_IOWR(GOLDFISH_SYNC_IOC_MAGIC, 0, struct goldfish_sync_ioctl_info)
++
++/* The above definitions (command codes, register layout, ioctl definitions)
++ * need to be in sync with the following files:
++ *
++ * Host-side (emulator):
++ * external/qemu/android/emulation/goldfish_sync.h
++ * external/qemu-android/hw/misc/goldfish_sync.c
++ *
++ * Guest-side (system image):
++ * device/generic/goldfish-opengl/system/egl/goldfish_sync.h
++ * device/generic/goldfish/ueventd.ranchu.rc
++ * platform/build/target/board/generic/sepolicy/file_contexts
++ */
++struct goldfish_sync_hostcmd {
++	/* sorted for alignment */
++	u64 handle;
++	u64 hostcmd_handle;
++	u32 cmd;
++	u32 time_arg;
++};
++
++struct goldfish_sync_guestcmd {
++	u64 host_command; /* u64 for alignment */
++	u64 glsync_handle;
++	u64 thread_handle;
++	u64 guest_timeline_handle;
++};
++
++#define GOLDFISH_SYNC_MAX_CMDS 32
++
++struct goldfish_sync_state {
++	char __iomem *reg_base;
++	int irq;
++
++	/* Spinlock protects |to_do| / |to_do_end|. */
++	spinlock_t lock;
++	/* |mutex_lock| protects all concurrent access
++	 * to timelines for both kernel and user space.
++	 */
++	struct mutex mutex_lock;
++
++	/* Buffer holding commands issued from host. */
++	struct goldfish_sync_hostcmd to_do[GOLDFISH_SYNC_MAX_CMDS];
++	u32 to_do_end;
++
++	/* Addresses for the reading or writing
++	 * of individual commands. The host can directly write
++	 * to |batch_hostcmd| (and then this driver immediately
++	 * copies contents to |to_do|). This driver either replies
++	 * through |batch_hostcmd| or simply issues a
++	 * guest->host command through |batch_guestcmd|.
++	 */
++	struct goldfish_sync_hostcmd *batch_hostcmd;
++	struct goldfish_sync_guestcmd *batch_guestcmd;
++
++	/* Used to give this struct itself to a work queue
++	 * function for executing actual sync commands.
++	 */
++	struct work_struct work_item;
++};
++
++static struct goldfish_sync_state global_sync_state[1];
++
++struct goldfish_sync_timeline_obj {
++	struct goldfish_sync_timeline *sync_tl;
++	u32 current_time;
++	/* We need to be careful about when we deallocate
++	 * this |goldfish_sync_timeline_obj| struct.
++	 * In order to ensure proper cleanup, we need to
++	 * consider the triggered host-side wait that may
++	 * still be in flight when the guest close()'s a
++	 * goldfish_sync device's sync context fd (and
++	 * destroys the |sync_tl| field above).
++	 * The host-side wait may raise IRQ
++	 * and tell the kernel to increment the timeline _after_
++	 * the |sync_tl| has already been set to null.
++	 *
++	 * From observations on OpenGL apps and CTS tests, this
++	 * happens at some very low probability upon context
++	 * destruction or process close, but it does happen
++	 * and it needs to be handled properly. Otherwise,
++	 * if we clean up the surrounding |goldfish_sync_timeline_obj|
++	 * too early, any |handle| field of any host->guest command
++	 * might not even point to a null |sync_tl| field,
++	 * but to garbage memory or even a reclaimed |sync_tl|.
++	 * If we do not count such "pending waits" and kfree the object
++	 * immediately upon |goldfish_sync_timeline_destroy|,
++	 * we might get mysterous RCU stalls after running a long
++	 * time because the garbage memory that is being read
++	 * happens to be interpretable as a |spinlock_t| struct
++	 * that is currently in the locked state.
++	 *
++	 * To track when to free the |goldfish_sync_timeline_obj|
++	 * itself, we maintain a kref.
++	 * The kref essentially counts the timeline itself plus
++	 * the number of waits in flight. kref_init/kref_put
++	 * are issued on
++	 * |goldfish_sync_timeline_create|/|goldfish_sync_timeline_destroy|
++	 * and kref_get/kref_put are issued on
++	 * |goldfish_sync_fence_create|/|goldfish_sync_timeline_inc|.
++	 *
++	 * The timeline is destroyed after reference count
++	 * reaches zero, which would happen after
++	 * |goldfish_sync_timeline_destroy| and all pending
++	 * |goldfish_sync_timeline_inc|'s are fulfilled.
++	 *
++	 * NOTE (1): We assume that |fence_create| and
++	 * |timeline_inc| calls are 1:1, otherwise the kref scheme
++	 * will not work. This is a valid assumption as long
++	 * as the host-side virtual device implementation
++	 * does not insert any timeline increments
++	 * that we did not trigger from here.
++	 *
++	 * NOTE (2): The use of kref by itself requires no locks,
++	 * but this does not mean everything works without locks.
++	 * Related timeline operations do require a lock of some sort,
++	 * or at least are not proven to work without it.
++	 * In particualr, we assume that all the operations
++	 * done on the |kref| field above are done in contexts where
++	 * |global_sync_state->mutex_lock| is held. Do not
++	 * remove that lock until everything is proven to work
++	 * without it!!!
++	 */
++	struct kref kref;
++};
++
++/* We will call |delete_timeline_obj| when the last reference count
++ * of the kref is decremented. This deletes the sync
++ * timeline object along with the wrapper itself.
++ */
++static void delete_timeline_obj(struct kref *kref)
++{
++	struct goldfish_sync_timeline_obj *obj =
++		container_of(kref, struct goldfish_sync_timeline_obj, kref);
++
++	goldfish_sync_timeline_put_internal(obj->sync_tl);
++	obj->sync_tl = NULL;
++	kfree(obj);
++}
++
++static u64 gensym_ctr;
++static void gensym(char *dst)
++{
++	sprintf(dst, "goldfish_sync:gensym:%llu", gensym_ctr);
++	gensym_ctr++;
++}
++
++/* |goldfish_sync_timeline_create| assumes that |global_sync_state->mutex_lock|
++ * is held.
++ */
++static struct goldfish_sync_timeline_obj *
++goldfish_sync_timeline_create(void)
++{
++	char timeline_name[256];
++	struct goldfish_sync_timeline *res_sync_tl = NULL;
++	struct goldfish_sync_timeline_obj *res;
++
++	DTRACE();
++
++	gensym(timeline_name);
++
++	res_sync_tl = goldfish_sync_timeline_create_internal(timeline_name);
++	if (!res_sync_tl) {
++		pr_err("Failed to create goldfish_sw_sync timeline.");
++		return NULL;
++	}
++
++	res = kzalloc(sizeof(*res), GFP_KERNEL);
++	res->sync_tl = res_sync_tl;
++	res->current_time = 0;
++	kref_init(&res->kref);
++
++	pr_debug("new timeline_obj=0x%p", res);
++	return res;
++}
++
++/* |goldfish_sync_fence_create| assumes that |global_sync_state->mutex_lock|
++ * is held.
++ */
++static int
++goldfish_sync_fence_create(struct goldfish_sync_timeline_obj *obj, u32 val)
++{
++	int fd;
++	char fence_name[256];
++	struct sync_pt *syncpt = NULL;
++	struct sync_file *sync_file_obj = NULL;
++	struct goldfish_sync_timeline *tl;
++
++	DTRACE();
++
++	if (!obj)
++		return -1;
++
++	tl = obj->sync_tl;
++
++	syncpt = goldfish_sync_pt_create_internal(
++				tl, sizeof(struct sync_pt) + 4, val);
++	if (!syncpt) {
++		pr_err(
++			"could not create sync point! goldfish_sync_timeline=0x%p val=%d",
++			tl, val);
++		return -1;
++	}
++
++	fd = get_unused_fd_flags(O_CLOEXEC);
++	if (fd < 0) {
++		pr_err("could not get unused fd for sync fence. errno=%d", fd);
++		goto err_cleanup_pt;
++	}
++
++	gensym(fence_name);
++
++	sync_file_obj = sync_file_create(&syncpt->base);
++	if (!sync_file_obj) {
++		pr_err("could not create sync fence! goldfish_sync_timeline=0x%p val=%d sync_pt=0x%p",
++		       tl, val, syncpt);
++		goto err_cleanup_fd_pt;
++	}
++
++	pr_debug("installing sync fence into fd %d sync_file_obj=0x%p",
++		 fd, sync_file_obj);
++	fd_install(fd, sync_file_obj->file);
++	kref_get(&obj->kref);
++
++	return fd;
++
++err_cleanup_fd_pt:
++	put_unused_fd(fd);
++err_cleanup_pt:
++	dma_fence_put(&syncpt->base);
++	return -1;
++}
++
++/* |goldfish_sync_timeline_inc| assumes that |global_sync_state->mutex_lock|
++ * is held.
++ */
++static void
++goldfish_sync_timeline_inc(struct goldfish_sync_timeline_obj *obj, u32 inc)
++{
++	DTRACE();
++	/* Just give up if someone else nuked the timeline.
++	 * Whoever it was won't care that it doesn't get signaled.
++	 */
++	if (!obj)
++		return;
++
++	pr_debug("timeline_obj=0x%p", obj);
++	goldfish_sync_timeline_signal_internal(obj->sync_tl, inc);
++	pr_debug("incremented timeline. increment max_time");
++	obj->current_time += inc;
++
++	/* Here, we will end up deleting the timeline object if it
++	 * turns out that this call was a pending increment after
++	 * |goldfish_sync_timeline_destroy| was called.
++	 */
++	kref_put(&obj->kref, delete_timeline_obj);
++	pr_debug("done");
++}
++
++/* |goldfish_sync_timeline_destroy| assumes
++ * that |global_sync_state->mutex_lock| is held.
++ */
++static void
++goldfish_sync_timeline_destroy(struct goldfish_sync_timeline_obj *obj)
++{
++	DTRACE();
++	/* See description of |goldfish_sync_timeline_obj| for why we
++	 * should not immediately destroy |obj|
++	 */
++	kref_put(&obj->kref, delete_timeline_obj);
++}
++
++static inline void
++goldfish_sync_cmd_queue(struct goldfish_sync_state *sync_state,
++			u32 cmd,
++			u64 handle,
++			u32 time_arg,
++			u64 hostcmd_handle)
++{
++	struct goldfish_sync_hostcmd *to_add;
++
++	DTRACE();
++
++	if (WARN_ON(sync_state->to_do_end == GOLDFISH_SYNC_MAX_CMDS))
++		return;
++
++	to_add = &sync_state->to_do[sync_state->to_do_end];
++
++	to_add->cmd = cmd;
++	to_add->handle = handle;
++	to_add->time_arg = time_arg;
++	to_add->hostcmd_handle = hostcmd_handle;
++
++	sync_state->to_do_end += 1;
++}
++
++static inline void
++goldfish_sync_hostcmd_reply(struct goldfish_sync_state *sync_state,
++			    u32 cmd,
++			    u64 handle,
++			    u32 time_arg,
++			    u64 hostcmd_handle)
++{
++	unsigned long irq_flags;
++	struct goldfish_sync_hostcmd *batch_hostcmd =
++		sync_state->batch_hostcmd;
++
++	DTRACE();
++
++	spin_lock_irqsave(&sync_state->lock, irq_flags);
++
++	batch_hostcmd->cmd = cmd;
++	batch_hostcmd->handle = handle;
++	batch_hostcmd->time_arg = time_arg;
++	batch_hostcmd->hostcmd_handle = hostcmd_handle;
++	writel(0, sync_state->reg_base + SYNC_REG_BATCH_COMMAND);
++
++	spin_unlock_irqrestore(&sync_state->lock, irq_flags);
++}
++
++static inline void
++goldfish_sync_send_guestcmd(struct goldfish_sync_state *sync_state,
++			    u32 cmd,
++			    u64 glsync_handle,
++			    u64 thread_handle,
++			    u64 timeline_handle)
++{
++	unsigned long irq_flags;
++	struct goldfish_sync_guestcmd *batch_guestcmd =
++		sync_state->batch_guestcmd;
++
++	DTRACE();
++
++	spin_lock_irqsave(&sync_state->lock, irq_flags);
++
++	batch_guestcmd->host_command = (u64)cmd;
++	batch_guestcmd->glsync_handle = (u64)glsync_handle;
++	batch_guestcmd->thread_handle = (u64)thread_handle;
++	batch_guestcmd->guest_timeline_handle = (u64)timeline_handle;
++	writel(0, sync_state->reg_base + SYNC_REG_BATCH_GUESTCOMMAND);
++
++	spin_unlock_irqrestore(&sync_state->lock, irq_flags);
++}
++
++/* |goldfish_sync_interrupt| handles IRQ raises from the virtual device.
++ * In the context of OpenGL, this interrupt will fire whenever we need
++ * to signal a fence fd in the guest, with the command
++ * |CMD_SYNC_TIMELINE_INC|.
++ * However, because this function will be called in an interrupt context,
++ * it is necessary to do the actual work of signaling off of interrupt context.
++ * The shared work queue is used for this purpose. At the end when
++ * all pending commands are intercepted by the interrupt handler,
++ * we call |schedule_work|, which will later run the actual
++ * desired sync command in |goldfish_sync_work_item_fn|.
++ */
++static irqreturn_t goldfish_sync_interrupt(int irq, void *dev_id)
++{
++	struct goldfish_sync_state *sync_state = dev_id;
++
++	u32 nextcmd;
++	u32 command_r;
++	u64 handle_rw;
++	u32 time_r;
++	u64 hostcmd_handle_rw;
++
++	int count = 0;
++
++	DTRACE();
++
++	sync_state = dev_id;
++
++	spin_lock(&sync_state->lock);
++
++	for (;;) {
++		readl(sync_state->reg_base + SYNC_REG_BATCH_COMMAND);
++		nextcmd = sync_state->batch_hostcmd->cmd;
++
++		if (nextcmd == 0)
++			break;
++
++		command_r = nextcmd;
++		handle_rw = sync_state->batch_hostcmd->handle;
++		time_r = sync_state->batch_hostcmd->time_arg;
++		hostcmd_handle_rw = sync_state->batch_hostcmd->hostcmd_handle;
++
++		goldfish_sync_cmd_queue(
++				sync_state,
++				command_r,
++				handle_rw,
++				time_r,
++				hostcmd_handle_rw);
++
++		count++;
++	}
++
++	spin_unlock(&sync_state->lock);
++
++	schedule_work(&sync_state->work_item);
++
++	return (count == 0) ? IRQ_NONE : IRQ_HANDLED;
++}
++
++/* |goldfish_sync_work_item_fn| does the actual work of servicing
++ * host->guest sync commands. This function is triggered whenever
++ * the IRQ for the goldfish sync device is raised. Once it starts
++ * running, it grabs the contents of the buffer containing the
++ * commands it needs to execute (there may be multiple, because
++ * our IRQ is active high and not edge triggered), and then
++ * runs all of them one after the other.
++ */
++static void goldfish_sync_work_item_fn(struct work_struct *input)
++{
++	struct goldfish_sync_state *sync_state;
++	int sync_fence_fd;
++
++	struct goldfish_sync_timeline_obj *timeline;
++	u64 timeline_ptr;
++
++	u64 hostcmd_handle;
++
++	u32 cmd;
++	u64 handle;
++	u32 time_arg;
++
++	struct goldfish_sync_hostcmd *todo;
++	u32 todo_end;
++
++	unsigned long irq_flags;
++
++	struct goldfish_sync_hostcmd to_run[GOLDFISH_SYNC_MAX_CMDS];
++	u32 i = 0;
++
++	sync_state = container_of(input, struct goldfish_sync_state, work_item);
++
++	mutex_lock(&sync_state->mutex_lock);
++
++	spin_lock_irqsave(&sync_state->lock, irq_flags); {
++		todo_end = sync_state->to_do_end;
++
++		pr_debug("num sync todos: %u", sync_state->to_do_end);
++
++		for (i = 0; i < todo_end; i++)
++			to_run[i] = sync_state->to_do[i];
++
++		/* We expect that commands will come in at a slow enough rate
++		 * so that incoming items will not be more than
++		 * GOLDFISH_SYNC_MAX_CMDS.
++		 *
++		 * This is because the way the sync device is used,
++		 * it's only for managing buffer data transfers per frame,
++		 * with a sequential dependency between putting things in
++		 * to_do and taking them out. Once a set of commands is
++		 * queued up in to_do, the user of the device waits for
++		 * them to be processed before queuing additional commands,
++		 * which limits the rate at which commands come in
++		 * to the rate at which we take them out here.
++		 *
++		 * We also don't expect more than MAX_CMDS to be issued
++		 * at once; there is a correspondence between
++		 * which buffers need swapping to the (display / buffer queue)
++		 * to particular commands, and we don't expect there to be
++		 * enough display or buffer queues in operation at once
++		 * to overrun GOLDFISH_SYNC_MAX_CMDS.
++		 */
++		sync_state->to_do_end = 0;
++
++	} spin_unlock_irqrestore(&sync_state->lock, irq_flags);
++
++	for (i = 0; i < todo_end; i++) {
++		pr_debug("todo index: %u", i);
++
++		todo = &to_run[i];
++
++		cmd = todo->cmd;
++
++		handle = (u64)todo->handle;
++		time_arg = todo->time_arg;
++		hostcmd_handle = (u64)todo->hostcmd_handle;
++
++		DTRACE();
++
++		timeline =
++			(struct goldfish_sync_timeline_obj *)(uintptr_t)handle;
++
++		switch (cmd) {
++		case CMD_SYNC_READY:
++			break;
++		case CMD_CREATE_SYNC_TIMELINE:
++			pr_debug("exec CMD_CREATE_SYNC_TIMELINE: handle=0x%llx time_arg=%d",
++				 handle, time_arg);
++			timeline = goldfish_sync_timeline_create();
++			timeline_ptr = (uintptr_t)timeline;
++			goldfish_sync_hostcmd_reply(sync_state,
++						    CMD_CREATE_SYNC_TIMELINE,
++						    timeline_ptr,
++						    0,
++						    hostcmd_handle);
++			pr_debug("sync timeline created: %p", timeline);
++			break;
++		case CMD_CREATE_SYNC_FENCE:
++			pr_debug("exec CMD_CREATE_SYNC_FENCE: handle=0x%llx time_arg=%d",
++				 handle, time_arg);
++			sync_fence_fd = goldfish_sync_fence_create(
++				timeline, time_arg);
++			goldfish_sync_hostcmd_reply(sync_state,
++						    CMD_CREATE_SYNC_FENCE,
++						    sync_fence_fd,
++						    0,
++						    hostcmd_handle);
++			break;
++		case CMD_SYNC_TIMELINE_INC:
++			pr_debug("exec CMD_SYNC_TIMELINE_INC: handle=0x%llx time_arg=%d",
++				 handle, time_arg);
++			goldfish_sync_timeline_inc(timeline, time_arg);
++			break;
++		case CMD_DESTROY_SYNC_TIMELINE:
++			pr_debug("exec CMD_DESTROY_SYNC_TIMELINE: handle=0x%llx time_arg=%d",
++				 handle, time_arg);
++			goldfish_sync_timeline_destroy(timeline);
++			break;
++		}
++		pr_debug("Done executing sync command");
++	}
++	mutex_unlock(&sync_state->mutex_lock);
++}
++
++/* Guest-side interface: file operations */
++
++/* Goldfish sync context and ioctl info.
++ *
++ * When a sync context is created by open()-ing the goldfish sync device, we
++ * create a sync context (|goldfish_sync_context|).
++ *
++ * Currently, the only data required to track is the sync timeline itself
++ * along with the current time, which are all packed up in the
++ * |goldfish_sync_timeline_obj| field. We use a |goldfish_sync_context|
++ * as the filp->private_data.
++ *
++ * Next, when a sync context user requests that work be queued and a fence
++ * fd provided, we use the |goldfish_sync_ioctl_info| struct, which holds
++ * information about which host handles to touch for this particular
++ * queue-work operation. We need to know about the host-side sync thread
++ * and the particular host-side GLsync object. We also possibly write out
++ * a file descriptor.
++ */
++struct goldfish_sync_context {
++	struct goldfish_sync_timeline_obj *timeline;
++};
++
++struct goldfish_sync_ioctl_info {
++	u64 host_glsync_handle_in;
++	u64 host_syncthread_handle_in;
++	int fence_fd_out;
++};
++
++static int goldfish_sync_open(struct inode *inode, struct file *file)
++{
++	struct goldfish_sync_context *sync_context;
++
++	DTRACE();
++
++	mutex_lock(&global_sync_state->mutex_lock);
++
++	sync_context = kzalloc(sizeof(*sync_context),
++			       GFP_KERNEL);
++
++	if (!sync_context) {
++		pr_err("Creation of goldfish sync context failed!");
++		mutex_unlock(&global_sync_state->mutex_lock);
++		return -ENOMEM;
++	}
++
++	sync_context->timeline = NULL;
++
++	file->private_data = sync_context;
++
++	pr_debug("successfully create a sync context @0x%p", sync_context);
++
++	mutex_unlock(&global_sync_state->mutex_lock);
++
++	return 0;
++}
++
++static int goldfish_sync_release(struct inode *inode, struct file *file)
++{
++	struct goldfish_sync_context *sync_context;
++
++	DTRACE();
++
++	mutex_lock(&global_sync_state->mutex_lock);
++
++	sync_context = file->private_data;
++
++	if (sync_context->timeline)
++		goldfish_sync_timeline_destroy(sync_context->timeline);
++
++	sync_context->timeline = NULL;
++
++	kfree(sync_context);
++
++	mutex_unlock(&global_sync_state->mutex_lock);
++
++	return 0;
++}
++
++/* |goldfish_sync_ioctl| is the guest-facing interface of goldfish sync
++ * and is used in conjunction with eglCreateSyncKHR to queue up the
++ * actual work of waiting for the EGL sync command to complete,
++ * possibly returning a fence fd to the guest.
++ */
++static long goldfish_sync_ioctl(struct file *file,
++				unsigned int cmd,
++				unsigned long arg)
++{
++	struct goldfish_sync_context *sync_context_data;
++	struct goldfish_sync_timeline_obj *timeline;
++	int fd_out;
++	struct goldfish_sync_ioctl_info ioctl_data;
++
++	DTRACE();
++
++	sync_context_data = file->private_data;
++	fd_out = -1;
++
++	switch (cmd) {
++	case GOLDFISH_SYNC_IOC_QUEUE_WORK:
++
++		pr_debug("exec GOLDFISH_SYNC_IOC_QUEUE_WORK");
++
++		mutex_lock(&global_sync_state->mutex_lock);
++
++		if (copy_from_user(&ioctl_data,
++				   (void __user *)arg,
++				   sizeof(ioctl_data))) {
++			pr_err("Failed to copy memory for ioctl_data from user.");
++			mutex_unlock(&global_sync_state->mutex_lock);
++			return -EFAULT;
++		}
++
++		if (ioctl_data.host_syncthread_handle_in == 0) {
++			pr_debug("Error: zero host syncthread handle!!!");
++			mutex_unlock(&global_sync_state->mutex_lock);
++			return -EFAULT;
++		}
++
++		if (!sync_context_data->timeline) {
++			pr_debug("no timeline yet, create one.");
++			sync_context_data->timeline =
++				goldfish_sync_timeline_create();
++			pr_debug("timeline: 0x%p",
++				 &sync_context_data->timeline);
++		}
++
++		timeline = sync_context_data->timeline;
++		fd_out = goldfish_sync_fence_create(timeline,
++						    timeline->current_time + 1);
++		pr_debug("Created fence with fd %d and current time %u (timeline: 0x%p)",
++			 fd_out,
++			 sync_context_data->timeline->current_time + 1,
++			 sync_context_data->timeline);
++
++		ioctl_data.fence_fd_out = fd_out;
++
++		if (copy_to_user((void __user *)arg,
++				 &ioctl_data,
++				 sizeof(ioctl_data))) {
++			pr_debug("Error, could not copy to user!!!");
++
++			sys_close(fd_out);
++			/* We won't be doing an increment, kref_put
++			 * immediately.
++			 */
++			kref_put(&timeline->kref, delete_timeline_obj);
++			mutex_unlock(&global_sync_state->mutex_lock);
++			return -EFAULT;
++		}
++
++		/* We are now about to trigger a host-side wait;
++		 * accumulate on |pending_waits|.
++		 */
++		goldfish_sync_send_guestcmd(
++				global_sync_state,
++				CMD_TRIGGER_HOST_WAIT,
++				ioctl_data.host_glsync_handle_in,
++				ioctl_data.host_syncthread_handle_in,
++				(u64)(uintptr_t)(sync_context_data->timeline));
++
++		mutex_unlock(&global_sync_state->mutex_lock);
++		return 0;
++	default:
++		return -ENOTTY;
++	}
++}
++
++static const struct file_operations goldfish_sync_fops = {
++	.owner = THIS_MODULE,
++	.open = goldfish_sync_open,
++	.release = goldfish_sync_release,
++	.unlocked_ioctl = goldfish_sync_ioctl,
++	.compat_ioctl = goldfish_sync_ioctl,
++};
++
++static struct miscdevice goldfish_sync_device = {
++	.name = "goldfish_sync",
++	.fops = &goldfish_sync_fops,
++};
++
++static bool setup_verify_batch_cmd_addr(struct goldfish_sync_state *sync_state,
++					void *batch_addr,
++					u32 addr_offset,
++					u32 addr_offset_high)
++{
++	u64 batch_addr_phys;
++	u32 batch_addr_phys_test_lo;
++	u32 batch_addr_phys_test_hi;
++
++	if (!batch_addr) {
++		pr_err("Could not use batch command address!");
++		return false;
++	}
++
++	batch_addr_phys = virt_to_phys(batch_addr);
++	writel((u32)(batch_addr_phys),
++	       sync_state->reg_base + addr_offset);
++	writel((u32)(batch_addr_phys >> 32),
++	       sync_state->reg_base + addr_offset_high);
++
++	batch_addr_phys_test_lo =
++		readl(sync_state->reg_base + addr_offset);
++	batch_addr_phys_test_hi =
++		readl(sync_state->reg_base + addr_offset_high);
++
++	if (virt_to_phys(batch_addr) !=
++			(((u64)batch_addr_phys_test_hi << 32) |
++			 batch_addr_phys_test_lo)) {
++		pr_err("Invalid batch command address!");
++		return false;
++	}
++
++	return true;
++}
++
++int goldfish_sync_probe(struct platform_device *pdev)
++{
++	struct resource *ioresource;
++	struct goldfish_sync_state *sync_state = global_sync_state;
++	int status;
++
++	DTRACE();
++
++	sync_state->to_do_end = 0;
++
++	spin_lock_init(&sync_state->lock);
++	mutex_init(&sync_state->mutex_lock);
++
++	platform_set_drvdata(pdev, sync_state);
++
++	ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!ioresource) {
++		pr_err("platform_get_resource failed");
++		return -ENODEV;
++	}
++
++	sync_state->reg_base =
++		devm_ioremap(&pdev->dev, ioresource->start, PAGE_SIZE);
++	if (!sync_state->reg_base) {
++		pr_err("Could not ioremap");
++		return -ENOMEM;
++	}
++
++	sync_state->irq = platform_get_irq(pdev, 0);
++	if (sync_state->irq < 0) {
++		pr_err("Could not platform_get_irq");
++		return -ENODEV;
++	}
++
++	status = devm_request_irq(&pdev->dev,
++				  sync_state->irq,
++				  goldfish_sync_interrupt,
++				  IRQF_SHARED,
++				  pdev->name,
++				  sync_state);
++	if (status) {
++		pr_err("request_irq failed");
++		return -ENODEV;
++	}
++
++	INIT_WORK(&sync_state->work_item,
++		  goldfish_sync_work_item_fn);
++
++	misc_register(&goldfish_sync_device);
++
++	/* Obtain addresses for batch send/recv of commands. */
++	{
++		struct goldfish_sync_hostcmd *batch_addr_hostcmd;
++		struct goldfish_sync_guestcmd *batch_addr_guestcmd;
++
++		batch_addr_hostcmd =
++			devm_kzalloc(&pdev->dev,
++				     sizeof(struct goldfish_sync_hostcmd),
++				     GFP_KERNEL);
++		batch_addr_guestcmd =
++			devm_kzalloc(&pdev->dev,
++				     sizeof(struct goldfish_sync_guestcmd),
++				     GFP_KERNEL);
++
++		if (!setup_verify_batch_cmd_addr(
++					sync_state,
++					batch_addr_hostcmd,
++					SYNC_REG_BATCH_COMMAND_ADDR,
++					SYNC_REG_BATCH_COMMAND_ADDR_HIGH)) {
++			pr_err("goldfish_sync: Could not setup batch command address");
++			return -ENODEV;
++		}
++
++		if (!setup_verify_batch_cmd_addr(
++				sync_state,
++				batch_addr_guestcmd,
++				SYNC_REG_BATCH_GUESTCOMMAND_ADDR,
++				SYNC_REG_BATCH_GUESTCOMMAND_ADDR_HIGH)) {
++			pr_err("goldfish_sync: Could not setup batch guest command address");
++			return -ENODEV;
++		}
++
++		sync_state->batch_hostcmd = batch_addr_hostcmd;
++		sync_state->batch_guestcmd = batch_addr_guestcmd;
++	}
++
++	pr_info("goldfish_sync: Initialized goldfish sync device");
++
++	writel(0, sync_state->reg_base + SYNC_REG_INIT);
++
++	return 0;
++}
++
++static int goldfish_sync_remove(struct platform_device *pdev)
++{
++	struct goldfish_sync_state *sync_state = global_sync_state;
++
++	DTRACE();
++
++	misc_deregister(&goldfish_sync_device);
++	memset(sync_state, 0, sizeof(struct goldfish_sync_state));
++	return 0;
++}
++
++static const struct of_device_id goldfish_sync_of_match[] = {
++	{ .compatible = "google,goldfish-sync", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, goldfish_sync_of_match);
++
++static const struct acpi_device_id goldfish_sync_acpi_match[] = {
++	{ "GFSH0006", 0 },
++	{ },
++};
++
++MODULE_DEVICE_TABLE(acpi, goldfish_sync_acpi_match);
++
++static struct platform_driver goldfish_sync = {
++	.probe = goldfish_sync_probe,
++	.remove = goldfish_sync_remove,
++	.driver = {
++		.name = "goldfish_sync",
++		.of_match_table = goldfish_sync_of_match,
++		.acpi_match_table = ACPI_PTR(goldfish_sync_acpi_match),
++	}
++};
++
++module_platform_driver(goldfish_sync);
++
++MODULE_AUTHOR("Google, Inc.");
++MODULE_DESCRIPTION("Android QEMU Sync Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("1.0");
+--- /dev/null
++++ b/drivers/staging/goldfish/goldfish_sync_timeline_fence.c
+@@ -0,0 +1,258 @@
++/*
++ * Timeline-based sync for Goldfish Sync
++ * Based on "Sync File validation framework"
++ * (drivers/dma-buf/sw_sync.c)
++ *
++ * Copyright (C) 2017 Google, Inc.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/syscalls.h>
++#include <linux/sync_file.h>
++#include <linux/dma-fence.h>
++
++#include "goldfish_sync_timeline_fence.h"
++
++/**
++ * struct goldfish_sync_timeline - sync object
++ * @kref:		reference count on fence.
++ * @name:		name of the goldfish_sync_timeline. Useful for debugging
++ * @child_list_head:	list of children sync_pts for goldfish_sync_timeline
++ * @child_list_lock:	lock protecting @child_list_head and fence.status
++ * @active_list_head:	list of active (unsignaled/errored) sync_pts
++ */
++struct goldfish_sync_timeline {
++	struct kref		kref;
++	char			name[32];
++
++	/* protected by child_list_lock */
++	u64			context;
++	int			value;
++
++	struct list_head	child_list_head;
++	/* protecting @child_list_head and fence.status */
++	spinlock_t		child_list_lock;
++
++	struct list_head	active_list_head;
++};
++
++static inline struct goldfish_sync_timeline *fence_parent(
++	struct dma_fence *fence)
++{
++	return container_of(fence->lock, struct goldfish_sync_timeline,
++				child_list_lock);
++}
++
++static const struct dma_fence_ops goldfish_sync_timeline_fence_ops;
++
++static inline struct sync_pt *goldfish_sync_fence_to_sync_pt(
++	struct dma_fence *fence)
++{
++	if (fence->ops != &goldfish_sync_timeline_fence_ops)
++		return NULL;
++	return container_of(fence, struct sync_pt, base);
++}
++
++/**
++ * goldfish_sync_timeline_create_internal() - creates a sync object
++ * @name:	sync_timeline name
++ *
++ * Creates a new sync_timeline. Returns the sync_timeline object or NULL in
++ * case of error.
++ */
++struct goldfish_sync_timeline
++*goldfish_sync_timeline_create_internal(const char *name)
++{
++	struct goldfish_sync_timeline *obj;
++
++	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
++	if (!obj)
++		return NULL;
++
++	kref_init(&obj->kref);
++	obj->context = dma_fence_context_alloc(1);
++	strlcpy(obj->name, name, sizeof(obj->name));
++
++	INIT_LIST_HEAD(&obj->child_list_head);
++	INIT_LIST_HEAD(&obj->active_list_head);
++	spin_lock_init(&obj->child_list_lock);
++
++	return obj;
++}
++
++static void goldfish_sync_timeline_free_internal(struct kref *kref)
++{
++	struct goldfish_sync_timeline *obj =
++		container_of(kref, struct goldfish_sync_timeline, kref);
++
++	kfree(obj);
++}
++
++static void goldfish_sync_timeline_get_internal(
++					struct goldfish_sync_timeline *obj)
++{
++	kref_get(&obj->kref);
++}
++
++void goldfish_sync_timeline_put_internal(struct goldfish_sync_timeline *obj)
++{
++	kref_put(&obj->kref, goldfish_sync_timeline_free_internal);
++}
++
++/**
++ * goldfish_sync_timeline_signal() -
++ * signal a status change on a goldfish_sync_timeline
++ * @obj:	sync_timeline to signal
++ * @inc:	num to increment on timeline->value
++ *
++ * A sync implementation should call this any time one of it's fences
++ * has signaled or has an error condition.
++ */
++void goldfish_sync_timeline_signal_internal(
++	struct goldfish_sync_timeline *obj, unsigned int inc)
++{
++	unsigned long flags;
++	struct sync_pt *pt, *next;
++
++	spin_lock_irqsave(&obj->child_list_lock, flags);
++
++	obj->value += inc;
++
++	list_for_each_entry_safe(pt, next, &obj->active_list_head,
++				 active_list) {
++		if (dma_fence_is_signaled_locked(&pt->base))
++			list_del_init(&pt->active_list);
++	}
++
++	spin_unlock_irqrestore(&obj->child_list_lock, flags);
++}
++
++/**
++ * goldfish_sync_pt_create_internal() - creates a sync pt
++ * @parent:	fence's parent sync_timeline
++ * @size:	size to allocate for this pt
++ * @inc:	value of the fence
++ *
++ * Creates a new sync_pt as a child of @parent.  @size bytes will be
++ * allocated allowing for implementation specific data to be kept after
++ * the generic sync_timeline struct. Returns the sync_pt object or
++ * NULL in case of error.
++ */
++struct sync_pt *goldfish_sync_pt_create_internal(
++	struct goldfish_sync_timeline *obj, int size, unsigned int value)
++{
++	unsigned long flags;
++	struct sync_pt *pt;
++
++	if (size < sizeof(*pt))
++		return NULL;
++
++	pt = kzalloc(size, GFP_KERNEL);
++	if (!pt)
++		return NULL;
++
++	spin_lock_irqsave(&obj->child_list_lock, flags);
++	goldfish_sync_timeline_get_internal(obj);
++	dma_fence_init(&pt->base, &goldfish_sync_timeline_fence_ops,
++		       &obj->child_list_lock, obj->context, value);
++	list_add_tail(&pt->child_list, &obj->child_list_head);
++	INIT_LIST_HEAD(&pt->active_list);
++	spin_unlock_irqrestore(&obj->child_list_lock, flags);
++	return pt;
++}
++
++static const char *goldfish_sync_timeline_fence_get_driver_name(
++	struct dma_fence *fence)
++{
++	return "sw_sync";
++}
++
++static const char *goldfish_sync_timeline_fence_get_timeline_name(
++	struct dma_fence *fence)
++{
++	struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++	return parent->name;
++}
++
++static void goldfish_sync_timeline_fence_release(struct dma_fence *fence)
++{
++	struct sync_pt *pt = goldfish_sync_fence_to_sync_pt(fence);
++	struct goldfish_sync_timeline *parent = fence_parent(fence);
++	unsigned long flags;
++
++	spin_lock_irqsave(fence->lock, flags);
++	list_del(&pt->child_list);
++	if (!list_empty(&pt->active_list))
++		list_del(&pt->active_list);
++	spin_unlock_irqrestore(fence->lock, flags);
++
++	goldfish_sync_timeline_put_internal(parent);
++	dma_fence_free(fence);
++}
++
++static bool goldfish_sync_timeline_fence_signaled(struct dma_fence *fence)
++{
++	struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++	return (fence->seqno > parent->value) ? false : true;
++}
++
++static bool goldfish_sync_timeline_fence_enable_signaling(
++	struct dma_fence *fence)
++{
++	struct sync_pt *pt = goldfish_sync_fence_to_sync_pt(fence);
++	struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++	if (goldfish_sync_timeline_fence_signaled(fence))
++		return false;
++
++	list_add_tail(&pt->active_list, &parent->active_list_head);
++	return true;
++}
++
++static void goldfish_sync_timeline_fence_disable_signaling(
++	struct dma_fence *fence)
++{
++	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
++
++	list_del_init(&pt->active_list);
++}
++
++static void goldfish_sync_timeline_fence_value_str(
++	struct dma_fence *fence, char *str, int size)
++{
++	snprintf(str, size, "%d", fence->seqno);
++}
++
++static void goldfish_sync_timeline_fence_timeline_value_str(
++	struct dma_fence *fence,
++	char *str, int size)
++{
++	struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++	snprintf(str, size, "%d", parent->value);
++}
++
++static const struct dma_fence_ops goldfish_sync_timeline_fence_ops = {
++	.get_driver_name = goldfish_sync_timeline_fence_get_driver_name,
++	.get_timeline_name = goldfish_sync_timeline_fence_get_timeline_name,
++	.enable_signaling = goldfish_sync_timeline_fence_enable_signaling,
++	.disable_signaling = goldfish_sync_timeline_fence_disable_signaling,
++	.signaled = goldfish_sync_timeline_fence_signaled,
++	.wait = dma_fence_default_wait,
++	.release = goldfish_sync_timeline_fence_release,
++	.fence_value_str = goldfish_sync_timeline_fence_value_str,
++	.timeline_value_str = goldfish_sync_timeline_fence_timeline_value_str,
++};
+--- /dev/null
++++ b/drivers/staging/goldfish/goldfish_sync_timeline_fence.h
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (C) 2016 Google, Inc.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/sync_file.h>
++#include <linux/dma-fence.h>
++
++/**
++ * struct sync_pt - sync_pt object
++ * @base: base fence object
++ * @child_list: sync timeline child's list
++ * @active_list: sync timeline active child's list
++ */
++struct sync_pt {
++	struct dma_fence base;
++	struct list_head child_list;
++	struct list_head active_list;
++};
++
++/**
++ * goldfish_sync_timeline_create_internal() - creates a sync object
++ * @name:	goldfish_sync_timeline name
++ *
++ * Creates a new goldfish_sync_timeline.
++ * Returns the goldfish_sync_timeline object or NULL in case of error.
++ */
++struct goldfish_sync_timeline
++*goldfish_sync_timeline_create_internal(const char *name);
++
++/**
++ * goldfish_sync_pt_create_internal() - creates a sync pt
++ * @parent:	fence's parent goldfish_sync_timeline
++ * @size:	size to allocate for this pt
++ * @inc:	value of the fence
++ *
++ * Creates a new sync_pt as a child of @parent.  @size bytes will be
++ * allocated allowing for implementation specific data to be kept after
++ * the generic sync_timeline struct. Returns the sync_pt object or
++ * NULL in case of error.
++ */
++struct sync_pt
++*goldfish_sync_pt_create_internal(
++	struct goldfish_sync_timeline *obj, int size, unsigned int value);
++
++/**
++ * goldfish_sync_timeline_signal_internal() -
++ * signal a status change on a sync_timeline
++ * @obj:	goldfish_sync_timeline to signal
++ * @inc:	num to increment on timeline->value
++ *
++ * A sync implementation should call this any time one of it's fences
++ * has signaled or has an error condition.
++ */
++void goldfish_sync_timeline_signal_internal(
++	struct goldfish_sync_timeline *obj, unsigned int inc);
++
++/**
++ * goldfish_sync_timeline_put_internal() - dec refcount of a sync_timeline
++ * and clean up memory if it was the last ref.
++ * @obj:	goldfish_sync_timeline to decref
++ */
++void goldfish_sync_timeline_put_internal(struct goldfish_sync_timeline *obj);
diff --git a/series b/series
index 10ecdfd..41096ea 100644
--- a/series
+++ b/series
@@ -1,3 +1,6 @@
+0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch
+0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch
+0003-goldfish-Add-goldfish-sync-driver.patch
 eventpoll.h-fix-epoll-event-masks.patch
 eventpoll.h-add-missing-epoll-event-masks.patch
 0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch