greybus: create host-device compilation unit
authorJohan Hovold <johan@hovoldconsulting.com>
Tue, 3 Nov 2015 17:03:22 +0000 (18:03 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 Nov 2015 04:25:57 +0000 (20:25 -0800)
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
drivers/staging/greybus/core.c
drivers/staging/greybus/greybus.h
drivers/staging/greybus/hd.c [new file with mode: 0644]
drivers/staging/greybus/hd.h [new file with mode: 0644]

index b8dc36b196aae959a640c2ea2d6fc315424f1196..ba60430ef760acd0ca584c7fa0ae30aee734972a 100644 (file)
@@ -1,5 +1,6 @@
 greybus-y :=   core.o          \
                debugfs.o       \
+               hd.o            \
                manifest.o      \
                endo.o          \
                module.o        \
index 726bf6480af33c90ff2ef3bc691b86567cb4b042..4396f90e65d66c4748796bf0e4be4b605e1f45ec 100644 (file)
@@ -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;
index 219b2ff7655889cbbab927f7808203d3f948c5ca..8eb63e020c2d49e31ae1e7d9cd42b087fa50ddcc 100644 (file)
@@ -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"
 #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 (file)
index 0000000..3ac8507
--- /dev/null
@@ -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 (file)
index 0000000..df953d4
--- /dev/null
@@ -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 */