aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/hcd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-08 13:03:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-08 13:03:52 -0400
commit132d68d37d33f1d0b9c1f507c8b4d64c27ecec8a (patch)
treeb3c05972e5579e1574873fe745fb1358c62a269c /drivers/usb/dwc2/hcd.c
parent80f232121b69cc69a31ccb2b38c1665d770b0710 (diff)
parent3515468a87a47781f6af818773650513ff14656a (diff)
Merge tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH: "Here is the big set of USB and PHY driver patches for 5.2-rc1 There is the usual set of: - USB gadget updates - PHY driver updates and additions - USB serial driver updates and fixes - typec updates and new chips supported - mtu3 driver updates - xhci driver updates - other tiny driver updates Nothing really interesting, just constant forward progress. All of these have been in linux-next for a while with no reported issues. The usb-gadget and usb-serial trees were merged a bit "late", but both of them had been in linux-next before they got merged here last Friday" * tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (206 commits) USB: serial: f81232: implement break control USB: serial: f81232: add high baud rate support USB: serial: f81232: clear overrun flag USB: serial: f81232: fix interrupt worker not stop usb: dwc3: Rename DWC3_DCTL_LPM_ERRATA usb: dwc3: Fix default lpm_nyet_threshold value usb: dwc3: debug: Print GET_STATUS(device) tracepoint usb: dwc3: Do core validation early on probe usb: dwc3: gadget: Set lpm_capable usb: gadget: atmel: tie wake lock to running clock usb: gadget: atmel: support USB suspend usb: gadget: atmel_usba_udc: simplify setting of interrupt-enabled mask dwc2: gadget: Fix completed transfer size calculation in DDMA usb: dwc2: Set lpm mode parameters depend on HW configuration usb: dwc2: Fix channel disable flow usb: dwc2: Set actual frame number for completed ISOC transfer usb: gadget: do not use __constant_cpu_to_le16 usb: dwc2: gadget: Increase descriptors count for ISOC's usb: introduce usb_ep_type_string() function usb: dwc3: move synchronize_irq() out of the spinlock protected block ...
Diffstat (limited to 'drivers/usb/dwc2/hcd.c')
-rw-r--r--drivers/usb/dwc2/hcd.c326
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 */
104static 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
126static 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
196static 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
253static 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
290static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) 100static 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
4195static 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
4525skip_power_saving: 4364skip_power_saving:
4526 hsotg->lx_state = DWC2_L2; 4365 hsotg->lx_state = DWC2_L2;
4527unlock: 4366unlock:
@@ -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