--- /dev/null
+/*
+ * Greybus endo code
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+
+/* endo sysfs attributes */
+static ssize_t serial_number_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct gb_endo *endo = to_gb_endo(dev);
+
+       return sprintf(buf, "%s", &endo->svc.serial_number[0]);
+}
+static DEVICE_ATTR_RO(serial_number);
+
+static ssize_t version_show(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       struct gb_endo *endo = to_gb_endo(dev);
+
+       return sprintf(buf, "%s", &endo->svc.version[0]);
+}
+static DEVICE_ATTR_RO(version);
+
+static struct attribute *endo_attrs[] = {
+       &dev_attr_serial_number.attr,
+       &dev_attr_version.attr,
+       NULL,
+};
+static const struct attribute_group endo_group = {
+       .attrs = endo_attrs,
+       .name = "SVC",
+};
+static const struct attribute_group *endo_groups[] = {
+       &endo_group,
+       NULL,
+};
+
+static void greybus_endo_release(struct device *dev)
+{
+       struct gb_endo *endo = to_gb_endo(dev);
+
+       kfree(endo);
+}
+
+struct device_type greybus_endo_type = {
+       .name =         "greybus_endo",
+       .release =      greybus_endo_release,
+};
+
+
+/*
+ * Endo "types" have different module locations, these are tables based on those
+ * types that list the module ids for the different locations.
+ *
+ * List must end with 0x00 in order to properly terminate the list.
+ */
+static u8 endo_0555[] = {
+       0x01,
+       0x03,
+       0x05,
+       0x07,
+       0x08,
+       0x0a,
+       0x0c,
+       0x00,
+};
+
+
+static int create_modules(struct gb_endo *endo)
+{
+       struct gb_module *module;
+       u8 *endo_modules;
+       int i;
+
+       /* Depending on the endo type, create a bunch of different modules */
+       switch (endo->type) {
+       case 0x0555:
+               endo_modules = &endo_0555[0];
+               break;
+       default:
+               dev_err(&endo->dev, "Unknown endo type 0x%04x, aborting!",
+                       endo->type);
+               return -EINVAL;
+       }
+
+       for (i = 0; endo_modules[i] != 0x00; ++i) {
+//             module = gb_module_create(&endo->dev, endo_modules[i]);
+               if (!module)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void remove_modules(struct gb_endo *endo)
+{
+       /*
+        * We really don't care how many modules have been created, or what the
+        * configuration of them are, let's just enumerate over everything in
+        * the system and delete all found modules.
+        */
+
+}
+
+struct gb_endo *gb_endo_create(struct greybus_host_device *hd)
+{
+       struct gb_endo *endo;
+       int retval;
+
+       endo = kzalloc(sizeof(*endo), GFP_KERNEL);
+       if (!endo)
+               return NULL;
+
+       endo->dev.parent = hd->parent;
+       endo->dev.bus = &greybus_bus_type;
+       endo->dev.type = &greybus_endo_type;
+       endo->dev.groups = endo_groups;
+       endo->dev.dma_mask = hd->parent->dma_mask;
+       device_initialize(&endo->dev);
+
+       // FIXME - determine endo "type" from the SVC
+       // Also get the version and serial number from the SVC, right now we are
+       // using "fake" numbers.
+       strcpy(&endo->svc.serial_number[0], "042");
+       strcpy(&endo->svc.version[0], "0.0");
+       endo->type = 0x0555;
+
+       dev_set_name(&endo->dev, "endo-0x%04x", endo->type);
+       retval = device_add(&endo->dev);
+       if (retval) {
+               dev_err(hd->parent, "failed to add endo device of type 0x%04x\n",
+                       endo->type);
+               put_device(&endo->dev);
+               kfree(endo);
+               return NULL;
+       }
+
+       retval = create_modules(endo);
+       if (retval) {
+               gb_endo_remove(endo);
+               return NULL;
+       }
+
+       return endo;
+}
+
+void gb_endo_remove(struct gb_endo *endo)
+{
+       if (!endo)
+               return;
+
+       /* remove all modules first */
+       remove_modules(endo);
+
+       device_unregister(&endo->dev);
+}
+