diff --git a/drivers/misc/qemupipe/qemu_pipe.c b/drivers/misc/qemupipe/qemu_pipe.c
index e5c47cd683ac45d3c798c08699d8141f2a87b307..25196082cc24ca12942a138850c5322ae4f42b95 100644
--- a/drivers/misc/qemupipe/qemu_pipe.c
+++ b/drivers/misc/qemupipe/qemu_pipe.c
@@ -81,6 +81,9 @@
 #define PIPE_REG_SIZE               0x0c  /* read/write: buffer size */
 #define PIPE_REG_ADDRESS            0x10  /* 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 */
 
 /* list of commands for PIPE_REG_COMMAND */
 #define CMD_OPEN               1  /* open new channel */
@@ -117,6 +120,16 @@
 #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{
+	uint32_t channel;
+	uint32_t size;
+	uint32_t address;
+	uint32_t cmd;
+	uint32_t result;
+	/* reserved for future extension */
+	uint32_t 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.
@@ -124,6 +137,7 @@
 struct qemu_pipe_dev {
 	spinlock_t lock;
 	unsigned char __iomem *base;
+	struct access_params *aps;
 	int irq;
 };
 
@@ -163,6 +177,73 @@ static int qemu_pipe_error_convert(int status)
 	return status;
 }
 
+/*
+ * Notice: QEMU will return 0 for un-known register access, indicating
+ * param_acess is supported or not
+ */
+static int valid_batchbuffer_addr(struct qemu_pipe_dev *dev,
+				  struct access_params *aps)
+{
+	uint32_t aph, apl;
+	uint64_t paddr;
+	aph = readl(dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
+	apl = readl(dev->base + PIPE_REG_PARAMS_ADDR_LOW);
+
+	paddr = ((uint64_t)aph << 32) | apl;
+	if (paddr != (__pa(aps)))
+	    return 0;
+	return 1;
+}
+
+/* 0 on success */
+static int setup_access_params_addr(struct qemu_pipe_dev *dev)
+{
+	uint64_t paddr;
+	struct access_params *aps;
+
+	aps = kmalloc(sizeof(struct access_params), GFP_KERNEL);
+	if (!aps)
+	    return -1;
+
+	paddr = __pa(aps);
+	writel((uint32_t)(paddr >> 32),
+	  dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
+	writel((uint32_t)paddr,
+	  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 qemu_pipe_dev *dev, const int cmd,
+                             unsigned long address, unsigned long avail,
+                             struct qemu_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 is not changed, or that means batch command failed */
+	if (aps->result == INITIAL_BATCH_RESULT)
+	    return -1;
+	*status = aps->result;
+	return 0;
+}
+
 /* This function is used for both reading from and writing to a given
  * pipe.
  */
@@ -235,12 +316,16 @@ static ssize_t qemu_pipe_read_write(struct file *filp, char __user *buffer,
 
 		/* Now, try to transfer the bytes in the current page */
 		spin_lock_irqsave(&dev->lock, irq_flags);
-		writel((unsigned long)pipe, dev->base + PIPE_REG_CHANNEL);
-		writel(avail, dev->base + PIPE_REG_SIZE);
-		writel(address, dev->base + PIPE_REG_ADDRESS);
-		writel(CMD_WRITE_BUFFER + cmd_offset,
-			dev->base + PIPE_REG_COMMAND);
-		status = readl(dev->base + PIPE_REG_STATUS);
+		if (access_with_param(dev, CMD_WRITE_BUFFER + cmd_offset, address,
+		      avail, pipe, &status))
+		{
+		    writel((unsigned long)pipe, dev->base + PIPE_REG_CHANNEL);
+		    writel(avail, dev->base + PIPE_REG_SIZE);
+		    writel(address, dev->base + PIPE_REG_ADDRESS);
+		    writel(CMD_WRITE_BUFFER + cmd_offset,
+		      dev->base + PIPE_REG_COMMAND);
+		    status = readl(dev->base + PIPE_REG_STATUS);
+		}
 		spin_unlock_irqrestore(&dev->lock, irq_flags);
 
 		if (status > 0) { /* Correct transfer */
@@ -517,6 +602,7 @@ static int qemu_pipe_probe(struct platform_device *pdev)
 	if (err)
 		goto err_misc_register;
 
+	setup_access_params_addr(dev);
 	return 0;
 
 err_misc_register:
@@ -537,6 +623,8 @@ static int qemu_pipe_remove(struct platform_device *pdev)
 	free_irq(dev->irq, pdev);
 
 	iounmap(dev->base);
+	if (dev->aps)
+		kfree(dev->aps);
 	dev->base = NULL;
 
 	return 0;