diff options
Diffstat (limited to 'drivers/usb/dwc3/core.h')
-rw-r--r-- | drivers/usb/dwc3/core.h | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index affb3d757310..c621a0fbc9a7 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -26,6 +26,7 @@ #include <linux/dma-mapping.h> #include <linux/mm.h> #include <linux/debugfs.h> +#include <linux/wait.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -176,6 +177,7 @@ /* Global Configuration Register */ #define DWC3_GCTL_PWRDNSCALE(n) ((n) << 19) +#define DWC3_GCTL_PWRDNSCALE_MASK DWC3_GCTL_PWRDNSCALE(0x1fff) #define DWC3_GCTL_U2RSTECN (1 << 16) #define DWC3_GCTL_RAMCLKSEL(x) (((x) & DWC3_GCTL_CLK_MASK) << 6) #define DWC3_GCTL_CLK_BUS (0) @@ -451,6 +453,8 @@ #define DWC3_DEPCMD_SETTRANSFRESOURCE (0x02 << 0) #define DWC3_DEPCMD_SETEPCONFIG (0x01 << 0) +#define DWC3_DEPCMD_CMD(x) ((x) & 0xf) + /* The EP number goes 0..31 so ep0 is always out and ep1 is always in */ #define DWC3_DALEPENA_EP(n) (1 << n) @@ -500,6 +504,7 @@ struct dwc3_event_buffer { * @endpoint: usb endpoint * @pending_list: list of pending requests for this endpoint * @started_list: list of started requests on this endpoint + * @wait_end_transfer: wait_queue_head_t for waiting on End Transfer complete * @lock: spinlock for endpoint request queue traversal * @regs: pointer to first endpoint register * @trb_pool: array of transaction buffers @@ -525,6 +530,8 @@ struct dwc3_ep { struct list_head pending_list; struct list_head started_list; + wait_queue_head_t wait_end_transfer; + spinlock_t lock; void __iomem *regs; @@ -541,6 +548,8 @@ struct dwc3_ep { #define DWC3_EP_BUSY (1 << 4) #define DWC3_EP_PENDING_REQUEST (1 << 5) #define DWC3_EP_MISSED_ISOC (1 << 6) +#define DWC3_EP_END_TRANSFER_PENDING (1 << 7) +#define DWC3_EP_TRANSFER_STARTED (1 << 8) /* This last one is specific to EP0 */ #define DWC3_EP0_DIR_IN (1 << 31) @@ -740,6 +749,7 @@ struct dwc3_scratchpad_array { /** * struct dwc3 - representation of our controller * @ctrl_req: usb control request which is used for ep0 + * @drd_work - workqueue used for role swapping * @ep0_trb: trb which is used for the ctrl_req * @ep0_bounce: bounce buffer for ep0 * @zlp_buf: used when request->zero is set @@ -764,6 +774,10 @@ struct dwc3_scratchpad_array { * @maximum_speed: maximum speed requested (mainly for testing purposes) * @revision: revision register contents * @dr_mode: requested mode of operation + * @current_dr_role: current role of operation when in dual-role mode + * @desired_dr_role: desired role of operation when in dual-role mode + * @edev: extcon handle + * @edev_nb: extcon notifier * @hsphy_mode: UTMI phy mode, one of following: * - USBPHY_INTERFACE_MODE_UTMI * - USBPHY_INTERFACE_MODE_UTMIW @@ -834,9 +848,11 @@ struct dwc3_scratchpad_array { * 1 - -3.5dB de-emphasis * 2 - No de-emphasis * 3 - Reserved + * @otg_caps: the OTG capabilities from hardware point */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; + struct work_struct drd_work; struct dwc3_trb *ep0_trb; void *ep0_bounce; void *zlp_buf; @@ -874,6 +890,10 @@ struct dwc3 { size_t regs_size; enum usb_dr_mode dr_mode; + u32 current_dr_role; + u32 desired_dr_role; + struct extcon_dev *edev; + struct notifier_block edev_nb; enum usb_phy_interface hsphy_mode; u32 fladj; @@ -979,9 +999,10 @@ struct dwc3 { unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; + struct usb_otg_caps otg_caps; }; -/* -------------------------------------------------------------------------- */ +#define work_to_dwc(w) (container_of((w), struct dwc3, drd_work)) /* -------------------------------------------------------------------------- */ @@ -1046,6 +1067,9 @@ struct dwc3_event_depevt { #define DEPEVT_TRANSFER_BUS_EXPIRY 2 u32 parameters:16; + +/* For Command Complete Events */ +#define DEPEVT_PARAMETER_CMD(n) (((n) & (0xf << 8)) >> 8) } __packed; /** @@ -1180,6 +1204,16 @@ static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc, { return 0; } #endif +#if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) +int dwc3_drd_init(struct dwc3 *dwc); +void dwc3_drd_exit(struct dwc3 *dwc); +#else +static inline int dwc3_drd_init(struct dwc3 *dwc) +{ return 0; } +static inline void dwc3_drd_exit(struct dwc3 *dwc) +{ } +#endif + /* power management interface */ #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) int dwc3_gadget_suspend(struct dwc3 *dwc); |