usb: dwc2: Replace polling code with function calls
Subsystems (2)
cover usb: dwc2: Replace polling code with function calls
This series moves dwc2_hsotg_wait_bit_set polling function to core.c and replaces all the register polling parts of code with function calls
Tested on HAPS platform with DWC_hsotg IP version 3.30a.
Sevak Arakelyan (2):
usb: dwc2: Move polling function to core.c.
usb: dwc2: Use common polling function.
drivers/usb/dwc2/core.c | 84 ++++++++++++++++++++++------------------------- drivers/usb/dwc2/core.h | 4 +++ drivers/usb/dwc2/gadget.c | 38 +++------------------ drivers/usb/dwc2/hcd.c | 18 ++++------ 4 files changed, 54 insertions(+), 90 deletions(-)
Signature · 1 line
2.11.0
PATCH 1/2 usb: dwc2: Move polling function to core.c.
Move polling function to core.c so it can be used
anywhere in the code.
Signed-off-by Sevak Arakelyan <[email protected]>
--- drivers/usb/dwc2/core.c | 23 +++++++++++++++++++++++ drivers/usb/dwc2/core.h | 4 ++++ drivers/usb/dwc2/gadget.c | 14 -------------- 3 files changed, 27 insertions(+), 14 deletions(-)
drivers/usb/dwc2/core.c +23 -0
@@ -791,6 +791,29 @@ bool dwc2_hw_is_device(struct dwc2_hsotg *hsotg) (op_mode ==GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE ); } +/** +* dwc2_hsotg_wait_bit_set - Waits for bit to be set. +* @hsotg: Programming view of DWC_otg controller. +* @offset: Register's offset where bit/bits must be set. +* @mask: Mask of the bit/bits which must be set. +* @timeout: Timeout to wait. +* +* Return: 0 if bit/bits are set or -ETIMEDOUT in case of timeout. +*/ +int dwc2_hsotg_wait_bit_set (struct dwc2_hsotg *hsotg,u32 offset,u32 mask, +u32 timeout) +{ +u32 i; + +for (i =0 ; i < timeout; i++) { +if (dwc2_readl (hsotg->regs + offset) & mask) +return 0 ; +udelay (1 ); + } + +return -ETIMEDOUT ; +} +MODULE_DESCRIPTION ("DESIGNWARE HS OTG Core" );MODULE_AUTHOR ("Synopsys, Inc." );MODULE_LICENSE ("Dual BSD/GPL" );
drivers/usb/dwc2/core.h +4 -0
@@ -1124,6 +1124,10 @@ extern const struct of_device_id dwc2_of_match_table[];int dwc2_lowlevel_hw_enable (struct dwc2_hsotg *hsotg);int dwc2_lowlevel_hw_disable (struct dwc2_hsotg *hsotg); +/* Common polling function */ +int dwc2_hsotg_wait_bit_set (struct dwc2_hsotg *hs_otg,u32 reg,u32 bit, +u32 timeout); +/* Parameters */ int dwc2_get_hwparams (struct dwc2_hsotg *hsotg);int dwc2_init_params (struct dwc2_hsotg *hsotg);
drivers/usb/dwc2/gadget.c +0 -14
@@ -3694,20 +3694,6 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)return IRQ_HANDLED ; } -static int dwc2_hsotg_wait_bit_set (struct dwc2_hsotg *hs_otg,u32 reg, -u32 bit,u32 timeout) -{ -u32 i; - -for (i =0 ; i < timeout; i++) { -if (dwc2_readl (hs_otg->regs + reg) & bit) -return 0 ; -udelay (1 ); - } - -return -ETIMEDOUT ; -} -static void dwc2_hsotg_ep_stop_xfr (struct dwc2_hsotg *hsotg,struct dwc2_hsotg_ep *hs_ep) {
Signature · 1 line
2.11.0
PATCH 2/2 usb: dwc2: Use common polling function.
In reply to Sevak ArakelyanReplace all the parts of register polling code with dwc2_hsotg_wait_bit_set function calls.
Signed-off-by Sevak Arakelyan <[email protected]>
--- drivers/usb/dwc2/core.c | 61 +++++++++++++---------------------------------- drivers/usb/dwc2/gadget.c | 24 ++++--------------- drivers/usb/dwc2/hcd.c | 18 +++++--------- 3 files changed, 27 insertions(+), 76 deletions(-)
drivers/usb/dwc2/core.c +17 -44
@@ -316,7 +316,6 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)int dwc2_core_reset (struct dwc2_hsotg *hsotg,bool skip_wait) {u32 greset; -int count =0 ;bool wait_for_host_mode = false;dev_vdbg (hsotg->dev,"%s()\n" , __func__);
@@ -345,29 +344,19 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) greset =dwc2_readl (hsotg->regs +GRSTCTL ); greset |=GRSTCTL_CSFTRST ;dwc2_writel (greset, hsotg->regs +GRSTCTL ); -do { -udelay (1 ); - greset =dwc2_readl (hsotg->regs +GRSTCTL ); -if (++count >50 ) { -dev_warn (hsotg->dev, -"%s() HANG! Soft Reset GRSTCTL=%0x\n" , - __func__, greset); -return -EBUSY ; - } - }while (greset &GRSTCTL_CSFTRST ); + +if (dwc2_hsotg_wait_bit_set (hsotg,GRSTCTL ,GRSTCTL_CSFTRST ,50 )) { +dev_warn (hsotg->dev,"%s: HANG! Soft Reset timeout GRSTCTL GRSTCTL_CSFTRST\n" , + __func__); +return -EBUSY ; + }/* Wait for AHB master IDLE state */ - count =0 ; -do { -udelay (1 ); - greset =dwc2_readl (hsotg->regs +GRSTCTL ); -if (++count >50 ) { -dev_warn (hsotg->dev, -"%s() HANG! AHB Idle GRSTCTL=%0x\n" , - __func__, greset); -return -EBUSY ; - } - }while (!(greset &GRSTCTL_AHBIDLE )); +if (dwc2_hsotg_wait_bit_set (hsotg,GRSTCTL ,GRSTCTL_AHBIDLE ,50 )) { +dev_warn (hsotg->dev,"%s: HANG! AHB Idle timeout GRSTCTL GRSTCTL_AHBIDLE\n" , + __func__); +return -EBUSY ; + }if (wait_for_host_mode && !skip_wait)dwc2_wait_for_mode (hsotg, true);
@@ -665,7 +654,6 @@ void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg)void dwc2_flush_tx_fifo (struct dwc2_hsotg *hsotg,const int num) {u32 greset; -int count =0 ;dev_vdbg (hsotg->dev,"Flush Tx FIFO %d\n" , num);
@@ -673,17 +661,9 @@ void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num) greset |= num <<GRSTCTL_TXFNUM_SHIFT &GRSTCTL_TXFNUM_MASK ;dwc2_writel (greset, hsotg->regs +GRSTCTL ); -do { - greset =dwc2_readl (hsotg->regs +GRSTCTL ); -if (++count >10000 ) { -dev_warn (hsotg->dev, -"%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n" , - __func__, greset, -dwc2_readl (hsotg->regs +GNPTXSTS )); -break ; - } -udelay (1 ); - }while (greset &GRSTCTL_TXFFLSH ); +if (dwc2_hsotg_wait_bit_set (hsotg,GRSTCTL ,GRSTCTL_TXFFLSH ,10000 )) +dev_warn (hsotg->dev,"%s: HANG! timeout GRSTCTL GRSTCTL_TXFFLSH\n" , + __func__);/* Wait for at least 3 PHY Clocks */ udelay (1 );
@@ -697,22 +677,15 @@ void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num)void dwc2_flush_rx_fifo (struct dwc2_hsotg *hsotg) {u32 greset; -int count =0 ;dev_vdbg (hsotg->dev,"%s()\n" , __func__); greset =GRSTCTL_RXFFLSH ;dwc2_writel (greset, hsotg->regs +GRSTCTL ); -do { - greset =dwc2_readl (hsotg->regs +GRSTCTL ); -if (++count >10000 ) { -dev_warn (hsotg->dev,"%s() HANG! GRSTCTL=%0x\n" , - __func__, greset); -break ; - } -udelay (1 ); - }while (greset &GRSTCTL_RXFFLSH ); +if (dwc2_hsotg_wait_bit_set (hsotg,GRSTCTL ,GRSTCTL_RXFFLSH ,10000 )) +dev_warn (hsotg->dev,"%s: HANG! timeout GRSTCTL GRSTCTL_RXFFLSH\n" , + __func__);/* Wait for at least 3 PHY Clocks */ udelay (1 );
drivers/usb/dwc2/gadget.c +4 -20
@@ -292,6 +292,7 @@ static void dwc2_hsotg_init_periodic_fifos(struct dwc2_hsotg *hsotg)unsigned int ep;unsigned int addr;int fifo_count; +u32 val;u32 *txfsz = hsotg->params.g_tx_fifo_size;
@@ -2519,30 +2520,13 @@ static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,*/ static void dwc2_hsotg_txfifo_flush (struct dwc2_hsotg *hsotg,unsigned int idx) { -int timeout; -int val; -dwc2_writel (GRSTCTL_TXFNUM (idx) |GRSTCTL_TXFFLSH , hsotg->regs +GRSTCTL );/* wait until the fifo is flushed */ - timeout =100 ; - -while (1 ) { - val =dwc2_readl (hsotg->regs +GRSTCTL ); - -if ((val & (GRSTCTL_TXFFLSH )) ==0 ) -break ; - -if (--timeout ==0 ) { -dev_err (hsotg->dev, -"%s: timeout flushing fifo (GRSTCTL=%08x)\n" , - __func__, val); -break ; - } - -udelay (1 ); - } +if (dwc2_hsotg_wait_bit_set (hsotg,GRSTCTL ,GRSTCTL_TXFFLSH ,100 )) +dev_warn (hsotg->dev,"%s: timeout flushing fifo GRSTCTL_TXFFLSH\n" , + __func__); }/**
drivers/usb/dwc2/hcd.c +6 -12
@@ -2392,24 +2392,18 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)/* Halt all channels to put them into a known state */ for (i =0 ; i < num_channels; i++) { -int count =0 ; - hcchar =dwc2_readl (hsotg->regs +HCCHAR (i)); hcchar |=HCCHAR_CHENA |HCCHAR_CHDIS ; hcchar &= ~HCCHAR_EPDIR ;dwc2_writel (hcchar, hsotg->regs +HCCHAR (i));dev_dbg (hsotg->dev,"%s: Halt channel %d\n" , __func__, i); -do { - hcchar =dwc2_readl (hsotg->regs +HCCHAR (i)); -if (++count >1000 ) { -dev_err (hsotg->dev, -"Unable to clear enable on channel %d\n" , - i); -break ; - } -udelay (1 ); - }while (hcchar &HCCHAR_CHENA ); + +if (dwc2_hsotg_wait_bit_set (hsotg,HCCHAR (i), +HCCHAR_CHENA ,1000 )) { +dev_warn (hsotg->dev,"Unable to clear enable on channal %d\n" , + i); + } } }
Signature · 1 line
2.11.0