From 7bc6faaca7d829d4e6f5d65909d5068f73b76bda Mon Sep 17 00:00:00 2001
From: Johan Hovold <johan@hovoldconsulting.com>
Date: Tue, 3 Nov 2015 18:03:22 +0100
Subject: [PATCH] greybus: create host-device compilation unit

Move everything host-device related to hd.c and hd.h.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
---
 drivers/staging/greybus/Makefile  |   1 +
 drivers/staging/greybus/core.c    | 100 --------------------------
 drivers/staging/greybus/greybus.h |  48 +------------
 drivers/staging/greybus/hd.c      | 115 ++++++++++++++++++++++++++++++
 drivers/staging/greybus/hd.h      |  61 ++++++++++++++++
 5 files changed, 178 insertions(+), 147 deletions(-)
 create mode 100644 drivers/staging/greybus/hd.c
 create mode 100644 drivers/staging/greybus/hd.h

diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile
index b8dc36b196aae..ba60430ef760a 100644
--- a/drivers/staging/greybus/Makefile
+++ b/drivers/staging/greybus/Makefile
@@ -1,5 +1,6 @@
 greybus-y :=	core.o		\
 		debugfs.o	\
+		hd.o		\
 		manifest.o	\
 		endo.o		\
 		module.o	\
diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c
index 726bf6480af33..4396f90e65d66 100644
--- a/drivers/staging/greybus/core.c
+++ b/drivers/staging/greybus/core.c
@@ -146,106 +146,6 @@ void greybus_deregister_driver(struct greybus_driver *driver)
 }
 EXPORT_SYMBOL_GPL(greybus_deregister_driver);
 
