greybus: interface: move route creation to interface activation
authorJohan Hovold <johan@hovoldconsulting.com>
Tue, 29 Mar 2016 22:56:04 +0000 (18:56 -0400)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 30 Mar 2016 21:17:40 +0000 (14:17 -0700)
Creating and destroying a route to an interface is arguably an interface
operation and belongs with the interface code.

Add new interface_activate and interface_deactivate helpers that will be
used to activate and deactivate an interface in the new interface boot
sequence.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/interface.c
drivers/staging/greybus/interface.h
drivers/staging/greybus/svc.c
drivers/staging/greybus/svc.h

index a13b221131bcb23e9c7573e805fa12159d1361b4..48f64fbe924817b7ea8a15b6f378ee1aa02b50f4 100644 (file)
 #include "greybus.h"
 
 
+static int gb_interface_route_create(struct gb_interface *intf)
+{
+       struct gb_svc *svc = intf->hd->svc;
+       u8 intf_id = intf->interface_id;
+       u8 device_id;
+       int ret;
+
+       /*
+        * Create a device id for the interface:
+        * - device id 0 (GB_DEVICE_ID_SVC) belongs to the SVC
+        * - device id 1 (GB_DEVICE_ID_AP) belongs to the AP
+        *
+        * XXX Do we need to allocate device ID for SVC or the AP here? And what
+        * XXX about an AP with multiple interface blocks?
+        */
+       ret = ida_simple_get(&svc->device_id_map,
+                            GB_DEVICE_ID_MODULES_START, 0, GFP_KERNEL);
+       if (ret < 0) {
+               dev_err(&intf->dev, "failed to allocate device id: %d\n", ret);
+               return ret;
+       }
+       device_id = ret;
+
+       ret = gb_svc_intf_device_id(svc, intf_id, device_id);
+       if (ret) {
+               dev_err(&intf->dev, "failed to set device id %u: %d\n",
+                               device_id, ret);
+               goto err_ida_remove;
+       }
+
+       /* Create a two-way route between the AP and the new interface. */
+       ret = gb_svc_route_create(svc, svc->ap_intf_id, GB_DEVICE_ID_AP,
+                                 intf_id, device_id);
+       if (ret) {
+               dev_err(&intf->dev, "failed to create route: %d\n", ret);
+               goto err_svc_id_free;
+       }
+
+       intf->device_id = device_id;
+
+       return 0;
+
+err_svc_id_free:
+       /*
+        * XXX Should we tell SVC that this id doesn't belong to interface
+        * XXX anymore.
+        */
+err_ida_remove:
+       ida_simple_remove(&svc->device_id_map, device_id);
+
+       return ret;
+}
+
+static void gb_interface_route_destroy(struct gb_interface *intf)
+{
+       struct gb_svc *svc = intf->hd->svc;
+
+       if (intf->device_id == GB_DEVICE_ID_BAD)
+               return;
+
+       gb_svc_route_destroy(svc, svc->ap_intf_id, intf->interface_id);
+       ida_simple_remove(&svc->device_id_map, intf->device_id);
+       intf->device_id = GB_DEVICE_ID_BAD;
+}
+
 /*
  * T_TstSrcIncrement is written by the module on ES2 as a stand-in for the
  * init-status attribute ES3_INIT_STATUS. The AP needs to read and clear it
@@ -213,6 +278,22 @@ struct gb_interface *gb_interface_create(struct gb_host_device *hd,
        return intf;
 }
 
+int gb_interface_activate(struct gb_interface *intf)
+{
+       int ret;
+
+       ret = gb_interface_route_create(intf);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+void gb_interface_deactivate(struct gb_interface *intf)
+{
+       gb_interface_route_destroy(intf);
+}
+
 /*
  * Enable an interface by enabling its control connection and fetching the
  * manifest and other information over it.
index 96caabc8a73fdd4b7b0d1905ff62f5cdbe7cb647..5dfaea51eb9fd99b4b5267d1fa3454e013bb9505 100644 (file)
@@ -50,6 +50,8 @@ struct gb_interface *gb_interface_find(struct gb_host_device *hd,
 
 struct gb_interface *gb_interface_create(struct gb_host_device *hd,
                                         u8 interface_id);
+int gb_interface_activate(struct gb_interface *intf);
+void gb_interface_deactivate(struct gb_interface *intf);
 int gb_interface_enable(struct gb_interface *intf);
 void gb_interface_disable(struct gb_interface *intf);
 int gb_interface_add(struct gb_interface *intf);
index ca2f34e3e1aaa6c9a6fea98b32e5061a2b5dad42..5c517d7e65f0758866fea05792750a34edfbd352 100644 (file)
@@ -108,7 +108,7 @@ static struct attribute *svc_attrs[] = {
 };
 ATTRIBUTE_GROUPS(svc);
 
-static int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id)
+int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id)
 {
        struct gb_svc_intf_device_id_request request;
 
@@ -251,7 +251,7 @@ void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
 EXPORT_SYMBOL_GPL(gb_svc_connection_destroy);
 
 /* Creates bi-directional routes between the devices */
