greybus: isolate greybus module code
authorAlex Elder <elder@linaro.org>
Thu, 2 Oct 2014 02:54:11 +0000 (21:54 -0500)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 3 Oct 2014 04:17:20 +0000 (21:17 -0700)
Define new source files "module.h" and "module.c" to separate the
definitions of the Greybus module abstraction from other code.

Rename "greybus_module" to be "gb_module", for brevity.  Do the same
for a few other symbols with "greybus_module" in their names.  A few
(like greybus_module_id) are more visible outside this kernel module
so we'll keep their names more descriptive.

Add a definition for U8_MAX in "kernel_ver.h" (it appeared in 3.14).

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
13 files changed:
drivers/staging/greybus/Makefile
drivers/staging/greybus/battery-gb.c
drivers/staging/greybus/core.c
drivers/staging/greybus/gbuf.c
drivers/staging/greybus/gpio-gb.c
drivers/staging/greybus/greybus.h
drivers/staging/greybus/i2c-gb.c
drivers/staging/greybus/module.c [new file with mode: 0644]
drivers/staging/greybus/module.h [new file with mode: 0644]
drivers/staging/greybus/sdio-gb.c
drivers/staging/greybus/sysfs.c
drivers/staging/greybus/test_sink.c
drivers/staging/greybus/uart-gb.c

index 2e048a010a2361933ff360b384cfd17e15e95523..9b5d8e9684a64b1d383ee9715f7a1f7b457f2bae 100644 (file)
@@ -3,6 +3,7 @@ greybus-y :=    core.o          \
                sysfs.o         \
                debugfs.o       \
                ap.o            \
+               module.o        \
                i2c-gb.o        \
                gpio-gb.o       \
                sdio-gb.o       \
index 5f1bf004dfbc8f80f06304591ff730fea7eaaf99..1ef2f17623b0b69e2c4da5d8eb4e76570a7fa3ea 100644 (file)
@@ -18,7 +18,7 @@ struct gb_battery {
        // we will want to keep the battery stats in here as we will be getting
        // updates from the SVC "on the fly" so we don't have to always go ask
        // the battery for some information.  Hopefully...
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
 };
 #define to_gb_battery(x) container_of(x, struct gb_battery, bat)
 
