From 55742d2a071a569bf20f90d37b1b5b8a25a3f882 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 27 May 2016 17:26:40 +0200 Subject: greybus: interface: implement generic mode-switch functionality Add a generic interface for bundle drivers to use to request that a mode switch is carried out on its behalf. Mode switching involves tearing down all connections to an interface, sending a unidirectional mode-switch request, and waiting for a mailbox event that triggers deferred control connection reset and re-enumeration of the interface. In case of a timeout waiting for the interface mailbox event, or on other errors, the interface is powered off. All of this needs to be done by core from work-queue context in order not to block incoming SVC requests and bundle-device tear down. Care must also be taken to serialise against concurrent module removal events and eject requests. Special handling of legacy mode-switching is also added in order to continue to support the ES3 bootrom. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/interface.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/staging/greybus/interface.h') diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h index e833f7df025d..603f146dce42 100644 --- a/drivers/staging/greybus/interface.h +++ b/drivers/staging/greybus/interface.h @@ -14,6 +14,7 @@ #define GB_INTERFACE_QUIRK_NO_INIT_STATUS BIT(1) #define GB_INTERFACE_QUIRK_NO_ARA_IDS BIT(2) #define GB_INTERFACE_QUIRK_FORCED_DISABLE BIT(3) +#define GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH BIT(4) struct gb_interface { struct device dev; @@ -40,9 +41,14 @@ struct gb_interface { struct mutex mutex; bool disconnected; + bool ejected; bool active; bool enabled; + bool mode_switch; + + struct work_struct mode_switch_work; + struct completion mode_switch_completion; }; #define to_gb_interface(d) container_of(d, struct gb_interface, dev) @@ -55,5 +61,9 @@ void gb_interface_disable(struct gb_interface *intf); int gb_interface_add(struct gb_interface *intf); void gb_interface_del(struct gb_interface *intf); void gb_interface_put(struct gb_interface *intf); +void gb_interface_mailbox_event(struct gb_interface *intf, u16 result, + u32 mailbox); + +int gb_interface_request_mode_switch(struct gb_interface *intf); #endif /* __INTERFACE_H */ -- cgit v1.2.3-55-g7522