summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
*