@@ -100,7 +100,7 @@ static enum power_supply_property battery_props[] = {
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
-int gb_battery_probe(struct greybus_module *gmod,
+int gb_battery_probe(struct gb_module *gmod,
                     const struct greybus_module_id *id)
 {
        struct gb_battery *gb;
@@ -130,7 +130,7 @@ int gb_battery_probe(struct greybus_module *gmod,
        return 0;
 }
 
-void gb_battery_disconnect(struct greybus_module *gmod)
+void gb_battery_disconnect(struct gb_module *gmod)
 {
        struct gb_battery *gb;
 
index e93ee40bb0db8cb7818958c1bedb889edacdf4a9..934bdebe039cae447648a43f0f6eaa3f7c48c343 100644 (file)
@@ -30,51 +30,13 @@ int greybus_disabled(void)
 }
 EXPORT_SYMBOL_GPL(greybus_disabled);
 
-static int greybus_match_one_id(struct greybus_module *gmod,
-                               const struct greybus_module_id *id)
-{
-       struct greybus_descriptor_module *module;
-
-       module = &gmod->module;
-
-       if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_VENDOR) &&
-           (id->vendor != le16_to_cpu(module->vendor)))
-               return 0;
-
-       if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_PRODUCT) &&
-           (id->product != le16_to_cpu(module->product)))
-               return 0;
-
-       if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
-           (id->serial_number != le64_to_cpu(module->serial_number)))
-               return 0;
-
-       return 1;
-}
-
-static const struct greybus_module_id *greybus_match_id(
-               struct greybus_module *gmod,
-               const struct greybus_module_id *id)
-{
-       if (id == NULL)
-               return NULL;
-
-       for (; id->vendor || id->product || id->serial_number ||
-              id->driver_info ; id++) {
-               if (greybus_match_one_id(gmod, id))
-                       return id;
-       }
-
-       return NULL;
-}
-
 static int greybus_module_match(struct device *dev, struct device_driver *drv)
 {
        struct greybus_driver *driver = to_greybus_driver(dev->driver);
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
        const struct greybus_module_id *id;
 
-       id = greybus_match_id(gmod, driver->id_table);
+       id = gb_module_match_id(gmod, driver->id_table);
        if (id)
                return 1;
        /* FIXME - Dyanmic ids? */
@@ -83,7 +45,7 @@ static int greybus_module_match(struct device *dev, struct device_driver *drv)
 
 static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       /* struct greybus_module *gmod = to_greybus_module(dev); */
+       /* struct gb_module *gmod = to_gb_module(dev); */
 
        /* FIXME - add some uevents here... */
        return 0;
@@ -98,12 +60,12 @@ static struct bus_type greybus_bus_type = {
 static int greybus_probe(struct device *dev)
 {
        struct greybus_driver *driver = to_greybus_driver(dev->driver);
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
        const struct greybus_module_id *id;
        int retval;
 
        /* match id */
-       id = greybus_match_id(gmod, driver->id_table);
+       id = gb_module_match_id(gmod, driver->id_table);
        if (!id)
                return -ENODEV;
 
@@ -117,7 +79,7 @@ static int greybus_probe(struct device *dev)
 static int greybus_remove(struct device *dev)
 {
        struct greybus_driver *driver = to_greybus_driver(dev->driver);
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
 
        driver->disconnect(gmod);
        return 0;
@@ -155,7 +117,7 @@ EXPORT_SYMBOL_GPL(greybus_deregister);
 
 static void greybus_module_release(struct device *dev)
 {
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
        int i;
 
        for (i = 0; i < gmod->num_strings; ++i)
@@ -164,7 +126,7 @@ static void greybus_module_release(struct device *dev)
 }
 
 
-const u8 *greybus_string(struct greybus_module *gmod, int id)
+const u8 *greybus_string(struct gb_module *gmod, int id)
 {
        int i;
        struct gmod_string *string;
@@ -185,7 +147,7 @@ static struct device_type greybus_module_type = {
        .release =      greybus_module_release,
 };
 
-static int gb_init_subdevs(struct greybus_module *gmod,
+static int gb_init_subdevs(struct gb_module *gmod,
                           const struct greybus_module_id *id)
 {
        int retval;
@@ -228,11 +190,11 @@ error_i2c:
        return retval;
 }
 
-static const struct greybus_module_id fake_gb_id = {
+static const struct greybus_module_id fake_greybus_module_id = {
        GREYBUS_DEVICE(0x42, 0x42)
 };
 
-static int create_module(struct greybus_module *gmod,
+static int create_module(struct gb_module *gmod,
                            struct greybus_descriptor_module *module,
                            size_t desc_size)
 {
@@ -245,7 +207,7 @@ static int create_module(struct greybus_module *gmod,
        return 0;
 }
 
-static int create_string(struct greybus_module *gmod,
+static int create_string(struct gb_module *gmod,
                         struct greybus_descriptor_string *string,
                         size_t desc_size)
 {
@@ -279,7 +241,7 @@ static int create_string(struct greybus_module *gmod,
        return 0;
 }
 
-static int create_cport(struct greybus_module *gmod,
+static int create_cport(struct gb_module *gmod,
                        struct greybus_descriptor_cport *cport,
                        size_t desc_size)
 {
@@ -309,7 +271,7 @@ static int create_cport(struct greybus_module *gmod,
 void gb_add_module(struct greybus_host_device *hd, u8 module_id,
                   u8 *data, int size)
 {
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
        struct greybus_manifest *manifest;
        int retval;
        int overall_size;
@@ -318,11 +280,10 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id,
        if (size <= sizeof(manifest->header))
                return;
 
-       gmod = kzalloc(sizeof(*gmod), GFP_KERNEL);
+       gmod = gb_module_create(hd, module_id);
        if (!gmod)
                return;
 
-       gmod->module_number = module_id;
        gmod->dev.parent = hd->parent;
        gmod->dev.driver = NULL;
        gmod->dev.bus = &greybus_bus_type;
@@ -400,7 +361,7 @@ void gb_add_module(struct greybus_host_device *hd, u8 module_id,
                data += desc_size;
        }
 
-       retval = gb_init_subdevs(gmod, &fake_gb_id);
+       retval = gb_init_subdevs(gmod, &fake_greybus_module_id);
        if (retval)
                goto error;
 
@@ -418,7 +379,7 @@ void gb_remove_module(struct greybus_host_device *hd, u8 module_id)
        // FIXME should be the remove_device call...
 }
 
-void greybus_remove_device(struct greybus_module *gmod)
+void greybus_remove_device(struct gb_module *gmod)
 {
        /* tear down all of the "sub device types" for this device */
        gb_i2c_disconnect(gmod);
@@ -453,6 +414,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
        kref_init(&hd->kref);
        hd->parent = parent;
        hd->driver = driver;
+       INIT_LIST_HEAD(&hd->modules);
 
        return hd;
 }
index 7b4a72a7c4b40dd79df22331e803336594ec0645..fada1219272669e0a43166f3c58466f0ea3ec9f7 100644 (file)
@@ -26,7 +26,7 @@ static struct kmem_cache *gbuf_head_cache;
 /* Workqueue to handle Greybus buffer completions. */
 static struct workqueue_struct *gbuf_workqueue;
 
-static struct gbuf *__alloc_gbuf(struct greybus_module *gmod,
+static struct gbuf *__alloc_gbuf(struct gb_module *gmod,
                                u16 cport_id,
                                gbuf_complete_t complete,
                                gfp_t gfp_mask,
@@ -63,7 +63,7 @@ static struct gbuf *__alloc_gbuf(struct greybus_module *gmod,
  * that the driver can then fill up with the data to be sent out.  Curse
  * hardware designers for this issue...
  */
-struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod,
+struct gbuf *greybus_alloc_gbuf(struct gb_module *gmod,
                                u16 cport_id,
                                gbuf_complete_t complete,
                                unsigned int size,
@@ -80,7 +80,7 @@ struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod,
        gbuf->direction = GBUF_DIRECTION_OUT;
 
        /* Host controller specific allocation for the actual buffer */
-       retval = gbuf->gmod->hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask);
+       retval = gmod->hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask);
        if (retval) {
                greybus_free_gbuf(gbuf);
                return NULL;
@@ -147,7 +147,7 @@ static void cport_process_event(struct work_struct *work)
 struct gb_cport_handler {
        gbuf_complete_t handler;
        u16 cport_id;
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
        void *context;
 };
 
@@ -155,8 +155,9 @@ static struct gb_cport_handler cport_handler[MAX_CPORTS];
 // FIXME - use a lock for this list of handlers, but really, for now we don't
 // need it, we don't have a dynamic system...
 
-int gb_register_cport_complete(struct greybus_module *gmod,
-                              gbuf_complete_t handler, u16 cport_id,
+int gb_register_cport_complete(struct gb_module *gmod,
+                              gbuf_complete_t handler,
+                              u16 cport_id,
                               void *context)
 {
        if (cport_handler[cport_id].handler)
index 4b7186651db5b364f434f616b36068dc5066dbba..2369175bf0f99d8640afc3d3ef4a2ca01e2b9802 100644 (file)
@@ -14,7 +14,7 @@
 
 struct gb_gpio_device {
        struct gpio_chip chip;
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
        struct gpio_chip *gpio;
        // FIXME - some lock?
 };
@@ -49,7 +49,7 @@ static void gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
        // FIXME - do something there
 }
 
-int gb_gpio_probe(struct greybus_module *gmod,
+int gb_gpio_probe(struct gb_module *gmod,
                  const struct greybus_module_id *id)
 {
        struct gb_gpio_device *gb_gpio;
@@ -86,7 +86,7 @@ int gb_gpio_probe(struct greybus_module *gmod,
        return 0;
 }
 
-void gb_gpio_disconnect(struct greybus_module *gmod)
+void gb_gpio_disconnect(struct gb_module *gmod)
 {
        struct gb_gpio_device *gb_gpio_dev;
        int retval;
index c8bd8eb4d7244b66a8271f41c20a3d9c5e152d17..a4fad874a70e9ee15d185a63c6625c68d07aa7fa 100644 (file)
 
 #ifdef __KERNEL__
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/module.h>
+
 #include "greybus_id.h"
 #include "greybus_manifest.h"
+#include "module.h"
 
 
 /* Matches up with the Greybus Protocol specification document */
@@ -113,7 +117,7 @@ struct gbuf {
        struct kref kref;
        void *hdpriv;
 
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
        u16 cport_id;
        int status;
        void *transfer_buffer;
@@ -142,7 +146,7 @@ struct gbuf {
  * same module as the gpio pins, etc.)
  *
  * So, put the "private" data structures here in greybus.h and link to them off
- * of the "main" greybus_module structure.
+ * of the "main" gb_module structure.
  */
 
 struct gb_i2c_device;
@@ -173,6 +177,8 @@ struct greybus_host_device {
        struct device *parent;
        const struct greybus_host_driver *driver;
 
+       struct list_head modules;
+
        /* Private data for the host driver */
        unsigned long hd_priv[0] __attribute__ ((aligned(sizeof(s64))));
 };
@@ -184,32 +190,7 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id,
                        u8 *data, size_t length);
 void greybus_gbuf_finished(struct gbuf *gbuf);
 
-
-/* Increase these values if needed */
-#define MAX_CPORTS_PER_MODULE  10
-#define MAX_STRINGS_PER_MODULE 10
-
-struct greybus_module {
-       struct device dev;
-       u16 module_number;
-       struct greybus_descriptor_module module;
-       int num_cports;
-       int num_strings;
-       u16 cport_ids[MAX_CPORTS_PER_MODULE];
-       struct gmod_string *string[MAX_STRINGS_PER_MODULE];
-
-       struct greybus_host_device *hd;
-
-       struct gb_i2c_device *gb_i2c_dev;
-       struct gb_gpio_device *gb_gpio_dev;
-       struct gb_sdio_host *gb_sdio_host;
-       struct gb_tty *gb_tty;
-       struct gb_usb_device *gb_usb_dev;
-       struct gb_battery *gb_battery;
-};
-#define to_greybus_module(d) container_of(d, struct greybus_module, dev)
-
-struct gbuf *greybus_alloc_gbuf(struct greybus_module *gmod, u16 cport_id,
+struct gbuf *greybus_alloc_gbuf(struct gb_module *gmod, u16 cport_id,
                                gbuf_complete_t complete, unsigned int size,
                                gfp_t gfp_mask, void *context);
 void greybus_free_gbuf(struct gbuf *gbuf);
@@ -223,12 +204,12 @@ int greybus_kill_gbuf(struct gbuf *gbuf);
 struct greybus_driver {
        const char *name;
 
-       int (*probe)(struct greybus_module *gmod,
+       int (*probe)(struct gb_module *gmod,
                     const struct greybus_module_id *id);
-       void (*disconnect)(struct greybus_module *gmod);
+       void (*disconnect)(struct gb_module *gmod);
 
-       int (*suspend)(struct greybus_module *gmod, pm_message_t message);
-       int (*resume)(struct greybus_module *gmod);
+       int (*suspend)(struct gb_module *gmod, pm_message_t message);
+       int (*resume)(struct gb_module *gmod);
 
        const struct greybus_module_id *id_table;
 
@@ -236,16 +217,6 @@ struct greybus_driver {
 };
 #define to_greybus_driver(d) container_of(d, struct greybus_driver, driver)
 
-static inline void greybus_set_drvdata(struct greybus_module *gmod, void *data)
-{
-       dev_set_drvdata(&gmod->dev, data);
-}
-
-static inline void *greybus_get_drvdata(struct greybus_module *gmod)
-{
-       return dev_get_drvdata(&gmod->dev);
-}
-
 /* Don't call these directly, use the module_greybus_driver() macro instead */
 int greybus_register_driver(struct greybus_driver *driver,
                            struct module *module, const char *mod_name);
@@ -268,9 +239,9 @@ void greybus_deregister(struct greybus_driver *driver);
 
 int greybus_disabled(void);
 
-void greybus_remove_device(struct greybus_module *gmod);
+void greybus_remove_device(struct gb_module *gmod);
 
-const u8 *greybus_string(struct greybus_module *gmod, int id);
+const u8 *greybus_string(struct gb_module *gmod, int id);
 
 /* Internal functions to gb module, move to internal .h file eventually. */
 
@@ -286,7 +257,7 @@ void gb_debugfs_cleanup(void);
 int gb_gbuf_init(void);
 void gb_gbuf_exit(void);
 
-int gb_register_cport_complete(struct greybus_module *gmod,
+int gb_register_cport_complete(struct gb_module *gmod,
                               gbuf_complete_t handler, u16 cport_id,
                               void *context);
 void gb_deregister_cport_complete(u16 cport_id);
@@ -298,16 +269,17 @@ extern const struct attribute_group *greybus_module_groups[];
  * we have static functions for this, not "dynamic" drivers like we really
  * should in the end.
  */
-int gb_i2c_probe(struct greybus_module *gmod, const struct greybus_module_id *id);
-void gb_i2c_disconnect(struct greybus_module *gmod);
-int gb_gpio_probe(struct greybus_module *gmod, const struct greybus_module_id *id);
-void gb_gpio_disconnect(struct greybus_module *gmod);
-int gb_sdio_probe(struct greybus_module *gmod, const struct greybus_module_id *id);
-void gb_sdio_disconnect(struct greybus_module *gmod);
-int gb_tty_probe(struct greybus_module *gmod, const struct greybus_module_id *id);
-void gb_tty_disconnect(struct greybus_module *gmod);
-int gb_battery_probe(struct greybus_module *gmod, const struct greybus_module_id *id);
-void gb_battery_disconnect(struct greybus_module *gmod);
+int gb_i2c_probe(struct gb_module *gmod, const struct greybus_module_id *id);
+void gb_i2c_disconnect(struct gb_module *gmod);
+int gb_gpio_probe(struct gb_module *gmod, const struct greybus_module_id *id);
+void gb_gpio_disconnect(struct gb_module *gmod);
+int gb_sdio_probe(struct gb_module *gmod, const struct greybus_module_id *id);
+void gb_sdio_disconnect(struct gb_module *gmod);
+int gb_tty_probe(struct gb_module *gmod, const struct greybus_module_id *id);
+void gb_tty_disconnect(struct gb_module *gmod);
+int gb_battery_probe(struct gb_module *gmod,
+                       const struct greybus_module_id *id);
+void gb_battery_disconnect(struct gb_module *gmod);
 
 int gb_tty_init(void);
 void gb_tty_exit(void);
index bd03f19a3568bbef7a1ec470dc653177a328a1d2..c01f41b59c55bb3f687d9d63556651fbd9174502 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+
 #include "greybus.h"
 
 struct gb_i2c_device {
        struct i2c_adapter *adapter;
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
 };
 
 static const struct greybus_module_id id_table[] = {
@@ -33,7 +34,7 @@ static s32 i2c_gb_access(struct i2c_adapter *adap, u16 addr,
                         int size, union i2c_smbus_data *data)
 {
        struct gb_i2c_device *gb_i2c_dev;
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
 
        gb_i2c_dev = i2c_get_adapdata(adap);
        gmod = gb_i2c_dev->gmod;
@@ -75,7 +76,7 @@ static const struct i2c_algorithm smbus_algorithm = {
        .functionality  = i2c_gb_func,
 };
 
-int gb_i2c_probe(struct greybus_module *gmod,
+int gb_i2c_probe(struct gb_module *gmod,
                 const struct greybus_module_id *id)
 {
        struct gb_i2c_device *gb_i2c_dev;
@@ -115,7 +116,7 @@ error:
        return retval;
 }
 
-void gb_i2c_disconnect(struct greybus_module *gmod)
+void gb_i2c_disconnect(struct gb_module *gmod)
 {
        struct gb_i2c_device *gb_i2c_dev;
 
diff --git a/drivers/staging/greybus/module.c b/drivers/staging/greybus/module.c
new file mode 100644 (file)
index 0000000..31017c2
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Greybus modules
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+
+/* XXX This could be per-host device */
+static DEFINE_SPINLOCK(gb_modules_lock);
+
+static int gb_module_match_one_id(struct gb_module *gmod,
+                               const struct greybus_module_id *id)
+{
+       struct greybus_descriptor_module *module;
+
+       module = &gmod->module;
+
+       if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_VENDOR) &&
+           (id->vendor != le16_to_cpu(module->vendor)))
+               return 0;
+
+       if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_PRODUCT) &&
+           (id->product != le16_to_cpu(module->product)))
+               return 0;
+
+       if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
+           (id->serial_number != le64_to_cpu(module->serial_number)))
+               return 0;
+
+       return 1;
+}
+
+const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
+                               const struct greybus_module_id *id)
+{
+       if (id == NULL)
+               return NULL;
+
+       for (; id->vendor || id->product || id->serial_number ||
+                       id->driver_info; id++) {
+               if (gb_module_match_one_id(gmod, id))
+                       return id;
+       }
+
+       return NULL;
+}
+
+/*
+ * A Greybus module represents a user-replacable component on an Ara
+ * phone.
+ *
+ * Create a gb_module structure to represent a discovered module.
+ * The position within the Endo is encoded in the "module_id" argument.
+ * Returns a pointer to the new module or a null pointer if a
+ * failure occurs due to memory exhaustion.
+ */
+struct gb_module *gb_module_create(struct greybus_host_device *hd, u8 module_id)
+{
+       struct gb_module *module;
+
+       module = kzalloc(sizeof(*module), GFP_KERNEL);
+       if (!module)
+               return NULL;
+
+       module->hd = hd;                /* XXX refcount? */
+       module->module_id = module_id;
+
+       spin_lock_irq(&gb_modules_lock);
+       list_add_tail(&module->links, &hd->modules);
+       spin_unlock_irq(&gb_modules_lock);
+
+       return module;
+}
+
+/*
+ * Tear down a previously set up module.
+ */
+void gb_module_destroy(struct gb_module *module)
+{
+       if (WARN_ON(!module))
+               return;
+
+       spin_lock_irq(&gb_modules_lock);
+       list_del(&module->links);
+       spin_unlock_irq(&gb_modules_lock);
+
+       /* kref_put(module->hd); */
+
+       kfree(module);
+}
diff --git a/drivers/staging/greybus/module.h b/drivers/staging/greybus/module.h
new file mode 100644 (file)
index 0000000..0d0f19f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Greybus modules
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __MODULE_H
+#define __MODULE_H
+
+/* Increase these values if needed */
+#define MAX_CPORTS_PER_MODULE  10
+#define MAX_STRINGS_PER_MODULE 10
+
+struct gb_module {
+       struct device dev;
+
+       struct list_head links; /* greybus_host_device->modules */
+       u8 module_id;           /* Physical location within the Endo */
+
+       struct greybus_descriptor_module module;
+       int num_cports;
+       int num_strings;
+       u16 cport_ids[MAX_CPORTS_PER_MODULE];
+       struct gmod_string *string[MAX_STRINGS_PER_MODULE];
+
+       struct greybus_host_device *hd;
+
+       struct gb_i2c_device *gb_i2c_dev;
+       struct gb_gpio_device *gb_gpio_dev;
+       struct gb_sdio_host *gb_sdio_host;
+       struct gb_tty *gb_tty;
+       struct gb_usb_device *gb_usb_dev;
+       struct gb_battery *gb_battery;
+};
+#define to_gb_module(d) container_of(d, struct gb_module, dev)
+
+static inline void
+gb_module_set_drvdata(struct gb_module *gmod, void *data)
+{
+       dev_set_drvdata(&gmod->dev, data);
+}
+
+static inline void *gb_module_get_drvdata(struct gb_module *gmod)
+{
+       return dev_get_drvdata(&gmod->dev);
+}
+
+const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
+                                       const struct greybus_module_id *id);
+
+struct gb_module *gb_module_create(struct greybus_host_device *hd,
+                                       u8 module_id);
+void gb_module_destroy(struct gb_module *module);
+
+#endif /* __MODULE_H */
index 3cf258aedc11bedd2bffa0d18f078290e8663ac4..f7e80abcc0a0a6298f877cc64fb34cfd94c69d05 100644 (file)
@@ -7,9 +7,9 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/mmc/host.h>
+
 #include "greybus.h"
 
 struct gb_sdio_host {
@@ -45,7 +45,7 @@ static const struct mmc_host_ops gb_sd_ops = {
        .get_ro         = gb_sd_get_ro,
 };
 
-int gb_sdio_probe(struct greybus_module *gmod,
+int gb_sdio_probe(struct gb_module *gmod,
                  const struct greybus_module_id *id)
 {
        struct mmc_host *mmc;
@@ -65,7 +65,7 @@ int gb_sdio_probe(struct greybus_module *gmod,
        return 0;
 }
 
-void gb_sdio_disconnect(struct greybus_module *gmod)
+void gb_sdio_disconnect(struct gb_module *gmod)
 {
        struct mmc_host *mmc;
        struct gb_sdio_host *host;
index a2dce7a0f1974ea503d9910b27ac191a4af741cc..804c0a0855b3b02efb35593b612985a526de3032 100644 (file)
 #include <linux/device.h>
 
 #include "greybus.h"
-
 #include "kernel_ver.h"
 
 /* Module fields */
-#define greybus_module_attr(field)                                     \
+#define gb_module_attr(field)                                          \
 static ssize_t module_##field##_show(struct device *dev,               \
                                     struct device_attribute *attr,     \
                                     char *buf)                         \
 {                                                                      \
-       struct greybus_module *gmod = to_greybus_module(dev);           \
+       struct gb_module *gmod = to_gb_module(dev);                     \
        return sprintf(buf, "%x\n", gmod->module.field);                \
 }                                                                      \
 static DEVICE_ATTR_RO(module_##field)
 
-greybus_module_attr(vendor);
-greybus_module_attr(product);
-greybus_module_attr(version);
+gb_module_attr(vendor);
+gb_module_attr(product);
+gb_module_attr(version);
 
 static ssize_t module_serial_number_show(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
 {
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
 
        return sprintf(buf, "%llX\n",
                      (unsigned long long)le64_to_cpu(gmod->module.serial_number));
@@ -50,7 +49,7 @@ static ssize_t module_vendor_string_show(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
 {
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
 
        return sprintf(buf, "%s",
                       greybus_string(gmod, gmod->module.vendor_stringid));
@@ -61,7 +60,7 @@ static ssize_t module_product_string_show(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
 {
-       struct greybus_module *gmod = to_greybus_module(dev);
+       struct gb_module *gmod = to_gb_module(dev);
 
        return sprintf(buf, "%s",
                       greybus_string(gmod, gmod->module.product_stringid));
@@ -81,7 +80,7 @@ static struct attribute *module_attrs[] = {
 static umode_t module_attrs_are_visible(struct kobject *kobj,
                                        struct attribute *a, int n)
 {
-       struct greybus_module *gmod = to_greybus_module(kobj_to_dev(kobj));
+       struct gb_module *gmod = to_gb_module(kobj_to_dev(kobj));
 
        if ((a == &dev_attr_module_vendor_string.attr) &&
            (gmod->module.vendor_stringid))
index 811a237898cc065f78a8689416a3e0bd09c7a939..1b477695b4183537703d19ab17d02bf84e5686dd 100644 (file)
 #include "greybus.h"
 
 struct test_device {
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
 };
 
-int gb_register_cport_complete(struct greybus_module *gmod,
+int gb_register_cport_complete(struct gb_module *gmod,
                               gbuf_complete_t handler, u16 cport_id,
                               void *context);
 void gb_deregister_cport_complete(u16 cport_id);
index 7f9d49869281f523fd2a1a2dbfac676f2dcb8421..301868cd587830ff232d8a1db61fbab7d639f509 100644 (file)
 #include <linux/idr.h>
 #include <linux/fs.h>
 #include <linux/kdev_t.h>
+
 #include "greybus.h"
+#include "module.h"
 
 #define GB_NUM_MINORS  255     /* 255 is enough for anyone... */
 #define GB_NAME                "ttyGB"
 
 struct gb_tty {
        struct tty_port port;
-       struct greybus_module *gmod;
+       struct gb_module *gmod;
        u16 cport_id;
        unsigned int minor;
        unsigned char clocal;
@@ -384,7 +386,7 @@ static const struct tty_operations gb_ops = {
 };
 
 
-int gb_tty_probe(struct greybus_module *gmod,
+int gb_tty_probe(struct gb_module *gmod,
                 const struct greybus_module_id *id)
 {
        struct gb_tty *gb_tty;
@@ -430,7 +432,7 @@ error:
        return retval;
 }
 
-void gb_tty_disconnect(struct greybus_module *gmod)
+void gb_tty_disconnect(struct gb_module *gmod)
 {
        struct gb_tty *gb_tty = gmod->gb_tty;
        struct tty_struct *tty;