[PATCH 11/15] platform: goldfish: pipe: Split the driver to v2 specific and the rest

2018-10-02 Thread rkir
From: Roman Kiryanov 

Move probe/remove and other driver stuff to a separate file
to plug v1 there later.

Signed-off-by: Roman Kiryanov 
---
 drivers/platform/goldfish/Makefile   |   3 +-
 drivers/platform/goldfish/goldfish_pipe.c| 124 +++
 drivers/platform/goldfish/goldfish_pipe.h|  10 ++
 drivers/platform/goldfish/goldfish_pipe_v2.c | 112 +++--
 drivers/platform/goldfish/goldfish_pipe_v2.h |  10 ++
 5 files changed, 161 insertions(+), 98 deletions(-)
 create mode 100644 drivers/platform/goldfish/goldfish_pipe.c
 create mode 100644 drivers/platform/goldfish/goldfish_pipe.h
 create mode 100644 drivers/platform/goldfish/goldfish_pipe_v2.h

diff --git a/drivers/platform/goldfish/Makefile 
b/drivers/platform/goldfish/Makefile
index 81f899a987a2..016769e003d8 100644
--- a/drivers/platform/goldfish/Makefile
+++ b/drivers/platform/goldfish/Makefile
@@ -1,4 +1,5 @@
 #
 # Makefile for Goldfish platform specific drivers
 #
-obj-$(CONFIG_GOLDFISH_PIPE)+= goldfish_pipe_v2.o
+obj-$(CONFIG_GOLDFISH_PIPE)+= goldfish_pipe_all.o
+goldfish_pipe_all-objs := goldfish_pipe.o goldfish_pipe_v2.o
diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
new file mode 100644
index ..792b20bdf76c
--- /dev/null
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/* 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 = "";
+ *if (write(fd, msg, strlen(msg)+1) < 0) {
+ *   ... could not connect to  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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "goldfish_pipe_qemu.h"
+#include "goldfish_pipe.h"
+#include "goldfish_pipe_v2.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
+};
+
+static int goldfish_pipe_probe(struct platform_device *pdev)
+{
+   struct resource *r;
+   char __iomem *base;
+   int irq;
+   int version;
+
+   r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!r || resource_size(r) < PAGE_SIZE) {
+   dev_err(>dev, "can't allocate i/o page\n");
+   return -EINVAL;
+   }
+   base = devm_ioremap(>dev, r->start, PAGE_SIZE);
+   if (!base) {
+   dev_err(>dev, "ioremap failed\n");
+   return -EINVAL;
+   }
+
+   r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+   if (!r)
+   return -EINVAL;
+
+   irq = r->start;
+
+   /*
+* 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(PIPE_DRIVER_VERSION, base + PIPE_REG_VERSION);
+   version = readl(base + PIPE_REG_VERSION);
+
+   if (WARN_ON(version < PIPE_CURRENT_DEVICE_VERSION))
+   return -EINVAL;
+
+   return goldfish_pipe_device_init(pdev, base, irq);
+}
+
+static int goldfish_pipe_remove(struct platform_device *pdev)
+{
+   struct goldfish_pipe_dev_base *dev = platform_get_drvdata(pdev);
+
+   return dev->deinit(dev, pdev);
+}
+
+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_driver = {
+   .probe = goldfish_pipe_probe,
+   .remove = goldfish_pipe_remove,
+   .driver = {

[PATCH 11/15] platform: goldfish: pipe: Split the driver to v2 specific and the rest

2018-10-02 Thread rkir
From: Roman Kiryanov 

Move probe/remove and other driver stuff to a separate file
to plug v1 there later.

Signed-off-by: Roman Kiryanov 
---
 drivers/platform/goldfish/Makefile   |   3 +-
 drivers/platform/goldfish/goldfish_pipe.c| 124 +++
 drivers/platform/goldfish/goldfish_pipe.h|  10 ++
 drivers/platform/goldfish/goldfish_pipe_v2.c | 112 +++--
 drivers/platform/goldfish/goldfish_pipe_v2.h |  10 ++
 5 files changed, 161 insertions(+), 98 deletions(-)
 create mode 100644 drivers/platform/goldfish/goldfish_pipe.c
 create mode 100644 drivers/platform/goldfish/goldfish_pipe.h
 create mode 100644 drivers/platform/goldfish/goldfish_pipe_v2.h

diff --git a/drivers/platform/goldfish/Makefile 
b/drivers/platform/goldfish/Makefile
index 81f899a987a2..016769e003d8 100644
--- a/drivers/platform/goldfish/Makefile
+++ b/drivers/platform/goldfish/Makefile
@@ -1,4 +1,5 @@
 #
 # Makefile for Goldfish platform specific drivers
 #
-obj-$(CONFIG_GOLDFISH_PIPE)+= goldfish_pipe_v2.o
+obj-$(CONFIG_GOLDFISH_PIPE)+= goldfish_pipe_all.o
+goldfish_pipe_all-objs := goldfish_pipe.o goldfish_pipe_v2.o
diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
new file mode 100644
index ..792b20bdf76c
--- /dev/null
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/* 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 = "";
+ *if (write(fd, msg, strlen(msg)+1) < 0) {
+ *   ... could not connect to  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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "goldfish_pipe_qemu.h"
+#include "goldfish_pipe.h"
+#include "goldfish_pipe_v2.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
+};
+
+static int goldfish_pipe_probe(struct platform_device *pdev)
+{
+   struct resource *r;
+   char __iomem *base;
+   int irq;
+   int version;
+
+   r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!r || resource_size(r) < PAGE_SIZE) {
+   dev_err(>dev, "can't allocate i/o page\n");
+   return -EINVAL;
+   }
+   base = devm_ioremap(>dev, r->start, PAGE_SIZE);
+   if (!base) {
+   dev_err(>dev, "ioremap failed\n");
+   return -EINVAL;
+   }
+
+   r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+   if (!r)
+   return -EINVAL;
+
+   irq = r->start;
+
+   /*
+* 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(PIPE_DRIVER_VERSION, base + PIPE_REG_VERSION);
+   version = readl(base + PIPE_REG_VERSION);
+
+   if (WARN_ON(version < PIPE_CURRENT_DEVICE_VERSION))
+   return -EINVAL;
+
+   return goldfish_pipe_device_init(pdev, base, irq);
+}
+
+static int goldfish_pipe_remove(struct platform_device *pdev)
+{
+   struct goldfish_pipe_dev_base *dev = platform_get_drvdata(pdev);
+
+   return dev->deinit(dev, pdev);
+}
+
+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_driver = {
+   .probe = goldfish_pipe_probe,
+   .remove = goldfish_pipe_remove,
+   .driver = {