INIT_LIST_HEAD(&hd->connections);
        ida_init(&hd->cport_id_map);
 
+       hd->endo = gb_endo_create(hd);
+       if (!hd->endo) {
+               greybus_remove_hd(hd);
+               return NULL;
+       }
+
        return hd;
 }
 EXPORT_SYMBOL_GPL(greybus_create_hd);
 
 void greybus_remove_hd(struct greybus_host_device *hd)
 {
-       /* Tear down all modules that happen to be associated with this host
-        * controller */
+       /*
+        * 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_remove_interfaces(hd);
+       gb_endo_remove(hd->endo);
        kref_put_mutex(&hd->kref, free_hd, &hd_mutex);
 }
 EXPORT_SYMBOL_GPL(greybus_remove_hd);
 
        }
 
        for (i = 0; endo_modules[i] != 0x00; ++i) {
-//             module = gb_module_create(&endo->dev, endo_modules[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;
        if (!endo)
                return;
 
-       /* remove all modules first */
-       remove_modules(endo);
+       /* remove all modules for this endo */
+       gb_module_remove_all(endo);
 
        device_unregister(&endo->dev);
 }
 
        return interface_id;
 }
 
+struct module_find {
+       struct gb_endo *endo;
+       u8 module_id;
+};
+
 static int module_find(struct device *dev, void *data)
 {
        struct gb_module *module;
-       u8 *module_id = data;
+       struct module_find *find = data;
 
        if (!is_gb_module(dev))
                return 0;
 
        module = to_gb_module(dev);
-       if (module->module_id == *module_id)
+       if ((module->module_id == find->module_id) &&
+           (module->dev.parent == &find->endo->dev))
                return 1;
 
        return 0;
  * Search the list of modules in the system.  If one is found, return it, with
  * the reference count incremented.
  */
-static struct gb_module *gb_module_find(u8 module_id)
+struct gb_module *gb_module_find(struct greybus_host_device *hd, u8 module_id)
 {
        struct device *dev;
        struct gb_module *module = NULL;
+       struct module_find find;
+
+       find.module_id = module_id;
+       find.endo = hd->endo;
 
        dev = bus_find_device(&greybus_bus_type, NULL,
-                             &module_id, module_find);
+                             &find, module_find);
        if (dev)
                module = to_gb_module(dev);
 
        return module;
 }
 
-static struct gb_module *gb_module_create(struct greybus_host_device *hd,
-                                         u8 module_id)
+struct gb_module *gb_module_create(struct device *parent, u8 module_id)
 {
        struct gb_module *module;
        int retval;
                return NULL;
 
        module->module_id = module_id;
-       module->refcount = 1;
-       module->dev.parent = hd->parent;
+       module->dev.parent = parent;
        module->dev.bus = &greybus_bus_type;
        module->dev.type = &greybus_module_type;
        module->dev.groups = module_groups;
-       module->dev.dma_mask = hd->parent->dma_mask;
+       module->dev.dma_mask = parent->dma_mask;
        device_initialize(&module->dev);
        dev_set_name(&module->dev, "%d", module_id);
 
        return module;
 }
 
-struct gb_module *gb_module_find_or_create(struct greybus_host_device *hd,
-                                          u8 module_id)
+static int module_remove(struct device *dev, void *data)
 {
        struct gb_module *module;
+       struct gb_endo *endo = data;
 
-       module = gb_module_find(module_id);
-       if (module) {
-               module->refcount++;
-               return module;
-       }
+       if (!is_gb_module(dev))
+               return 0;
+
+       module = to_gb_module(dev);
+       if (module->dev.parent == &endo->dev)
+               device_unregister(&module->dev);
 
-       return gb_module_create(hd, module_id);
+       return 0;
 }
 
-void gb_module_remove(struct gb_module *module)
+void gb_module_remove_all(struct gb_endo *endo)
 {
-       if (!module)
-               return;
-
-       if (!--module->refcount)
-               device_unregister(&module->dev);
+       bus_for_each_dev(&greybus_bus_type, NULL, endo, module_remove);
 }
-
 
 struct gb_module {
        struct device dev;
        u8 module_id;           /* Physical location within the Endo */
-       u16 refcount;
 };
 #define to_gb_module(d) container_of(d, struct gb_module, dev)
 
 struct greybus_host_device;
 
 /* Greybus "private" definitions */
-struct gb_module *gb_module_find_or_create(struct greybus_host_device *hd,
-                                          u8 module_id);
-void gb_module_remove(struct gb_module *module);
+struct gb_module *gb_module_find(struct greybus_host_device *hd, u8 module_id);
+struct gb_module *gb_module_create(struct device *parent, u8 module_id);
+void gb_module_remove_all(struct gb_endo *endo);
 
 u8 get_module_id(u8 interface_id);