/* Define get_version() routine */
 define_get_version(gb_svc, SVC);
 
+/*
+ * AP's SVC cport is required early to get messages from the SVC. This happens
+ * even before the Endo is created and hence any modules or interfaces.
+ *
+ * This is a temporary connection, used only at initial bootup.
+ */
+struct gb_connection *
+gb_ap_svc_connection_create(struct greybus_host_device *hd)
+{
+       struct gb_connection *connection;
+
+       connection = gb_connection_create_range(hd, NULL, hd->parent,
+                                               GB_SVC_CPORT_ID,
+                                               GREYBUS_PROTOCOL_SVC,
+                                               GB_SVC_CPORT_ID,
+                                               GB_SVC_CPORT_ID + 1);
+
+       return connection;
+}
+EXPORT_SYMBOL_GPL(gb_ap_svc_connection_create);
+
+/*
+ * We know endo-type and AP's interface id now, lets create a proper svc
+ * connection (and its interface/bundle) now and get rid of the initial
+ * 'partially' initialized one svc connection.
+ */
+static struct gb_interface *
+gb_ap_interface_create(struct greybus_host_device *hd,
+                      struct gb_connection *connection, u8 interface_id)
+{
+       struct gb_interface *intf;
+       struct device *dev = &hd->endo->dev;
+       int ret;
+
+       intf = gb_interface_create(hd, interface_id);
+       if (!intf) {
+               dev_err(dev, "%s: Failed to create interface with id %hhu\n",
+                       __func__, interface_id);
+               return NULL;
+       }
+
+       intf->device_id = GB_DEVICE_ID_AP;
+
+       /*
+        * XXX: Disable the initial svc connection here, but don't destroy it
+        * yet. We do need to send a response of 'svc-hello message' on that.
+        */
+
+       /* Establish new control CPort connection */
+       ret = gb_create_bundle_connection(intf, GREYBUS_CLASS_SVC);
+       if (ret) {
+               dev_err(&intf->dev, "%s: Failed to create svc connection (%d %d)\n",
+                       __func__, interface_id, ret);
+               gb_interface_destroy(intf);
+               intf = NULL;
+       }
+
+       return intf;
+}
+
 static int intf_device_id_operation(struct gb_svc *svc,
                                u8 intf_id, u8 device_id)
 {
 
        svc->connection = connection;
        connection->private = svc;
+
+       /*
+        * SVC connection is created twice:
+        * - before the interface-id of the AP and the endo type is known.
+        * - after receiving endo type and interface-id of the AP from the SVC.
+        *
+        * We should do light-weight initialization for the first case.
+        */
+       if (!connection->bundle) {
+               WARN_ON(connection->hd->initial_svc_connection);
+               connection->hd->initial_svc_connection = connection;
+               return 0;
+       }
+
+       ida_init(&greybus_svc_device_id_map);
+
        ret = gb_svc_device_setup(svc);
        if (ret)
                kfree(svc);
 {
        struct gb_svc *svc = connection->private;
 
-       if (WARN_ON(connection->bundle->intf->svc != svc))
-               return;
-
-       connection->bundle->intf->svc = NULL;
+       if (connection->hd->initial_svc_connection == connection) {
+               connection->hd->initial_svc_connection = NULL;
+       } else {
+               if (WARN_ON(connection->bundle->intf->svc != svc))
+                       return;
+               connection->bundle->intf->svc = NULL;
+       }
 
+       connection->private = NULL;
        kfree(svc);
 }