-
-static DEFINE_MUTEX(hd_mutex);
-
-static void free_hd(struct kref *kref)
-{
-	struct greybus_host_device *hd;
-
-	hd = container_of(kref, struct greybus_host_device, kref);
-
-	ida_destroy(&hd->cport_id_map);
-	kfree(hd);
-	mutex_unlock(&hd_mutex);
-}
-
-struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver,
-					      struct device *parent,
-					      size_t buffer_size_max,
-					      size_t num_cports)
-{
-	struct greybus_host_device *hd;
-
-	/*
-	 * Validate that the driver implements all of the callbacks
-	 * so that we don't have to every time we make them.
-	 */
-	if ((!driver->message_send) || (!driver->message_cancel)) {
-		pr_err("Must implement all greybus_host_driver callbacks!\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (buffer_size_max < GB_OPERATION_MESSAGE_SIZE_MIN) {
-		dev_err(parent, "greybus host-device buffers too small\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (num_cports == 0 || num_cports > CPORT_ID_MAX) {
-		dev_err(parent, "Invalid number of CPorts: %zu\n", num_cports);
-		return ERR_PTR(-EINVAL);
-	}
-
-	/*
-	 * Make sure to never allocate messages larger than what the Greybus
-	 * protocol supports.
-	 */
-	if (buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) {
-		dev_warn(parent, "limiting buffer size to %u\n",
-			 GB_OPERATION_MESSAGE_SIZE_MAX);
-		buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX;
-	}
-
-	hd = kzalloc(sizeof(*hd) + driver->hd_priv_size, GFP_KERNEL);
-	if (!hd)
-		return ERR_PTR(-ENOMEM);
-
-	kref_init(&hd->kref);
-	hd->parent = parent;
-	hd->driver = driver;
-	INIT_LIST_HEAD(&hd->interfaces);
-	INIT_LIST_HEAD(&hd->connections);
-	ida_init(&hd->cport_id_map);
-	hd->buffer_size_max = buffer_size_max;
-	hd->num_cports = num_cports;
-
-	/*
-	 * Initialize AP's SVC protocol connection:
-	 *
-	 * This is required as part of early initialization of the host device
-	 * as we need this connection in order to start any kind of message
-	 * exchange between the AP and the SVC. SVC will start with a
-	 * 'get-version' request followed by a 'svc-hello' message and at that
-	 * time we will create a fully initialized svc-connection, as we need
-	 * endo-id and AP's interface id for that.
-	 */
-	if (!gb_ap_svc_connection_create(hd)) {
-		kref_put_mutex(&hd->kref, free_hd, &hd_mutex);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	return hd;
-}
-EXPORT_SYMBOL_GPL(greybus_create_hd);
-
-void greybus_remove_hd(struct greybus_host_device *hd)
-{
-	/*
-	 * Tear down all interfaces, modules, and the endo that is associated
-	 * with this host controller before freeing the memory associated with
-	 * the host controller.
-	 */
-	gb_interfaces_remove(hd);
-	gb_endo_remove(hd->endo);
-
-	/* Is the SVC still using the partially uninitialized connection ? */
-	if (hd->initial_svc_connection)
-		gb_connection_destroy(hd->initial_svc_connection);
-
-	kref_put_mutex(&hd->kref, free_hd, &hd_mutex);
-}
-EXPORT_SYMBOL_GPL(greybus_remove_hd);
-
 static int __init gb_init(void)
 {
 	int retval;
diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h
index 219b2ff765588..8eb63e020c2d4 100644
--- a/drivers/staging/greybus/greybus.h
+++ b/drivers/staging/greybus/greybus.h
@@ -25,6 +25,7 @@
 #include "greybus_manifest.h"
 #include "greybus_protocols.h"
 #include "manifest.h"
+#include "hd.h"
 #include "endo.h"
 #include "svc.h"
 #include "firmware.h"
@@ -57,53 +58,6 @@
 #define CPORT_ID_MAX	4095		/* UniPro max id is 4095 */
 #define CPORT_ID_BAD	U16_MAX
 
-struct greybus_host_device;
-
-/* Greybus "Host driver" structure, needed by a host controller driver to be
- * able to handle both SVC control as well as "real" greybus messages
- */
-struct greybus_host_driver {
-	size_t	hd_priv_size;
-
-	int (*cport_enable)(struct greybus_host_device *hd, u16 cport_id);
-	int (*cport_disable)(struct greybus_host_device *hd, u16 cport_id);
-	int (*message_send)(struct greybus_host_device *hd, u16 dest_cport_id,
-			struct gb_message *message, gfp_t gfp_mask);
-	void (*message_cancel)(struct gb_message *message);
-	int (*latency_tag_enable)(struct greybus_host_device *hd, u16 cport_id);
-	int (*latency_tag_disable)(struct greybus_host_device *hd,
-				   u16 cport_id);
-};
-
-struct greybus_host_device {
-	struct kref kref;
-	struct device *parent;
-	const struct greybus_host_driver *driver;
-
-	struct list_head interfaces;
-	struct list_head connections;
-	struct ida cport_id_map;
-
-	/* Number of CPorts supported by the UniPro IP */
-	size_t num_cports;
-
-	/* Host device buffer constraints */
-	size_t buffer_size_max;
-
-	struct gb_endo *endo;
-	struct gb_connection *initial_svc_connection;
-	struct gb_svc *svc;
-
-	/* Private data for the host driver */
-	unsigned long hd_priv[0] __aligned(sizeof(s64));
-};
-
-struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *hd,
-					      struct device *parent,
-					      size_t buffer_size_max,
-					      size_t num_cports);
-void greybus_remove_hd(struct greybus_host_device *hd);
-
 struct greybus_driver {
 	const char *name;
 
diff --git a/drivers/staging/greybus/hd.c b/drivers/staging/greybus/hd.c
new file mode 100644
index 0000000000000..3ac85077b431c
--- /dev/null
+++ b/drivers/staging/greybus/hd.c
@@ -0,0 +1,115 @@
+/*
+ * Greybus Host Device
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "greybus.h"
+
+static DEFINE_MUTEX(hd_mutex);
+
+
+static void free_hd(struct kref *kref)
+{
+	struct greybus_host_device *hd;
+
+	hd = container_of(kref, struct greybus_host_device, kref);
+
+	ida_destroy(&hd->cport_id_map);
+	kfree(hd);
+	mutex_unlock(&hd_mutex);
+}
+
+struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver,
+					      struct device *parent,
+					      size_t buffer_size_max,
+					      size_t num_cports)
+{
+	struct greybus_host_device *hd;
+
+	/*
+	 * Validate that the driver implements all of the callbacks
+	 * so that we don't have to every time we make them.
+	 */
+	if ((!driver->message_send) || (!driver->message_cancel)) {
+		pr_err("Must implement all greybus_host_driver callbacks!\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (buffer_size_max < GB_OPERATION_MESSAGE_SIZE_MIN) {
+		dev_err(parent, "greybus host-device buffers too small\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (num_cports == 0 || num_cports > CPORT_ID_MAX) {
+		dev_err(parent, "Invalid number of CPorts: %zu\n", num_cports);
+		return ERR_PTR(-EINVAL);
+	}
+
+	/*
+	 * Make sure to never allocate messages larger than what the Greybus
+	 * protocol supports.
+	 */
+	if (buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) {
+		dev_warn(parent, "limiting buffer size to %u\n",
+			 GB_OPERATION_MESSAGE_SIZE_MAX);
+		buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX;
+	}
+
+	hd = kzalloc(sizeof(*hd) + driver->hd_priv_size, GFP_KERNEL);
+	if (!hd)
+		return ERR_PTR(-ENOMEM);
+
+	kref_init(&hd->kref);
+	hd->parent = parent;
+	hd->driver = driver;
+	INIT_LIST_HEAD(&hd->interfaces);
+	INIT_LIST_HEAD(&hd->connections);
+	ida_init(&hd->cport_id_map);
+	hd->buffer_size_max = buffer_size_max;
+	hd->num_cports = num_cports;
+
+	/*
+	 * Initialize AP's SVC protocol connection:
+	 *
+	 * This is required as part of early initialization of the host device
+	 * as we need this connection in order to start any kind of message
+	 * exchange between the AP and the SVC. SVC will start with a
+	 * 'get-version' request followed by a 'svc-hello' message and at that
+	 * time we will create a fully initialized svc-connection, as we need
+	 * endo-id and AP's interface id for that.
+	 */
+	if (!gb_ap_svc_connection_create(hd)) {
+		kref_put_mutex(&hd->kref, free_hd, &hd_mutex);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return hd;
+}
+EXPORT_SYMBOL_GPL(greybus_create_hd);
+
+void greybus_remove_hd(struct greybus_host_device *hd)
+{
+	/*
+	 * Tear down all interfaces, modules, and the endo that is associated
+	 * with this host controller before freeing the memory associated with
+	 * the host controller.
+	 */
+	gb_interfaces_remove(hd);
+	gb_endo_remove(hd->endo);
+
+	/* Is the SVC still using the partially uninitialized connection ? */
+	if (hd->initial_svc_connection)
+		gb_connection_destroy(hd->initial_svc_connection);
+
+	kref_put_mutex(&hd->kref, free_hd, &hd_mutex);
+}
+EXPORT_SYMBOL_GPL(greybus_remove_hd);
diff --git a/drivers/staging/greybus/hd.h b/drivers/staging/greybus/hd.h
new file mode 100644
index 0000000000000..df953d43a634e
--- /dev/null
+++ b/drivers/staging/greybus/hd.h
@@ -0,0 +1,61 @@
+/*
+ * Greybus Host Device
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __HD_H
+#define __HD_H
+
+struct greybus_host_device;
+struct gb_message;
+
+/* Greybus "Host driver" structure, needed by a host controller driver to be
+ * able to handle both SVC control as well as "real" greybus messages
+ */
+struct greybus_host_driver {
+	size_t	hd_priv_size;
+
+	int (*cport_enable)(struct greybus_host_device *hd, u16 cport_id);
+	int (*cport_disable)(struct greybus_host_device *hd, u16 cport_id);
+	int (*message_send)(struct greybus_host_device *hd, u16 dest_cport_id,
+			struct gb_message *message, gfp_t gfp_mask);
+	void (*message_cancel)(struct gb_message *message);
+	int (*latency_tag_enable)(struct greybus_host_device *hd, u16 cport_id);
+	int (*latency_tag_disable)(struct greybus_host_device *hd,
+				   u16 cport_id);
+};
+
+struct greybus_host_device {
+	struct kref kref;
+	struct device *parent;
+	const struct greybus_host_driver *driver;
+
+	struct list_head interfaces;
+	struct list_head connections;
+	struct ida cport_id_map;
+
+	/* Number of CPorts supported by the UniPro IP */
+	size_t num_cports;
+
+	/* Host device buffer constraints */
+	size_t buffer_size_max;
+
+	struct gb_endo *endo;
+	struct gb_connection *initial_svc_connection;
+	struct gb_svc *svc;
+
+	/* Private data for the host driver */
+	unsigned long hd_priv[0] __aligned(sizeof(s64));
+};
+
+struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *hd,
+					      struct device *parent,
+					      size_t buffer_size_max,
+					      size_t num_cports);
+void greybus_remove_hd(struct greybus_host_device *hd);
+
+#endif	/* __HD_H */
-- 
2.30.2