usb: dwc2: Clear fifo_map when resetting core.
Switching from device mode to host mode by disconnecting device cable core enters and exits form hibernation. However, the fifo map remains not cleared. It results to a WARNING (WARNING: CPU: 5 PID: 0 at drivers/usb/dwc2/ gadget.c:307 dwc2_hsotg_init_fifo+0x12/0x152 [dwc2]) if in host mode we disconnect the micro a to b host cable. Because core reset occurs. To avoid the WARNING, fifo_map should be cleared in dwc2_core_reset() function by taking into account configs. fifo_map must be cleared only if driver is configured in "CONFIG_USB_DWC2_PERIPHERAL" or "CONFIG_USB_DWC2_DUAL_ROLE" mode. - Added "static inline void dwc2_clear_fifo_map()" helper function to clear fifo_map with peripheral or dual role mode. - Added a dummy version of "dwc2_clear_fifo_map()" helper for host-only mode. Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com> Link: https://lore.kernel.org/r/20210416124731.C500AA005D@mailhost.synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4111d5f805
commit
238f65aeea
|
@ -470,6 +470,22 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait)
|
|||
dwc2_writel(hsotg, greset, GRSTCTL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Switching from device mode to host mode by disconnecting
|
||||
* device cable core enters and exits form hibernation.
|
||||
* However, the fifo map remains not cleared. It results
|
||||
* to a WARNING (WARNING: CPU: 5 PID: 0 at drivers/usb/dwc2/
|
||||
* gadget.c:307 dwc2_hsotg_init_fifo+0x12/0x152 [dwc2])
|
||||
* if in host mode we disconnect the micro a to b host
|
||||
* cable. Because core reset occurs.
|
||||
* To avoid the WARNING, fifo_map should be cleared
|
||||
* in dwc2_core_reset() function by taking into account configs.
|
||||
* fifo_map must be cleared only if driver is configured in
|
||||
* "CONFIG_USB_DWC2_PERIPHERAL" or "CONFIG_USB_DWC2_DUAL_ROLE"
|
||||
* mode.
|
||||
*/
|
||||
dwc2_clear_fifo_map(hsotg);
|
||||
|
||||
/* Wait for AHB master IDLE state */
|
||||
if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 10000)) {
|
||||
dev_warn(hsotg->dev, "%s: HANG! AHB Idle timeout GRSTCTL GRSTCTL_AHBIDLE\n",
|
||||
|
|
|
@ -1425,6 +1425,8 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
|
|||
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
|
||||
void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
|
||||
void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg);
|
||||
static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg)
|
||||
{ hsotg->fifo_map = 0; }
|
||||
#else
|
||||
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
|
||||
{ return 0; }
|
||||
|
@ -1469,6 +1471,7 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
|
|||
{ return 0; }
|
||||
static inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {}
|
||||
static inline void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg) {}
|
||||
static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) {}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
|
||||
|
|
Loading…
Reference in New Issue