mirror of https://github.com/OpenIPC/firmware.git
				
				
				
			
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Diff
		
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Diff
		
	
	
| diff -drupN a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
 | |
| --- a/drivers/usb/dwc2/hcd.c	2017-10-21 18:09:07.000000000 +0300
 | |
| +++ b/drivers/usb/dwc2/hcd.c	2022-06-09 05:02:34.000000000 +0300
 | |
| @@ -302,6 +302,7 @@ void dwc2_hcd_disconnect(struct dwc2_hso
 | |
|  		if (hsotg->op_state != OTG_STATE_A_SUSPEND) {
 | |
|  			dev_dbg(hsotg->dev, "Disconnect: PortPower off\n");
 | |
|  			dwc2_writel(0, hsotg->regs + HPRT0);
 | |
| +			usb_phy_vbus_off(hsotg->uphy);
 | |
|  		}
 | |
|  
 | |
|  		dwc2_disable_host_interrupts(hsotg);
 | |
| @@ -356,6 +357,7 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hs
 | |
|  	/* Turn off the vbus power */
 | |
|  	dev_dbg(hsotg->dev, "PortPower off\n");
 | |
|  	dwc2_writel(0, hsotg->regs + HPRT0);
 | |
| +	usb_phy_vbus_off(hsotg->uphy);
 | |
|  }
 | |
|  
 | |
|  /* Caller must hold driver lock */
 | |
| @@ -1367,6 +1369,7 @@ static void dwc2_conn_id_status_change(s
 | |
|  
 | |
|  	/* B-Device connector (Device Mode) */
 | |
|  	if (gotgctl & GOTGCTL_CONID_B) {
 | |
| +		usb_phy_vbus_off(hsotg->uphy);
 | |
|  		/* Wait for switch to device mode */
 | |
|  		dev_dbg(hsotg->dev, "connId B\n");
 | |
|  		while (!dwc2_is_device_mode(hsotg)) {
 | |
| @@ -1382,12 +1385,18 @@ static void dwc2_conn_id_status_change(s
 | |
|  			dev_err(hsotg->dev,
 | |
|  				"Connection id status change timed out\n");
 | |
|  		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 | |
| -		dwc2_core_init(hsotg, false, -1);
 | |
| +		dwc2_core_init(hsotg, false, -1, false);
 | |
|  		dwc2_enable_global_interrupts(hsotg);
 | |
|  		spin_lock_irqsave(&hsotg->lock, flags);
 | |
| -		dwc2_hsotg_core_init_disconnected(hsotg, false);
 | |
| -		spin_unlock_irqrestore(&hsotg->lock, flags);
 | |
| -		dwc2_hsotg_core_connect(hsotg);
 | |
| +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
 | |
| +		if(hsotg->enabled){
 | |
| +			dwc2_hsotg_core_init_disconnected(hsotg, false);
 | |
| +			spin_unlock_irqrestore(&hsotg->lock, flags);
 | |
| +			dwc2_hsotg_core_connect(hsotg);
 | |
| +		}else{
 | |
| +			spin_unlock_irqrestore(&hsotg->lock, flags);
 | |
| +		}
 | |
| +#endif
 | |
|  	} else {
 | |
|  		/* A-Device connector (Host Mode) */
 | |
|  		dev_dbg(hsotg->dev, "connId A\n");
 | |
| @@ -1405,7 +1414,7 @@ static void dwc2_conn_id_status_change(s
 | |
|  		hsotg->op_state = OTG_STATE_A_HOST;
 | |
|  
 | |
|  		/* Initialize the Core for Host mode */
 | |
| -		dwc2_core_init(hsotg, false, -1);
 | |
| +		dwc2_core_init(hsotg, false, -1, false);
 | |
|  		dwc2_enable_global_interrupts(hsotg);
 | |
|  		dwc2_hcd_start(hsotg);
 | |
|  	}
 | |
| @@ -2378,11 +2387,14 @@ static void _dwc2_hcd_stop(struct usb_hc
 | |
|  
 | |
|  static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 | |
|  {
 | |
| +	int ret = 0;
 | |
|  	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 | |
|  	unsigned long flags;
 | |
| -	int ret = 0;
 | |
|  	u32 hprt0;
 | |
|  
 | |
| +	if(!dwc2_is_host_mode(hsotg))
 | |
| +		return ret;
 | |
| +
 | |
|  	spin_lock_irqsave(&hsotg->lock, flags);
 | |
|  
 | |
|  	if (hsotg->lx_state != DWC2_L0)
 | |
| @@ -2403,6 +2415,7 @@ static int _dwc2_hcd_suspend(struct usb_
 | |
|  		hprt0 |= HPRT0_SUSP;
 | |
|  		hprt0 &= ~HPRT0_PWR;
 | |
|  		dwc2_writel(hprt0, hsotg->regs + HPRT0);
 | |
| +		usb_phy_vbus_off(hsotg->uphy);
 | |
|  	}
 | |
|  
 | |
|  	/* Enter hibernation */
 | |
| @@ -2428,18 +2441,20 @@ skip_power_saving:
 | |
|  	hsotg->lx_state = DWC2_L2;
 | |
|  unlock:
 | |
|  	spin_unlock_irqrestore(&hsotg->lock, flags);
 | |
| -
 | |
|  	return ret;
 | |
|  }
 | |
|  
 | |
|  static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 | |
|  {
 | |
| +
 | |
| +	int ret = 0;
 | |
|  	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 | |
|  	unsigned long flags;
 | |
| -	int ret = 0;
 | |
|  
 | |
| -	spin_lock_irqsave(&hsotg->lock, flags);
 | |
| +	if(!dwc2_is_host_mode(hsotg))
 | |
| +		return ret;
 | |
|  
 | |
| +	spin_lock_irqsave(&hsotg->lock, flags);
 | |
|  	if (hsotg->lx_state != DWC2_L2)
 | |
|  		goto unlock;
 | |
|  
 | |
| @@ -2487,6 +2502,7 @@ static int _dwc2_hcd_resume(struct usb_h
 | |
|  		 * Clear Port Enable and Port Status changes.
 | |
|  		 * Enable Port Power.
 | |
|  		 */
 | |
| +		usb_phy_vbus_on(hsotg->uphy);
 | |
|  		dwc2_writel(HPRT0_PWR | HPRT0_CONNDET |
 | |
|  				HPRT0_ENACHG, hsotg->regs + HPRT0);
 | |
|  		/* Wait for controller to detect Port Connect */
 | |
| @@ -2496,7 +2512,6 @@ static int _dwc2_hcd_resume(struct usb_h
 | |
|  	return ret;
 | |
|  unlock:
 | |
|  	spin_unlock_irqrestore(&hsotg->lock, flags);
 | |
| -
 | |
|  	return ret;
 | |
|  }
 | |
|  
 | |
| @@ -3054,7 +3069,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hso
 | |
|  	dwc2_disable_global_interrupts(hsotg);
 | |
|  
 | |
|  	/* Initialize the DWC_otg core, and select the Phy type */
 | |
| -	retval = dwc2_core_init(hsotg, true, irq);
 | |
| +	retval = dwc2_core_init(hsotg, true, irq, true);
 | |
|  	if (retval)
 | |
|  		goto error2;
 | |
|  
 |