diff options
Diffstat (limited to 'drivers/usb/cdns3/cdnsp-gadget.c')
| -rw-r--r-- | drivers/usb/cdns3/cdnsp-gadget.c | 21 | 
1 files changed, 19 insertions, 2 deletions
| diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c index 4824a10df07e..55f95f41b3b4 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.c +++ b/drivers/usb/cdns3/cdnsp-gadget.c @@ -29,7 +29,8 @@  unsigned int cdnsp_port_speed(unsigned int port_status)  {  	/*Detect gadget speed based on PORTSC register*/ -	if (DEV_SUPERSPEEDPLUS(port_status)) +	if (DEV_SUPERSPEEDPLUS(port_status) || +	    DEV_SSP_GEN1x2(port_status) || DEV_SSP_GEN2x2(port_status))  		return USB_SPEED_SUPER_PLUS;  	else if (DEV_SUPERSPEED(port_status))  		return USB_SPEED_SUPER; @@ -547,6 +548,7 @@ int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)  	dma_addr_t cmd_deq_dma;  	union cdnsp_trb *event;  	u32 cycle_state; +	u32 retry = 10;  	int ret, val;  	u64 cmd_dma;  	u32  flags; @@ -578,8 +580,23 @@ int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)  		flags = le32_to_cpu(event->event_cmd.flags);  		/* Check the owner of the TRB. */ -		if ((flags & TRB_CYCLE) != cycle_state) +		if ((flags & TRB_CYCLE) != cycle_state) { +			/* +			 * Give some extra time to get chance controller +			 * to finish command before returning error code. +			 * Checking CMD_RING_BUSY is not sufficient because +			 * this bit is cleared to '0' when the Command +			 * Descriptor has been executed by controller +			 * and not when command completion event has +			 * be added to event ring. +			 */ +			if (retry--) { +				udelay(20); +				continue; +			} +  			return -EINVAL; +		}  		cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb); | 
