greybus: svc: keep interfaces registered during mode switch
Keep a detected interface registered until it is physically removed. Specifically, do not re-register an interface that is switching mode. Note that this also allows us to get rid of some nasty hacks from core. The Ara VID/PID bootrom hack for ES2 will continue to work, but is now mostly confined to the bootrom driver. Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Родитель
87a4c819a5
Коммит
96fb6c340b
|
@ -426,8 +426,9 @@ void gb_interface_deactivate(struct gb_interface *intf)
|
|||
}
|
||||
|
||||
/*
|
||||
* Enable an interface by enabling its control connection and fetching the
|
||||
* manifest and other information over it.
|
||||
* Enable an interface by enabling its control connection, fetching the
|
||||
* manifest and other information over it, and finally registering its child
|
||||
* devices.
|
||||
*/
|
||||
int gb_interface_enable(struct gb_interface *intf)
|
||||
{
|
||||
|
@ -499,6 +500,19 @@ int gb_interface_enable(struct gb_interface *intf)
|
|||
if (ret)
|
||||
goto err_destroy_bundles;
|
||||
|
||||
/* Register the control device and any bundles */
|
||||
ret = gb_control_add(intf->control);
|
||||
if (ret)
|
||||
goto err_destroy_bundles;
|
||||
|
||||
list_for_each_entry_safe_reverse(bundle, tmp, &intf->bundles, links) {
|
||||
ret = gb_bundle_add(bundle);
|
||||
if (ret) {
|
||||
gb_bundle_destroy(bundle);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(manifest);
|
||||
|
||||
intf->enabled = true;
|
||||
|
@ -546,10 +560,9 @@ void gb_interface_disable(struct gb_interface *intf)
|
|||
intf->enabled = false;
|
||||
}
|
||||
|
||||
/* Register an interface and its bundles. */
|
||||
/* Register an interface. */
|
||||
int gb_interface_add(struct gb_interface *intf)
|
||||
{
|
||||
struct gb_bundle *bundle, *tmp;
|
||||
int ret;
|
||||
|
||||
ret = device_add(&intf->dev);
|
||||
|
@ -563,17 +576,6 @@ int gb_interface_add(struct gb_interface *intf)
|
|||
dev_info(&intf->dev, "DDBL1 Manufacturer=0x%08x, Product=0x%08x\n",
|
||||
intf->ddbl1_manufacturer_id, intf->ddbl1_product_id);
|
||||
|
||||
/* NOTE: ignoring errors for now */
|
||||
gb_control_add(intf->control);
|
||||
|
||||
list_for_each_entry_safe_reverse(bundle, tmp, &intf->bundles, links) {
|
||||
ret = gb_bundle_add(bundle);
|
||||
if (ret) {
|
||||
gb_bundle_destroy(bundle);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -452,8 +452,6 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
|
|||
struct gb_host_device *hd = connection->hd;
|
||||
struct gb_interface *intf;
|
||||
u8 intf_id;
|
||||
u32 vendor_id = 0;
|
||||
u32 product_id = 0;
|
||||
int ret;
|
||||
|
||||
/* The request message size has already been verified. */
|
||||
|
@ -464,27 +462,15 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
|
|||
|
||||
intf = gb_interface_find(hd, intf_id);
|
||||
if (intf) {
|
||||
/* HACK: Save Ara VID/PID for ES2 hack below */
|
||||
vendor_id = intf->vendor_id;
|
||||
product_id = intf->product_id;
|
||||
|
||||
/*
|
||||
* We have received a hotplug request for an interface that
|
||||
* already exists.
|
||||
*
|
||||
* This can happen in cases like:
|
||||
* - bootrom loading the firmware image and booting into that,
|
||||
* which only generates a hotplug event. i.e. no hot-unplug
|
||||
* event.
|
||||
* - Or the firmware on the module crashed and sent hotplug
|
||||
* request again to the SVC, which got propagated to AP.
|
||||
*
|
||||
* Remove the interface and add it again, and let user know
|
||||
* about this with a print message.
|
||||
*/
|
||||
dev_info(&svc->dev, "removing interface %u to add it again\n",
|
||||
dev_info(&svc->dev, "mode switch detected on interface %u\n",
|
||||
intf_id);
|
||||
gb_svc_intf_remove(svc, intf);
|
||||
|
||||
/* Mark as disconnected to prevent I/O during disable. */
|
||||
intf->disconnected = true;
|
||||
gb_interface_disable(intf);
|
||||
intf->disconnected = false;
|
||||
|
||||
goto enable_interface;
|
||||
}
|
||||
|
||||
intf = gb_interface_create(hd, intf_id);
|
||||
|
@ -498,19 +484,15 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
|
|||
if (ret) {
|
||||
dev_err(&svc->dev, "failed to activate interface %u: %d\n",
|
||||
intf_id, ret);
|
||||
goto err_interface_add;
|
||||
gb_interface_add(intf);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* HACK: Use Ara VID/PID from earlier boot stage.
|
||||
*
|
||||
* FIXME: remove quirk with ES2 support
|
||||
*/
|
||||
if (intf->quirks & GB_INTERFACE_QUIRK_NO_ARA_IDS) {
|
||||
intf->vendor_id = vendor_id;
|
||||
intf->product_id = product_id;
|
||||
}
|
||||
ret = gb_interface_add(intf);
|
||||
if (ret)
|
||||
goto err_interface_deactivate;
|
||||
|
||||
enable_interface:
|
||||
ret = gb_interface_enable(intf);
|
||||
if (ret) {
|
||||
dev_err(&svc->dev, "failed to enable interface %u: %d\n",
|
||||
|
@ -518,19 +500,10 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
|
|||
goto err_interface_deactivate;
|
||||
}
|
||||
|
||||
ret = gb_interface_add(intf);
|
||||
if (ret) {
|
||||
gb_interface_disable(intf);
|
||||
gb_interface_deactivate(intf);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
err_interface_deactivate:
|
||||
gb_interface_deactivate(intf);
|
||||
err_interface_add:
|
||||
gb_interface_add(intf);
|
||||
}
|
||||
|
||||
static void gb_svc_process_intf_hot_unplug(struct gb_operation *operation)
|
||||
|
|
Загрузка…
Ссылка в новой задаче