return 0;
}
-static int gb_interface_activate_operation(struct gb_interface *intf)
+static int gb_interface_activate_operation(struct gb_interface *intf,
+ enum gb_interface_type *intf_type)
{
struct gb_svc *svc = intf->hd->svc;
u8 type;
switch (type) {
case GB_SVC_INTF_TYPE_DUMMY:
- intf->type = GB_INTERFACE_TYPE_DUMMY;
+ *intf_type = GB_INTERFACE_TYPE_DUMMY;
/* FIXME: handle as an error for now */
return -ENODEV;
case GB_SVC_INTF_TYPE_UNIPRO:
- intf->type = GB_INTERFACE_TYPE_UNIPRO;
+ *intf_type = GB_INTERFACE_TYPE_UNIPRO;
dev_err(&intf->dev, "interface type UniPro not supported\n");
/* FIXME: handle as an error for now */
return -ENODEV;
case GB_SVC_INTF_TYPE_GREYBUS:
- intf->type = GB_INTERFACE_TYPE_GREYBUS;
+ *intf_type = GB_INTERFACE_TYPE_GREYBUS;
break;
default:
dev_err(&intf->dev, "unknown interface type: %u\n", type);
- intf->type = GB_INTERFACE_TYPE_UNKNOWN;
+ *intf_type = GB_INTERFACE_TYPE_UNKNOWN;
return -ENODEV;
}
return gb_svc_intf_set_power_mode_hibernate(svc, intf->interface_id);
}
-static int _gb_interface_activate(struct gb_interface *intf)
+static int _gb_interface_activate(struct gb_interface *intf,
+ enum gb_interface_type *type)
{
int ret;
+ *type = GB_INTERFACE_TYPE_UNKNOWN;
+
if (intf->ejected)
return -ENODEV;
if (ret)
goto err_refclk_disable;
- ret = gb_interface_activate_operation(intf);
+ ret = gb_interface_activate_operation(intf, type);
if (ret)
goto err_unipro_disable;
}
/*
- * Activate an interface.
+ * At present, we assume a UniPro-only module to be a Greybus module that
+ * failed to send its mailbox poke. There is some reason to believe that this
+ * is because of a bug in the ES3 bootrom.
*
- * Locking: Caller holds the interface mutex.
+ * FIXME: Check if this is a Toshiba bridge before retrying?
*/
-int gb_interface_activate(struct gb_interface *intf)
+static int _gb_interface_activate_es3_hack(struct gb_interface *intf,
+ enum gb_interface_type *type)
{
int retries = 3;
int ret;
- /*
- * At present, we assume a UniPro-only module
- * to be a Greybus module that failed to send its mailbox
- * poke. There is some reason to believe that this is
- * because of a bug in the ES3 bootrom.
- *
- * FIXME: Check if this is a Toshiba bridge before retrying?
- */
while (retries--) {
- ret = _gb_interface_activate(intf);
- if (ret == -ENODEV && intf->type == GB_SVC_INTF_TYPE_UNIPRO)
+ ret = _gb_interface_activate(intf, type);
+ if (ret == -ENODEV && *type == GB_INTERFACE_TYPE_UNIPRO)
continue;
break;
}
/*
+ * Activate an interface.
+ *
+ * Locking: Caller holds the interface mutex.
+ */
+int gb_interface_activate(struct gb_interface *intf)
+{
+ enum gb_interface_type type;
+ int ret;
+
+ switch (intf->type) {
+ case GB_INTERFACE_TYPE_INVALID:
+ case GB_INTERFACE_TYPE_GREYBUS:
+ ret = _gb_interface_activate_es3_hack(intf, &type);
+ break;
+ default:
+ ret = _gb_interface_activate(intf, &type);
+ }
+
+ /* Make sure type is detected correctly during reactivation. */
+ if (intf->type != GB_INTERFACE_TYPE_INVALID) {
+ if (type != intf->type) {
+ dev_err(&intf->dev, "failed to detect interface type\n");
+
+ if (!ret)
+ gb_interface_deactivate(intf);
+
+ return -EIO;
+ }
+ } else {
+ intf->type = type;
+ }
+
+ return ret;
+}
+
+/*
* Deactivate an interface.
*
* Locking: Caller holds the interface mutex.