mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			157 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 02dda1428329f58c6a71e82cfac505d7fd0bb40d Mon Sep 17 00:00:00 2001
 | ||
| From: Minas Harutyunyan <minas.harutyunyan@synopsys.com>
 | ||
| Date: Mon, 10 Dec 2018 18:09:32 +0400
 | ||
| Subject: [PATCH 313/432] usb: dwc2: Fix disable all EP's on disconnect
 | ||
| MIME-Version: 1.0
 | ||
| Content-Type: text/plain; charset=UTF-8
 | ||
| Content-Transfer-Encoding: 8bit
 | ||
| 
 | ||
| commit 4fe4f9fecc36956fd53c8edf96dd0c691ef98ff9 upstream.
 | ||
| 
 | ||
| Disabling all EP's allow to reset EP's to initial state.
 | ||
| Introduced new function dwc2_hsotg_ep_disable_lock() which
 | ||
| before calling dwc2_hsotg_ep_disable() function acquire
 | ||
| hsotg->lock and release on exiting.
 | ||
| From dwc2_hsotg_ep_disable() function removed acquiring
 | ||
| hsotg->lock.
 | ||
| In dwc2_hsotg_core_init_disconnected() function when USB
 | ||
| reset interrupt asserted disabling all ep’s by
 | ||
| dwc2_hsotg_ep_disable() function.
 | ||
| This updates eliminating sparse imbalance warnings.
 | ||
| 
 | ||
| Reverted changes in dwc2_hostg_disconnect() function.
 | ||
| Introduced new function dwc2_hsotg_ep_disable_lock().
 | ||
| Changed dwc2_hsotg_ep_ops. Now disable point to
 | ||
| dwc2_hsotg_ep_disable_lock() function.
 | ||
| In functions dwc2_hsotg_udc_stop() and dwc2_hsotg_suspend()
 | ||
| dwc2_hsotg_ep_disable() function replaced by
 | ||
| dwc2_hsotg_ep_disable_lock() function.
 | ||
| In dwc2_hsotg_ep_disable() function removed acquiring
 | ||
| of hsotg->lock.
 | ||
| 
 | ||
| Fixes: dccf1bad4be7 ("usb: dwc2: Disable all EP's on disconnect")
 | ||
| Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
 | ||
| Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
 | ||
| ---
 | ||
|  drivers/usb/dwc2/gadget.c | 41 ++++++++++++++++++++++-----------------
 | ||
|  1 file changed, 23 insertions(+), 18 deletions(-)
 | ||
| 
 | ||
| diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
 | ||
| index 79189db4bf17..138261efe744 100644
 | ||
| --- a/drivers/usb/dwc2/gadget.c
 | ||
| +++ b/drivers/usb/dwc2/gadget.c
 | ||
| @@ -3109,8 +3109,6 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg,
 | ||
|  		dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index);
 | ||
|  }
 | ||
|  
 | ||
| -static int dwc2_hsotg_ep_disable(struct usb_ep *ep);
 | ||
| -
 | ||
|  /**
 | ||
|   * dwc2_hsotg_disconnect - disconnect service
 | ||
|   * @hsotg: The device state.
 | ||
| @@ -3132,9 +3130,11 @@ void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
 | ||
|  	/* all endpoints should be shutdown */
 | ||
|  	for (ep = 0; ep < hsotg->num_of_eps; ep++) {
 | ||
|  		if (hsotg->eps_in[ep])
 | ||
| -			dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 | ||
| +			kill_all_requests(hsotg, hsotg->eps_in[ep],
 | ||
| +					  -ESHUTDOWN);
 | ||
|  		if (hsotg->eps_out[ep])
 | ||
| -			dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 | ||
| +			kill_all_requests(hsotg, hsotg->eps_out[ep],
 | ||
| +					  -ESHUTDOWN);
 | ||
|  	}
 | ||
|  
 | ||
|  	call_gadget(hsotg, disconnect);
 | ||
| @@ -3178,6 +3178,7 @@ static void dwc2_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 | ||
|  			GINTSTS_PTXFEMP |  \
 | ||
|  			GINTSTS_RXFLVL)
 | ||
|  
 | ||
| +static int dwc2_hsotg_ep_disable(struct usb_ep *ep);
 | ||
