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. Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@xxxxxxxxxxxx> Acked-by: Minas Harutyunyan <Minas.Harutyunyan@xxxxxxxxxxxx> --- drivers/usb/dwc2/core.c | 16 ++++++++++++++++ drivers/usb/dwc2/core.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index cb65f7f60573..eccd96fa164e 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -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", diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 8c12b3061f7f..e1f432095565 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1423,6 +1423,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; } @@ -1467,6 +1469,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) -- 2.25.1