brcm2708: add linux 4.19 support
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0313-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch
1 From c28c22b965a3c129fd4ba70a5e6b1b2353282d46 Mon Sep 17 00:00:00 2001
2 From: Minas Harutyunyan <minas.harutyunyan@synopsys.com>
3 Date: Mon, 10 Dec 2018 18:09:32 +0400
4 Subject: [PATCH 313/703] usb: dwc2: Fix disable all EP's on disconnect
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 commit 4fe4f9fecc36956fd53c8edf96dd0c691ef98ff9 upstream.
10
11 Disabling all EP's allow to reset EP's to initial state.
12 Introduced new function dwc2_hsotg_ep_disable_lock() which
13 before calling dwc2_hsotg_ep_disable() function acquire
14 hsotg->lock and release on exiting.
15 From dwc2_hsotg_ep_disable() function removed acquiring
16 hsotg->lock.
17 In dwc2_hsotg_core_init_disconnected() function when USB
18 reset interrupt asserted disabling all ep’s by
19 dwc2_hsotg_ep_disable() function.
20 This updates eliminating sparse imbalance warnings.
21
22 Reverted changes in dwc2_hostg_disconnect() function.
23 Introduced new function dwc2_hsotg_ep_disable_lock().
24 Changed dwc2_hsotg_ep_ops. Now disable point to
25 dwc2_hsotg_ep_disable_lock() function.
26 In functions dwc2_hsotg_udc_stop() and dwc2_hsotg_suspend()
27 dwc2_hsotg_ep_disable() function replaced by
28 dwc2_hsotg_ep_disable_lock() function.
29 In dwc2_hsotg_ep_disable() function removed acquiring
30 of hsotg->lock.
31
32 Fixes: dccf1bad4be7 ("usb: dwc2: Disable all EP's on disconnect")
33 Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
34 Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
35 ---
36 drivers/usb/dwc2/gadget.c | 41 ++++++++++++++++++++++-----------------
37 1 file changed, 23 insertions(+), 18 deletions(-)
38
39 --- a/drivers/usb/dwc2/gadget.c
40 +++ b/drivers/usb/dwc2/gadget.c
41 @@ -3107,8 +3107,6 @@ static void kill_all_requests(struct dwc
42 dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index);
43 }
44
45 -static int dwc2_hsotg_ep_disable(struct usb_ep *ep);
46 -
47 /**
48 * dwc2_hsotg_disconnect - disconnect service
49 * @hsotg: The device state.
50 @@ -3130,9 +3128,11 @@ void dwc2_hsotg_disconnect(struct dwc2_h
51 /* all endpoints should be shutdown */
52 for (ep = 0; ep < hsotg->num_of_eps; ep++) {
53 if (hsotg->eps_in[ep])
54 - dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
55 + kill_all_requests(hsotg, hsotg->eps_in[ep],
56 + -ESHUTDOWN);
57 if (hsotg->eps_out[ep])
58 - dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
59 + kill_all_requests(hsotg, hsotg->eps_out[ep],
60 + -ESHUTDOWN);
61 }
62
63 call_gadget(hsotg, disconnect);
64 @@ -3176,6 +3176,7 @@ static void dwc2_hsotg_irq_fifoempty(str
65 GINTSTS_PTXFEMP | \
66 GINTSTS_RXFLVL)
67
68 +static int dwc2_hsotg_ep_disable(struct usb_ep *ep);
69 /**
70 * dwc2_hsotg_core_init - issue softreset to the core
71 * @hsotg: The device state
72 @@ -4004,10 +4005,8 @@ static int dwc2_hsotg_ep_disable(struct
73 struct dwc2_hsotg *hsotg = hs_ep->parent;
74 int dir_in = hs_ep->dir_in;
75 int index = hs_ep->index;
76 - unsigned long flags;
77 u32 epctrl_reg;
78 u32 ctrl;
79 - int locked;
80
81 dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep);
82
83 @@ -4023,10 +4022,6 @@ static int dwc2_hsotg_ep_disable(struct
84
85 epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
86
87 - locked = spin_is_locked(&hsotg->lock);
88 - if (!locked)
89 - spin_lock_irqsave(&hsotg->lock, flags);
90 -
91 ctrl = dwc2_readl(hsotg, epctrl_reg);
92
93 if (ctrl & DXEPCTL_EPENA)
94 @@ -4049,12 +4044,22 @@ static int dwc2_hsotg_ep_disable(struct
95 hs_ep->fifo_index = 0;
96 hs_ep->fifo_size = 0;
97
98 - if (!locked)
99 - spin_unlock_irqrestore(&hsotg->lock, flags);
100 -
101 return 0;
102 }
103
104 +static int dwc2_hsotg_ep_disable_lock(struct usb_ep *ep)
105 +{
106 + struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
107 + struct dwc2_hsotg *hsotg = hs_ep->parent;
108 + unsigned long flags;
109 + int ret;
110 +
111 + spin_lock_irqsave(&hsotg->lock, flags);
112 + ret = dwc2_hsotg_ep_disable(ep);
113 + spin_unlock_irqrestore(&hsotg->lock, flags);
114 + return ret;
115 +}
116 +
117 /**
118 * on_list - check request is on the given endpoint
119 * @ep: The endpoint to check.
120 @@ -4202,7 +4207,7 @@ static int dwc2_hsotg_ep_sethalt_lock(st
121
122 static const struct usb_ep_ops dwc2_hsotg_ep_ops = {
123 .enable = dwc2_hsotg_ep_enable,
124 - .disable = dwc2_hsotg_ep_disable,
125 + .disable = dwc2_hsotg_ep_disable_lock,
126 .alloc_request = dwc2_hsotg_ep_alloc_request,
127 .free_request = dwc2_hsotg_ep_free_request,
128 .queue = dwc2_hsotg_ep_queue_lock,
129 @@ -4342,9 +4347,9 @@ static int dwc2_hsotg_udc_stop(struct us
130 /* all endpoints should be shutdown */
131 for (ep = 1; ep < hsotg->num_of_eps; ep++) {
132 if (hsotg->eps_in[ep])
133 - dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
134 + dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep);
135 if (hsotg->eps_out[ep])
136 - dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
137 + dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep);
138 }
139
140 spin_lock_irqsave(&hsotg->lock, flags);
141 @@ -4792,9 +4797,9 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg
142
143 for (ep = 0; ep < hsotg->num_of_eps; ep++) {
144 if (hsotg->eps_in[ep])
145 - dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
146 + dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep);
147 if (hsotg->eps_out[ep])
148 - dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
149 + dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep);
150 }
151 }
152