Commit e16715c1 authored by Jeffrey Carlyle's avatar Jeffrey Carlyle Committed by Greg Kroah-Hartman
Browse files

greybus: interface: retry enumeration of UniPro-only modules



Greybus modules will sometimes fail to send the mailbox poke and
erroneously be enumerated as UniPro-only modules. The root cause for
this on the module side is not fully understand, but it seems that this
may be due to "the bootrom bug:" a known problem with the bootrom where
linkup will occasionally fail because of a race condition.

Before the new hotplug code was implemented in the firmware, the SVC
would retry enumeration of modules that did not send the mailbox poke;
this patch ports that functionality to the AP.

Signed-off-by: default avatarJeffrey Carlyle <jcarlyle@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 9bc63b7f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -447,7 +447,8 @@ static int gb_interface_activate_operation(struct gb_interface *intf)
		return -ENODEV;
	case GB_SVC_INTF_TYPE_UNIPRO:
		dev_err(&intf->dev, "interface type UniPro not supported\n");
		return -ENODEV;
		/* FIXME: check if this is a Toshiba bridge before retrying? */
		return -EAGAIN;
	case GB_SVC_INTF_TYPE_GREYBUS:
		break;
	default:
+20 −1
Original line number Diff line number Diff line
@@ -138,13 +138,32 @@ static void gb_module_register_interface(struct gb_interface *intf)
	struct gb_module *module = intf->module;
	u8 intf_id = intf->interface_id;
	int ret;
	int retries = 3;

	mutex_lock(&intf->mutex);

	while (retries--) {
		ret = gb_interface_activate(intf);
		if (ret != -EAGAIN)
			break;
	}
	if (ret) {
		dev_err(&module->dev, "failed to activate interface %u: %d\n",
				intf_id, ret);

		/*
		 * -EAGAIN indicates that the Greybus operation
		 * interface_activate determined the remote interface to be
		 * UniPro-only.  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.  If we exhause our
		 * retries trying to activate such an interface, convert
		 * the error code back into a "no device" error.
		 */
		if (ret == -EAGAIN)
			ret = -ENODEV;

		gb_interface_add(intf);
		goto err_unlock;
	}