diff options
Diffstat (limited to 'drivers/usb/dwc2/hcd.c')
-rw-r--r-- | drivers/usb/dwc2/hcd.c | 326 |
1 files changed, 88 insertions, 238 deletions
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 3f087962f498..b50ec3714fd8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
@@ -97,196 +97,6 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) | |||
97 | dwc2_writel(hsotg, intmsk, GINTMSK); | 97 | dwc2_writel(hsotg, intmsk, GINTMSK); |
98 | } | 98 | } |
99 | 99 | ||
100 | /* | ||
101 | * Initializes the FSLSPClkSel field of the HCFG register depending on the | ||
102 | * PHY type | ||
103 | */ | ||
104 | static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) | ||
105 | { | ||
106 | u32 hcfg, val; | ||
107 | |||
108 | if ((hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && | ||
109 | hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && | ||
110 | hsotg->params.ulpi_fs_ls) || | ||
111 | hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) { | ||
112 | /* Full speed PHY */ | ||
113 | val = HCFG_FSLSPCLKSEL_48_MHZ; | ||
114 | } else { | ||
115 | /* High speed PHY running at full speed or high speed */ | ||
116 | val = HCFG_FSLSPCLKSEL_30_60_MHZ; | ||
117 | } | ||
118 | |||
119 | dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val); | ||
120 | hcfg = dwc2_readl(hsotg, HCFG); | ||
121 | hcfg &= ~HCFG_FSLSPCLKSEL_MASK; | ||
122 | hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT; | ||
123 | dwc2_writel(hsotg, hcfg, HCFG); | ||
124 | } | ||
125 | |||
126 | static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | ||
127 | { | ||
128 | u32 usbcfg, ggpio, i2cctl; | ||
129 | int retval = 0; | ||
130 | |||
131 | /* | ||
132 | * core_init() is now called on every switch so only call the | ||
133 | * following for the first time through | ||
134 | */ | ||
135 | if (select_phy) { | ||
136 | dev_dbg(hsotg->dev, "FS PHY selected\n"); | ||
137 | |||
138 | usbcfg = dwc2_readl(hsotg, GUSBCFG); | ||
139 | if (!(usbcfg & GUSBCFG_PHYSEL)) { | ||
140 | usbcfg |= GUSBCFG_PHYSEL; | ||
141 | dwc2_writel(hsotg, usbcfg, GUSBCFG); | ||
142 | |||
143 | /* Reset after a PHY select */ | ||
144 | retval = dwc2_core_reset(hsotg, false); | ||
145 | |||
146 | if (retval) { | ||
147 | dev_err(hsotg->dev, | ||
148 | "%s: Reset failed, aborting", __func__); | ||
149 | return retval; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | if (hsotg->params.activate_stm_fs_transceiver) { | ||
154 | ggpio = dwc2_readl(hsotg, GGPIO); | ||
155 | if (!(ggpio & GGPIO_STM32_OTG_GCCFG_PWRDWN)) { | ||
156 | dev_dbg(hsotg->dev, "Activating transceiver\n"); | ||
157 | /* | ||
158 | * STM32F4x9 uses the GGPIO register as general | ||
159 | * core configuration register. | ||
160 | */ | ||
161 | ggpio |= GGPIO_STM32_OTG_GCCFG_PWRDWN; | ||
162 | dwc2_writel(hsotg, ggpio, GGPIO); | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also | ||
169 | * do this on HNP Dev/Host mode switches (done in dev_init and | ||
170 | * host_init). | ||
171 | */ | ||
172 | if (dwc2_is_host_mode(hsotg)) | ||
173 | dwc2_init_fs_ls_pclk_sel(hsotg); | ||
174 | |||
175 | if (hsotg->params.i2c_enable) { | ||
176 | dev_dbg(hsotg->dev, "FS PHY enabling I2C\n"); | ||
177 | |||
178 | /* Program GUSBCFG.OtgUtmiFsSel to I2C */ | ||
179 | usbcfg = dwc2_readl(hsotg, GUSBCFG); | ||
180 | usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL; | ||
181 | dwc2_writel(hsotg, usbcfg, GUSBCFG); | ||
182 | |||
183 | /* Program GI2CCTL.I2CEn */ | ||
184 | i2cctl = dwc2_readl(hsotg, GI2CCTL); | ||
185 | i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK; | ||
186 | i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT; | ||
187 | i2cctl &= ~GI2CCTL_I2CEN; | ||
188 | dwc2_writel(hsotg, i2cctl, GI2CCTL); | ||
189 | i2cctl |= GI2CCTL_I2CEN; | ||
190 | dwc2_writel(hsotg, i2cctl, GI2CCTL); | ||
191 | } | ||
192 | |||
193 | return retval; | ||
194 | } | ||
195 | |||
196 | static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | ||
197 | { | ||
198 | u32 usbcfg, usbcfg_old; | ||
199 | int retval = 0; | ||
200 | |||
201 | if (!select_phy) | ||
202 | return 0; | ||
203 | |||
204 | usbcfg = dwc2_readl(hsotg, GUSBCFG); | ||
205 | usbcfg_old = usbcfg; | ||
206 | |||
207 | /* | ||
208 | * HS PHY parameters. These parameters are preserved during soft reset | ||
209 | * so only program the first time. Do a soft reset immediately after | ||
210 | * setting phyif. | ||
211 | */ | ||
212 | switch (hsotg->params.phy_type) { | ||
213 | case DWC2_PHY_TYPE_PARAM_ULPI: | ||
214 | /* ULPI interface */ | ||
215 | dev_dbg(hsotg->dev, "HS ULPI PHY selected\n"); | ||
216 | usbcfg |= GUSBCFG_ULPI_UTMI_SEL; | ||
217 | usbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); | ||
218 | if (hsotg->params.phy_ulpi_ddr) | ||
219 | usbcfg |= GUSBCFG_DDRSEL; | ||
220 | |||
221 | /* Set external VBUS indicator as needed. */ | ||
222 | if (hsotg->params.oc_disable) | ||
223 | usbcfg |= (GUSBCFG_ULPI_INT_VBUS_IND | | ||
224 | GUSBCFG_INDICATORPASSTHROUGH); | ||
225 | break; | ||
226 | case DWC2_PHY_TYPE_PARAM_UTMI: | ||
227 | /* UTMI+ interface */ | ||
228 | dev_dbg(hsotg->dev, "HS UTMI+ PHY selected\n"); | ||
229 | usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); | ||
230 | if (hsotg->params.phy_utmi_width == 16) | ||
231 | usbcfg |= GUSBCFG_PHYIF16; | ||
232 | break; | ||
233 | default: | ||
234 | dev_err(hsotg->dev, "FS PHY selected at HS!\n"); | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | if (usbcfg != usbcfg_old) { | ||
239 | dwc2_writel(hsotg, usbcfg, GUSBCFG); | ||
240 | |||
241 | /* Reset after setting the PHY parameters */ | ||
242 | retval = dwc2_core_reset(hsotg, false); | ||
243 | if (retval) { | ||
244 | dev_err(hsotg->dev, | ||
245 | "%s: Reset failed, aborting", __func__); | ||
246 | return retval; | ||
247 | } | ||
248 | } | ||
249 | |||
250 | return retval; | ||
251 | } | ||
252 | |||
253 | static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | ||
254 | { | ||
255 | u32 usbcfg; | ||
256 | int retval = 0; | ||
257 | |||
258 | if ((hsotg->params.speed == DWC2_SPEED_PARAM_FULL || | ||
259 | hsotg->params.speed == DWC2_SPEED_PARAM_LOW) && | ||
260 | hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS) { | ||
261 | /* If FS/LS mode with FS/LS PHY */ | ||
262 | retval = dwc2_fs_phy_init(hsotg, select_phy); | ||
263 | if (retval) | ||
264 | return retval; | ||
265 | } else { | ||
266 | /* High speed PHY */ | ||
267 | retval = dwc2_hs_phy_init(hsotg, select_phy); | ||
268 | if (retval) | ||
269 | return retval; | ||
270 | } | ||
271 | |||
272 | if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && | ||
273 | hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && | ||
274 | hsotg->params.ulpi_fs_ls) { | ||
275 | dev_dbg(hsotg->dev, "Setting ULPI FSLS\n"); | ||
276 | usbcfg = dwc2_readl(hsotg, GUSBCFG); | ||
277 | usbcfg |= GUSBCFG_ULPI_FS_LS; | ||
278 | usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M; | ||
279 | dwc2_writel(hsotg, usbcfg, GUSBCFG); | ||
280 | } else { | ||
281 | usbcfg = dwc2_readl(hsotg, GUSBCFG); | ||
282 | usbcfg &= ~GUSBCFG_ULPI_FS_LS; | ||
283 | usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M; | ||
284 | dwc2_writel(hsotg, usbcfg, GUSBCFG); | ||
285 | } | ||
286 | |||
287 | return retval; | ||
288 | } | ||
289 | |||
290 | static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) | 100 | static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) |
291 | { | 101 | { |
292 | u32 ahbcfg = dwc2_readl(hsotg, GAHBCFG); | 102 | u32 ahbcfg = dwc2_readl(hsotg, GAHBCFG); |
@@ -2437,25 +2247,31 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg) | |||
2437 | num_channels = hsotg->params.host_channels; | 2247 | num_channels = hsotg->params.host_channels; |
2438 | for (i = 0; i < num_channels; i++) { | 2248 | for (i = 0; i < num_channels; i++) { |
2439 | hcchar = dwc2_readl(hsotg, HCCHAR(i)); | 2249 | hcchar = dwc2_readl(hsotg, HCCHAR(i)); |
2440 | hcchar &= ~HCCHAR_CHENA; | 2250 | if (hcchar & HCCHAR_CHENA) { |
2441 | hcchar |= HCCHAR_CHDIS; | 2251 | hcchar &= ~HCCHAR_CHENA; |
2442 | hcchar &= ~HCCHAR_EPDIR; | 2252 | hcchar |= HCCHAR_CHDIS; |
2443 | dwc2_writel(hsotg, hcchar, HCCHAR(i)); | 2253 | hcchar &= ~HCCHAR_EPDIR; |
2254 | dwc2_writel(hsotg, hcchar, HCCHAR(i)); | ||
2255 | } | ||
2444 | } | 2256 | } |
2445 | 2257 | ||
2446 | /* Halt all channels to put them into a known state */ | 2258 | /* Halt all channels to put them into a known state */ |
2447 | for (i = 0; i < num_channels; i++) { | 2259 | for (i = 0; i < num_channels; i++) { |
2448 | hcchar = dwc2_readl(hsotg, HCCHAR(i)); | 2260 | hcchar = dwc2_readl(hsotg, HCCHAR(i)); |
2449 | hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; | 2261 | if (hcchar & HCCHAR_CHENA) { |
2450 | hcchar &= ~HCCHAR_EPDIR; | 2262 | hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; |
2451 | dwc2_writel(hsotg, hcchar, HCCHAR(i)); | 2263 | hcchar &= ~HCCHAR_EPDIR; |
2452 | dev_dbg(hsotg->dev, "%s: Halt channel %d\n", | 2264 | dwc2_writel(hsotg, hcchar, HCCHAR(i)); |
2453 | __func__, i); | 2265 | dev_dbg(hsotg->dev, "%s: Halt channel %d\n", |
2454 | 2266 | __func__, i); | |
2455 | if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i), | 2267 | |
2456 | HCCHAR_CHENA, 1000)) { | 2268 | if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i), |
2457 | dev_warn(hsotg->dev, "Unable to clear enable on channel %d\n", | 2269 | HCCHAR_CHENA, |
2458 | i); | 2270 | 1000)) { |
2271 | dev_warn(hsotg->dev, | ||
2272 | "Unable to clear enable on channel %d\n", | ||
2273 | i); | ||
2274 | } | ||
2459 | } | 2275 | } |
2460 | } | 2276 | } |
2461 | } | 2277 | } |
@@ -4376,6 +4192,17 @@ static void dwc2_hcd_reset_func(struct work_struct *work) | |||
4376 | spin_unlock_irqrestore(&hsotg->lock, flags); | 4192 | spin_unlock_irqrestore(&hsotg->lock, flags); |
4377 | } | 4193 | } |
4378 | 4194 | ||
4195 | static void dwc2_hcd_phy_reset_func(struct work_struct *work) | ||
4196 | { | ||
4197 | struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, | ||
4198 | phy_reset_work); | ||
4199 | int ret; | ||
4200 | |||
4201 | ret = phy_reset(hsotg->phy); | ||
4202 | if (ret) | ||
4203 | dev_warn(hsotg->dev, "PHY reset failed\n"); | ||
4204 | } | ||
4205 | |||
4379 | /* | 4206 | /* |
4380 | * ========================================================================= | 4207 | * ========================================================================= |
4381 | * Linux HC Driver Functions | 4208 | * Linux HC Driver Functions |
@@ -4471,6 +4298,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) | |||
4471 | unsigned long flags; | 4298 | unsigned long flags; |
4472 | int ret = 0; | 4299 | int ret = 0; |
4473 | u32 hprt0; | 4300 | u32 hprt0; |
4301 | u32 pcgctl; | ||
4474 | 4302 | ||
4475 | spin_lock_irqsave(&hsotg->lock, flags); | 4303 | spin_lock_irqsave(&hsotg->lock, flags); |
4476 | 4304 | ||
@@ -4486,7 +4314,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) | |||
4486 | if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) | 4314 | if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) |
4487 | goto unlock; | 4315 | goto unlock; |
4488 | 4316 | ||
4489 | if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) | 4317 | if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) |
4490 | goto skip_power_saving; | 4318 | goto skip_power_saving; |
4491 | 4319 | ||
4492 | /* | 4320 | /* |
@@ -4495,21 +4323,35 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) | |||
4495 | */ | 4323 | */ |
4496 | if (!hsotg->bus_suspended) { | 4324 | if (!hsotg->bus_suspended) { |
4497 | hprt0 = dwc2_read_hprt0(hsotg); | 4325 | hprt0 = dwc2_read_hprt0(hsotg); |
4498 | hprt0 |= HPRT0_SUSP; | 4326 | if (hprt0 & HPRT0_CONNSTS) { |
4499 | hprt0 &= ~HPRT0_PWR; | 4327 | hprt0 |= HPRT0_SUSP; |
4500 | dwc2_writel(hsotg, hprt0, HPRT0); | 4328 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) |
4501 | spin_unlock_irqrestore(&hsotg->lock, flags); | 4329 | hprt0 &= ~HPRT0_PWR; |
4502 | dwc2_vbus_supply_exit(hsotg); | 4330 | dwc2_writel(hsotg, hprt0, HPRT0); |
4503 | spin_lock_irqsave(&hsotg->lock, flags); | 4331 | } |
4332 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { | ||
4333 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
4334 | dwc2_vbus_supply_exit(hsotg); | ||
4335 | spin_lock_irqsave(&hsotg->lock, flags); | ||
4336 | } else { | ||
4337 | pcgctl = readl(hsotg->regs + PCGCTL); | ||
4338 | pcgctl |= PCGCTL_STOPPCLK; | ||
4339 | writel(pcgctl, hsotg->regs + PCGCTL); | ||
4340 | } | ||
4504 | } | 4341 | } |
4505 | 4342 | ||
4506 | /* Enter partial_power_down */ | 4343 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { |
4507 | ret = dwc2_enter_partial_power_down(hsotg); | 4344 | /* Enter partial_power_down */ |
4508 | if (ret) { | 4345 | ret = dwc2_enter_partial_power_down(hsotg); |
4509 | if (ret != -ENOTSUPP) | 4346 | if (ret) { |
4510 | dev_err(hsotg->dev, | 4347 | if (ret != -ENOTSUPP) |
4511 | "enter partial_power_down failed\n"); | 4348 | dev_err(hsotg->dev, |
4512 | goto skip_power_saving; | 4349 | "enter partial_power_down failed\n"); |
4350 | goto skip_power_saving; | ||
4351 | } | ||
4352 | |||
4353 | /* After entering partial_power_down, hardware is no more accessible */ | ||
4354 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
4513 | } | 4355 | } |
4514 | 4356 | ||
4515 | /* Ask phy to be suspended */ | 4357 | /* Ask phy to be suspended */ |
@@ -4519,9 +4361,6 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) | |||
4519 | spin_lock_irqsave(&hsotg->lock, flags); | 4361 | spin_lock_irqsave(&hsotg->lock, flags); |
4520 | } | 4362 | } |
4521 | 4363 | ||
4522 | /* After entering partial_power_down, hardware is no more accessible */ | ||
4523 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
4524 | |||
4525 | skip_power_saving: | 4364 | skip_power_saving: |
4526 | hsotg->lx_state = DWC2_L2; | 4365 | hsotg->lx_state = DWC2_L2; |
4527 | unlock: | 4366 | unlock: |
@@ -4534,6 +4373,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) | |||
4534 | { | 4373 | { |
4535 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); | 4374 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); |
4536 | unsigned long flags; | 4375 | unsigned long flags; |
4376 | u32 pcgctl; | ||
4537 | int ret = 0; | 4377 | int ret = 0; |
4538 | 4378 | ||
4539 | spin_lock_irqsave(&hsotg->lock, flags); | 4379 | spin_lock_irqsave(&hsotg->lock, flags); |
@@ -4544,18 +4384,12 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) | |||
4544 | if (hsotg->lx_state != DWC2_L2) | 4384 | if (hsotg->lx_state != DWC2_L2) |
4545 | goto unlock; | 4385 | goto unlock; |
4546 | 4386 | ||
4547 | if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) { | 4387 | if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) { |
4548 | hsotg->lx_state = DWC2_L0; | 4388 | hsotg->lx_state = DWC2_L0; |
4549 | goto unlock; | 4389 | goto unlock; |
4550 | } | 4390 | } |
4551 | 4391 | ||
4552 | /* | 4392 | /* |
4553 | * Set HW accessible bit before powering on the controller | ||
4554 | * since an interrupt may rise. | ||
4555 | */ | ||
4556 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
4557 | |||
4558 | /* | ||
4559 | * Enable power if not already done. | 4393 | * Enable power if not already done. |
4560 | * This must not be spinlocked since duration | 4394 | * This must not be spinlocked since duration |
4561 | * of this call is unknown. | 4395 | * of this call is unknown. |
@@ -4566,10 +4400,23 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) | |||
4566 | spin_lock_irqsave(&hsotg->lock, flags); | 4400 | spin_lock_irqsave(&hsotg->lock, flags); |
4567 | } | 4401 | } |
4568 | 4402 | ||
4569 | /* Exit partial_power_down */ | 4403 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { |
4570 | ret = dwc2_exit_partial_power_down(hsotg, true); | 4404 | /* |
4571 | if (ret && (ret != -ENOTSUPP)) | 4405 | * Set HW accessible bit before powering on the controller |
4572 | dev_err(hsotg->dev, "exit partial_power_down failed\n"); | 4406 | * since an interrupt may rise. |
4407 | */ | ||
4408 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
4409 | |||
4410 | |||
4411 | /* Exit partial_power_down */ | ||
4412 | ret = dwc2_exit_partial_power_down(hsotg, true); | ||
4413 | if (ret && (ret != -ENOTSUPP)) | ||
4414 | dev_err(hsotg->dev, "exit partial_power_down failed\n"); | ||
4415 | } else { | ||
4416 | pcgctl = readl(hsotg->regs + PCGCTL); | ||
4417 | pcgctl &= ~PCGCTL_STOPPCLK; | ||
4418 | writel(pcgctl, hsotg->regs + PCGCTL); | ||
4419 | } | ||
4573 | 4420 | ||
4574 | hsotg->lx_state = DWC2_L0; | 4421 | hsotg->lx_state = DWC2_L0; |
4575 | 4422 | ||
@@ -4581,10 +4428,12 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) | |||
4581 | spin_unlock_irqrestore(&hsotg->lock, flags); | 4428 | spin_unlock_irqrestore(&hsotg->lock, flags); |
4582 | dwc2_port_resume(hsotg); | 4429 | dwc2_port_resume(hsotg); |
4583 | } else { | 4430 | } else { |
4584 | dwc2_vbus_supply_init(hsotg); | 4431 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { |
4432 | dwc2_vbus_supply_init(hsotg); | ||
4585 | 4433 | ||
4586 | /* Wait for controller to correctly update D+/D- level */ | 4434 | /* Wait for controller to correctly update D+/D- level */ |
4587 | usleep_range(3000, 5000); | 4435 | usleep_range(3000, 5000); |
4436 | } | ||
4588 | 4437 | ||
4589 | /* | 4438 | /* |
4590 | * Clear Port Enable and Port Status changes. | 4439 | * Clear Port Enable and Port Status changes. |
@@ -5130,6 +4979,8 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg) | |||
5130 | destroy_workqueue(hsotg->wq_otg); | 4979 | destroy_workqueue(hsotg->wq_otg); |
5131 | } | 4980 | } |
5132 | 4981 | ||
4982 | cancel_work_sync(&hsotg->phy_reset_work); | ||
4983 | |||
5133 | del_timer(&hsotg->wkp_timer); | 4984 | del_timer(&hsotg->wkp_timer); |
5134 | } | 4985 | } |
5135 | 4986 | ||
@@ -5271,11 +5122,10 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg) | |||
5271 | hsotg->hc_ptr_array[i] = channel; | 5122 | hsotg->hc_ptr_array[i] = channel; |
5272 | } | 5123 | } |
5273 | 5124 | ||
5274 | /* Initialize hsotg start work */ | 5125 | /* Initialize work */ |
5275 | INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func); | 5126 | INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func); |
5276 | |||
5277 | /* Initialize port reset work */ | ||
5278 | INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func); | 5127 | INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func); |
5128 | INIT_WORK(&hsotg->phy_reset_work, dwc2_hcd_phy_reset_func); | ||
5279 | 5129 | ||
5280 | /* | 5130 | /* |
5281 | * Allocate space for storing data on status transactions. Normally no | 5131 | * Allocate space for storing data on status transactions. Normally no |