summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHemant Kumar <hemantk@codeaurora.org>2015-08-26 17:18:36 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:07:10 -0700
commit92f418332c16491d233a6dfe381a441ccccae0b1 (patch)
treeb5cd7a0de8634367de374f6de5c64fdf9858b90e
parenta8028071dd84eea4a3c36eb972e0abac5d77696a (diff)
usb: dwc3: Add support for POR upon composition switch
Composition switch to GSI transport based composition from another GSI transport based composition requires power on reset of USB controller to synchronize operation with USB wrapper for GSI. Specifically GSI_EN bit cannot be cleared without performing usb controller reset. Hence introduce gadget restart operation to simulate vbus off and vbus on and perform this operation from gsi bind config. Change-Id: Ie4695807c73c2d14c0d9e17c486f34a90fd93ddb Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
-rw-r--r--drivers/usb/dwc3/core.h1
-rw-r--r--drivers/usb/dwc3/gadget.c8
-rw-r--r--include/linux/usb/gadget.h15
3 files changed, 24 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index f2006c0c26bc..6886b14c8dd8 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -716,6 +716,7 @@ struct dwc3_scratchpad_array {
#define DWC3_CORE_PM_RESUME_EVENT 4
#define DWC3_CONTROLLER_CONNDONE_EVENT 5
#define DWC3_CONTROLLER_NOTIFY_OTG_EVENT 6
+#define DWC3_CONTROLLER_RESTART_USB_SESSION 10
#define MAX_INTR_STATS 10
/**
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index b63e9c0ab305..377282fc486c 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2025,6 +2025,13 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
return 0;
}
+static int dwc3_gadget_restart_usb_session(struct usb_gadget *g)
+{
+ struct dwc3 *dwc = gadget_to_dwc(g);
+
+ return dwc3_notify_event(dwc, DWC3_CONTROLLER_RESTART_USB_SESSION);
+}
+
static const struct usb_gadget_ops dwc3_gadget_ops = {
.get_frame = dwc3_gadget_get_frame,
.wakeup = dwc3_gadget_wakeup,
@@ -2033,6 +2040,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
.pullup = dwc3_gadget_pullup,
.udc_start = dwc3_gadget_start,
.udc_stop = dwc3_gadget_stop,
+ .restart = dwc3_gadget_restart_usb_session,
};
/* -------------------------------------------------------------------------- */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 7c18c70df503..3f572d5dc16d 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -649,6 +649,7 @@ struct usb_gadget_ops {
int (*vbus_session) (struct usb_gadget *, int is_active);
int (*vbus_draw) (struct usb_gadget *, unsigned mA);
int (*pullup) (struct usb_gadget *, int is_on);
+ int (*restart)(struct usb_gadget *);
int (*ioctl)(struct usb_gadget *,
unsigned code, unsigned long param);
void (*get_config_params)(struct usb_dcd_config_params *);
@@ -1049,6 +1050,20 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget)
}
/**
+ * usb_gadget_restart - software-controlled reset of USB peripheral connection
+ * @gadget:the peripheral being reset
+ *
+ * Informs controller driver for Vbus LOW followed by Vbus HIGH notification.
+ * This performs full hardware reset and re-initialization.
+ */
+static inline int usb_gadget_restart(struct usb_gadget *gadget)
+{
+ if (!gadget->ops->restart)
+ return -EOPNOTSUPP;
+ return gadget->ops->restart(gadget);
+}
+
+/**
* usb_gadget_deactivate - deactivate function which is not ready to work
* @gadget: the peripheral being deactivated
*