-static int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
+int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
                               u8 intf2_id, u8 dev2_id)
 {
        struct gb_svc_route_create_request request;
@@ -266,7 +266,7 @@ static int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
 }
 
 /* Destroys bi-directional routes between the devices */
-static void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id)
+void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id)
 {
        struct gb_svc_route_destroy_request request;
        int ret;
@@ -397,78 +397,12 @@ static int gb_svc_hello(struct gb_operation *op)
        return 0;
 }
 
-static int gb_svc_interface_route_create(struct gb_svc *svc,
-                                               struct gb_interface *intf)
-{
-       u8 intf_id = intf->interface_id;
-       u8 device_id;
-       int ret;
-
-       /*
-        * Create a device id for the interface:
-        * - device id 0 (GB_DEVICE_ID_SVC) belongs to the SVC
-        * - device id 1 (GB_DEVICE_ID_AP) belongs to the AP
-        *
-        * XXX Do we need to allocate device ID for SVC or the AP here? And what
-        * XXX about an AP with multiple interface blocks?
-        */
-       ret = ida_simple_get(&svc->device_id_map,
-                            GB_DEVICE_ID_MODULES_START, 0, GFP_KERNEL);
-       if (ret < 0) {
-               dev_err(&svc->dev, "failed to allocate device id for interface %u: %d\n",
-                               intf_id, ret);
-               return ret;
-       }
-       device_id = ret;
-
-       ret = gb_svc_intf_device_id(svc, intf_id, device_id);
-       if (ret) {
-               dev_err(&svc->dev, "failed to set device id %u for interface %u: %d\n",
-                               device_id, intf_id, ret);
-               goto err_ida_remove;
-       }
-
-       /* Create a two-way route between the AP and the new interface. */
-       ret = gb_svc_route_create(svc, svc->ap_intf_id, GB_DEVICE_ID_AP,
-                                 intf_id, device_id);
-       if (ret) {
-               dev_err(&svc->dev, "failed to create route to interface %u (device id %u): %d\n",
-                               intf_id, device_id, ret);
-               goto err_svc_id_free;
-       }
-
-       intf->device_id = device_id;
-
-       return 0;
-
-err_svc_id_free:
-       /*
-        * XXX Should we tell SVC that this id doesn't belong to interface
-        * XXX anymore.
-        */
-err_ida_remove:
-       ida_simple_remove(&svc->device_id_map, device_id);
-
-       return ret;
-}
-
-static void gb_svc_interface_route_destroy(struct gb_svc *svc,
-                                               struct gb_interface *intf)
-{
-       if (intf->device_id == GB_DEVICE_ID_BAD)
-               return;
-
-       gb_svc_route_destroy(svc, svc->ap_intf_id, intf->interface_id);
-       ida_simple_remove(&svc->device_id_map, intf->device_id);
-       intf->device_id = GB_DEVICE_ID_BAD;
-}
-
 static void gb_svc_intf_remove(struct gb_svc *svc, struct gb_interface *intf)
 {
        intf->disconnected = true;
 
        gb_interface_disable(intf);
-       gb_svc_interface_route_destroy(svc, intf);
+       gb_interface_deactivate(intf);
        gb_interface_remove(intf);
 }
 
@@ -546,9 +480,12 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
                intf->product_id = product_id;
        }
 
-       ret = gb_svc_interface_route_create(svc, intf);
-       if (ret)
+       ret = gb_interface_activate(intf);
+       if (ret) {
+               dev_err(&svc->dev, "failed to activate interface %u: %d\n",
+                               intf_id, ret);
                goto out_interface_add;
+       }
 
        ret = gb_interface_enable(intf);
        if (ret) {
index 904b2dd918cc7b1323daa4e816c600d01ad22775..8950baff9aef4365257293de68373c7bfc6fb6e4 100644 (file)
@@ -48,6 +48,10 @@ int gb_svc_add(struct gb_svc *svc);
 void gb_svc_del(struct gb_svc *svc);
 void gb_svc_put(struct gb_svc *svc);
 
+int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id);
+int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
+                              u8 intf2_id, u8 dev2_id);
+void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id);
 int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
                             u8 intf2_id, u16 cport2_id, u8 cport_flags);
 void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,