greybus: interface: move boot-status clearing to interface enable
authorJohan Hovold <johan@hovoldconsulting.com>
Tue, 29 Mar 2016 22:56:00 +0000 (18:56 -0400)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 30 Mar 2016 21:17:40 +0000 (14:17 -0700)
Reading and clearing the boot status of an interface is an interface
operation and belongs in the interface code.

As part of the reworked interface boot sequence, we also want to do this
when enabling (enumerating) a Greybus interface.

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/svc.c

index 44226c4c48ec5175e86dd775fee4195009913cfe..deb5b2641f4a8ebad8de1e6071ffd83eee98e6ad 100644 (file)
@@ -9,6 +9,69 @@
 
 #include "greybus.h"
 
+
+/*
+ * T_TstSrcIncrement is written by the module on ES2 as a stand-in for boot
+ * status attribute ES3_INIT_STATUS. AP needs to read and clear it, after
+ * reading a non-zero value from it.
+ *
+ * FIXME: This is module-hardware dependent and needs to be extended for every
+ * type of module we want to support.
+ */
+static int gb_interface_read_and_clear_boot_status(struct gb_interface *intf)
+{
+       struct gb_host_device *hd = intf->hd;
+       int ret;
+       u32 value;
+       u16 attr;
+       u8 init_status;
+
+       /*
+        * Check if the module is ES2 or ES3, and choose attr number
+        * appropriately.
+        * FIXME: Remove ES2 support from the kernel entirely.
+        */
+       if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
+                               intf->ddbl1_product_id == ES2_DDBL1_PROD_ID)
+               attr = DME_ATTR_T_TST_SRC_INCREMENT;
+       else
+               attr = DME_ATTR_ES3_INIT_STATUS;
+
+       /* Read and clear boot status in ES3_INIT_STATUS */
+       ret = gb_svc_dme_peer_get(hd->svc, intf->interface_id, attr,
+                                 DME_ATTR_SELECTOR_INDEX, &value);
+       if (ret)
+               return ret;
+
+       /*
+        * A nonzero boot status indicates the module has finished
+        * booting. Clear it.
+        */
+       if (!value) {
+               dev_err(&intf->dev, "Module not ready yet\n");
+               return -ENODEV;
+       }
+
+       /*
+        * Check if the module needs to boot from UniPro.
+        * For ES2: We need to check lowest 8 bits of 'value'.
+        * For ES3: We need to check highest 8 bits out of 32 of 'value'.
+        * FIXME: Remove ES2 support from the kernel entirely.
+        */
+       if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
+                       intf->ddbl1_product_id == ES2_DDBL1_PROD_ID)
+               init_status = value;
+       else
+               init_status = value >> 24;
+
+       if (init_status == DME_DIS_UNIPRO_BOOT_STARTED ||
+                       init_status == DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED)
+               intf->boot_over_unipro = true;
+
+       return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr,
+                                  DME_ATTR_SELECTOR_INDEX, 0);
+}
+
 /* interface sysfs attributes */
 #define gb_interface_attr(field, type)                                 \
 static ssize_t field##_show(struct device *dev,                                \
@@ -147,6 +210,12 @@ int gb_interface_enable(struct gb_interface *intf)
        int ret, size;
        void *manifest;
 
+       ret = gb_interface_read_and_clear_boot_status(intf);
+       if (ret) {
+               dev_err(&intf->dev, "failed to clear boot status: %d\n", ret);
+               return ret;
+       }
+
        /* Establish control connection */
        ret = gb_control_enable(intf->control);
        if (ret)
index ca1d4826ca9c1663dc93b48ab4706b3885fa5265..ca2f34e3e1aaa6c9a6fea98b32e5061a2b5dad42 100644 (file)
@@ -210,69 +210,6 @@ int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
 }
 EXPORT_SYMBOL_GPL(gb_svc_dme_peer_set);
 
-/*
- * T_TstSrcIncrement is written by the module on ES2 as a stand-in for boot
- * status attribute ES3_INIT_STATUS. AP needs to read and clear it, after
- * reading a non-zero value from it.
- *
- * FIXME: This is module-hardware dependent and needs to be extended for every
- * type of module we want to support.
- */
-static int gb_svc_read_and_clear_module_boot_status(struct gb_interface *intf)
-{
-       struct gb_host_device *hd = intf->hd;
-       int ret;
-       u32 value;
-       u16 attr;
-       u8 init_status;
-
-       /*
-        * Check if the module is ES2 or ES3, and choose attr number
-        * appropriately.
-        * FIXME: Remove ES2 support from the kernel entirely.
-        */
-       if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
-                               intf->ddbl1_product_id == ES2_DDBL1_PROD_ID)
-               attr = DME_ATTR_T_TST_SRC_INCREMENT;
-       else
-               attr = DME_ATTR_ES3_INIT_STATUS;
-
-       /* Read and clear boot status in ES3_INIT_STATUS */
-       ret = gb_svc_dme_peer_get(hd->svc, intf->interface_id, attr,
-                                 DME_ATTR_SELECTOR_INDEX, &value);
-
-       if (ret)
-               return ret;
-
-       /*
-        * A nonzero boot status indicates the module has finished
-        * booting. Clear it.
-        */
-       if (!value) {
-               dev_err(&intf->dev, "Module not ready yet\n");
-               return -ENODEV;
-       }
-
-       /*
-        * Check if the module needs to boot from UniPro.
-        * For ES2: We need to check lowest 8 bits of 'value'.
-        * For ES3: We need to check highest 8 bits out of 32 of 'value'.
-        * FIXME: Remove ES2 support from the kernel entirely.
-        */
-       if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
-                               intf->ddbl1_product_id == ES2_DDBL1_PROD_ID)
-               init_status = value;
-       else
-               init_status = value >> 24;
-
-       if (init_status == DME_DIS_UNIPRO_BOOT_STARTED ||
-                               init_status == DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED)
-               intf->boot_over_unipro = true;
-
-       return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr,
-                                  DME_ATTR_SELECTOR_INDEX, 0);
-}
-
 int gb_svc_connection_create(struct gb_svc *svc,
                                u8 intf1_id, u16 cport1_id,
                                u8 intf2_id, u16 cport2_id,
@@ -609,13 +546,6 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
                intf->product_id = product_id;
        }
 
-       ret = gb_svc_read_and_clear_module_boot_status(intf);
-       if (ret) {
-               dev_err(&svc->dev, "failed to clear boot status of interface %u: %d\n",
-                               intf_id, ret);
-               goto out_interface_add;
-       }
-
        ret = gb_svc_interface_route_create(svc, intf);
        if (ret)
                goto out_interface_add;