|  /**
 | ||
|   * dwc2_hsotg_core_init - issue softreset to the core
 | ||
|   * @hsotg: The device state
 | ||
| @@ -4001,10 +4002,8 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
 | ||
|  	struct dwc2_hsotg *hsotg = hs_ep->parent;
 | ||
|  	int dir_in = hs_ep->dir_in;
 | ||
|  	int index = hs_ep->index;
 | ||
| -	unsigned long flags;
 | ||
|  	u32 epctrl_reg;
 | ||
|  	u32 ctrl;
 | ||
| -	int locked;
 | ||
|  
 | ||
|  	dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep);
 | ||
|  
 | ||
| @@ -4020,10 +4019,6 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
 | ||
|  
 | ||
|  	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
 | ||
|  
 | ||
| -	locked = spin_is_locked(&hsotg->lock);
 | ||
| -	if (!locked)
 | ||
| -		spin_lock_irqsave(&hsotg->lock, flags);
 | ||
| -
 | ||
|  	ctrl = dwc2_readl(hsotg, epctrl_reg);
 | ||
|  
 | ||
|  	if (ctrl & DXEPCTL_EPENA)
 | ||
| @@ -4046,12 +4041,22 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
 | ||
|  	hs_ep->fifo_index = 0;
 | ||
|  	hs_ep->fifo_size = 0;
 | ||
|  
 | ||
| -	if (!locked)
 | ||
| -		spin_unlock_irqrestore(&hsotg->lock, flags);
 | ||
| -
 | ||
|  	return 0;
 | ||
|  }
 | ||
|  
 | ||
| +static int dwc2_hsotg_ep_disable_lock(struct usb_ep *ep)
 | ||
| +{
 | ||
| +	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 | ||
| +	struct dwc2_hsotg *hsotg = hs_ep->parent;
 | ||
| +	unsigned long flags;
 | ||
| +	int ret;
 | ||
| +
 | ||
| +	spin_lock_irqsave(&hsotg->lock, flags);
 | ||
| +	ret = dwc2_hsotg_ep_disable(ep);
 | ||
| +	spin_unlock_irqrestore(&hsotg->lock, flags);
 | ||
| +	return ret;
 | ||
| +}
 | ||
| +
 | ||
|  /**
 | ||
|   * on_list - check request is on the given endpoint
 | ||
|   * @ep: The endpoint to check.
 | ||
| @@ -4199,7 +4204,7 @@ static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
 | ||
|  
 | ||
|  static const struct usb_ep_ops dwc2_hsotg_ep_ops = {
 | ||
|  	.enable		= dwc2_hsotg_ep_enable,
 | ||
| -	.disable	= dwc2_hsotg_ep_disable,
 | ||
| +	.disable	= dwc2_hsotg_ep_disable_lock,
 | ||
|  	.alloc_request	= dwc2_hsotg_ep_alloc_request,
 | ||
|  	.free_request	= dwc2_hsotg_ep_free_request,
 | ||
|  	.queue		= dwc2_hsotg_ep_queue_lock,
 | ||
| @@ -4339,9 +4344,9 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
 | ||
|  	/* all endpoints should be shutdown */
 | ||
|  	for (ep = 1; ep < hsotg->num_of_eps; ep++) {
 | ||
|  		if (hsotg->eps_in[ep])
 | ||
| -			dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 | ||
| +			dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep);
 | ||
|  		if (hsotg->eps_out[ep])
 | ||
| -			dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 | ||
| +			dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep);
 | ||
|  	}
 | ||
|  
 | ||
|  	spin_lock_irqsave(&hsotg->lock, flags);
 | ||
| @@ -4789,9 +4794,9 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg)
 | ||
|  
 | ||
|  		for (ep = 0; ep < hsotg->num_of_eps; ep++) {
 | ||
|  			if (hsotg->eps_in[ep])
 | ||
| -				dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 | ||
| +				dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep);
 | ||
|  			if (hsotg->eps_out[ep])
 | ||
| -				dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 | ||
| +				dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep);
 | ||
|  		}
 | ||
|  	}
 | ||
|  
 | ||
| -- 
 | ||
| 2.19.1
 | ||
| 
 |