.. | .. |
---|
97 | 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 | 100 | static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) |
---|
291 | 101 | { |
---|
292 | 102 | u32 ahbcfg = dwc2_readl(hsotg, GAHBCFG); |
---|
.. | .. |
---|
358 | 168 | |
---|
359 | 169 | static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) |
---|
360 | 170 | { |
---|
361 | | - int ret; |
---|
| 171 | + if (hsotg->vbus_supply) |
---|
| 172 | + return regulator_enable(hsotg->vbus_supply); |
---|
362 | 173 | |
---|
363 | | - hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); |
---|
364 | | - if (IS_ERR(hsotg->vbus_supply)) { |
---|
365 | | - ret = PTR_ERR(hsotg->vbus_supply); |
---|
366 | | - hsotg->vbus_supply = NULL; |
---|
367 | | - return ret == -ENODEV ? 0 : ret; |
---|
368 | | - } |
---|
369 | | - |
---|
370 | | - return regulator_enable(hsotg->vbus_supply); |
---|
| 174 | + return 0; |
---|
371 | 175 | } |
---|
372 | 176 | |
---|
373 | 177 | static int dwc2_vbus_supply_exit(struct dwc2_hsotg *hsotg) |
---|
.. | .. |
---|
1330 | 1134 | u32 remaining_count; |
---|
1331 | 1135 | u32 byte_count; |
---|
1332 | 1136 | u32 dword_count; |
---|
1333 | | - u32 __iomem *data_fifo; |
---|
1334 | 1137 | u32 *data_buf = (u32 *)chan->xfer_buf; |
---|
1335 | 1138 | |
---|
1336 | 1139 | if (dbg_hc(chan)) |
---|
1337 | 1140 | dev_vdbg(hsotg->dev, "%s()\n", __func__); |
---|
1338 | | - |
---|
1339 | | - data_fifo = (u32 __iomem *)(hsotg->regs + HCFIFO(chan->hc_num)); |
---|
1340 | 1141 | |
---|
1341 | 1142 | remaining_count = chan->xfer_len - chan->xfer_count; |
---|
1342 | 1143 | if (remaining_count > chan->max_packet) |
---|
.. | .. |
---|
2451 | 2252 | num_channels = hsotg->params.host_channels; |
---|
2452 | 2253 | for (i = 0; i < num_channels; i++) { |
---|
2453 | 2254 | hcchar = dwc2_readl(hsotg, HCCHAR(i)); |
---|
2454 | | - hcchar &= ~HCCHAR_CHENA; |
---|
2455 | | - hcchar |= HCCHAR_CHDIS; |
---|
2456 | | - hcchar &= ~HCCHAR_EPDIR; |
---|
2457 | | - dwc2_writel(hsotg, hcchar, HCCHAR(i)); |
---|
| 2255 | + if (hcchar & HCCHAR_CHENA) { |
---|
| 2256 | + hcchar &= ~HCCHAR_CHENA; |
---|
| 2257 | + hcchar |= HCCHAR_CHDIS; |
---|
| 2258 | + hcchar &= ~HCCHAR_EPDIR; |
---|
| 2259 | + dwc2_writel(hsotg, hcchar, HCCHAR(i)); |
---|
| 2260 | + } |
---|
2458 | 2261 | } |
---|
2459 | 2262 | |
---|
2460 | 2263 | /* Halt all channels to put them into a known state */ |
---|
2461 | 2264 | for (i = 0; i < num_channels; i++) { |
---|
2462 | 2265 | hcchar = dwc2_readl(hsotg, HCCHAR(i)); |
---|
2463 | | - hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; |
---|
2464 | | - hcchar &= ~HCCHAR_EPDIR; |
---|
2465 | | - dwc2_writel(hsotg, hcchar, HCCHAR(i)); |
---|
2466 | | - dev_dbg(hsotg->dev, "%s: Halt channel %d\n", |
---|
2467 | | - __func__, i); |
---|
| 2266 | + if (hcchar & HCCHAR_CHENA) { |
---|
| 2267 | + hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; |
---|
| 2268 | + hcchar &= ~HCCHAR_EPDIR; |
---|
| 2269 | + dwc2_writel(hsotg, hcchar, HCCHAR(i)); |
---|
| 2270 | + dev_dbg(hsotg->dev, "%s: Halt channel %d\n", |
---|
| 2271 | + __func__, i); |
---|
2468 | 2272 | |
---|
2469 | | - if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i), |
---|
2470 | | - HCCHAR_CHENA, 1000)) { |
---|
2471 | | - dev_warn(hsotg->dev, "Unable to clear enable on channel %d\n", |
---|
2472 | | - i); |
---|
| 2273 | + if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i), |
---|
| 2274 | + HCCHAR_CHENA, |
---|
| 2275 | + 1000)) { |
---|
| 2276 | + dev_warn(hsotg->dev, |
---|
| 2277 | + "Unable to clear enable on channel %d\n", |
---|
| 2278 | + i); |
---|
| 2279 | + } |
---|
2473 | 2280 | } |
---|
2474 | 2281 | } |
---|
2475 | 2282 | } |
---|
.. | .. |
---|
3844 | 3651 | "SetPortFeature - USB_PORT_FEAT_SUSPEND\n"); |
---|
3845 | 3652 | if (windex != hsotg->otg_port) |
---|
3846 | 3653 | goto error; |
---|
3847 | | - if (hsotg->params.power_down == 2) |
---|
| 3654 | + if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION) |
---|
3848 | 3655 | dwc2_enter_hibernation(hsotg, 1); |
---|
3849 | 3656 | else |
---|
3850 | 3657 | dwc2_port_suspend(hsotg, windex); |
---|
.. | .. |
---|
3862 | 3669 | break; |
---|
3863 | 3670 | |
---|
3864 | 3671 | case USB_PORT_FEAT_RESET: |
---|
3865 | | - if (hsotg->params.power_down == 2 && |
---|
| 3672 | + if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION && |
---|
3866 | 3673 | hsotg->hibernated) |
---|
3867 | 3674 | dwc2_exit_hibernation(hsotg, 0, 1, 1); |
---|
3868 | 3675 | hprt0 = dwc2_read_hprt0(hsotg); |
---|
.. | .. |
---|
4017 | 3824 | gfp_t mem_flags) |
---|
4018 | 3825 | { |
---|
4019 | 3826 | struct dwc2_hcd_urb *urb; |
---|
4020 | | - u32 size = sizeof(*urb) + iso_desc_count * |
---|
4021 | | - sizeof(struct dwc2_hcd_iso_packet_desc); |
---|
4022 | 3827 | |
---|
4023 | | - urb = kzalloc(size, mem_flags); |
---|
| 3828 | + urb = kzalloc(struct_size(urb, iso_descs, iso_desc_count), mem_flags); |
---|
4024 | 3829 | if (urb) |
---|
4025 | 3830 | urb->packet_count = iso_desc_count; |
---|
4026 | 3831 | return urb; |
---|
.. | .. |
---|
4417 | 4222 | spin_unlock_irqrestore(&hsotg->lock, flags); |
---|
4418 | 4223 | } |
---|
4419 | 4224 | |
---|
| 4225 | +static void dwc2_hcd_phy_reset_func(struct work_struct *work) |
---|
| 4226 | +{ |
---|
| 4227 | + struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg, |
---|
| 4228 | + phy_reset_work); |
---|
| 4229 | + int ret; |
---|
| 4230 | + |
---|
| 4231 | + ret = phy_reset(hsotg->phy); |
---|
| 4232 | + if (ret) |
---|
| 4233 | + dev_warn(hsotg->dev, "PHY reset failed\n"); |
---|
| 4234 | +} |
---|
| 4235 | + |
---|
4420 | 4236 | /* |
---|
4421 | 4237 | * ========================================================================= |
---|
4422 | 4238 | * Linux HC Driver Functions |
---|
.. | .. |
---|
4528 | 4344 | if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) |
---|
4529 | 4345 | goto unlock; |
---|
4530 | 4346 | |
---|
| 4347 | + if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL || |
---|
| 4348 | + hsotg->flags.b.port_connect_status == 0) |
---|
| 4349 | + goto skip_power_saving; |
---|
| 4350 | + |
---|
4531 | 4351 | /* |
---|
4532 | 4352 | * Drive USB suspend and disable port Power |
---|
4533 | 4353 | * if usb bus is not suspended. |
---|
.. | .. |
---|
4536 | 4356 | hprt0 = dwc2_read_hprt0(hsotg); |
---|
4537 | 4357 | if (hprt0 & HPRT0_CONNSTS) { |
---|
4538 | 4358 | hprt0 |= HPRT0_SUSP; |
---|
4539 | | - if (hsotg->params.power_down == |
---|
4540 | | - DWC2_POWER_DOWN_PARAM_PARTIAL) |
---|
| 4359 | + if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) |
---|
4541 | 4360 | hprt0 &= ~HPRT0_PWR; |
---|
4542 | 4361 | dwc2_writel(hsotg, hprt0, HPRT0); |
---|
4543 | | - hsotg->bus_suspended = true; |
---|
4544 | 4362 | } |
---|
4545 | 4363 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { |
---|
4546 | 4364 | spin_unlock_irqrestore(&hsotg->lock, flags); |
---|
4547 | 4365 | dwc2_vbus_supply_exit(hsotg); |
---|
4548 | 4366 | spin_lock_irqsave(&hsotg->lock, flags); |
---|
4549 | 4367 | } else { |
---|
4550 | | - pcgctl = dwc2_readl(hsotg, PCGCTL); |
---|
| 4368 | + pcgctl = readl(hsotg->regs + PCGCTL); |
---|
4551 | 4369 | pcgctl |= PCGCTL_STOPPCLK; |
---|
4552 | | - dwc2_writel(hsotg, pcgctl, PCGCTL); |
---|
| 4370 | + writel(pcgctl, hsotg->regs + PCGCTL); |
---|
4553 | 4371 | } |
---|
4554 | 4372 | } |
---|
4555 | 4373 | |
---|
.. | .. |
---|
4563 | 4381 | goto skip_power_saving; |
---|
4564 | 4382 | } |
---|
4565 | 4383 | |
---|
4566 | | - /* |
---|
4567 | | - * After entering partial_power_down, |
---|
4568 | | - * hardware is no more accessible. |
---|
4569 | | - */ |
---|
| 4384 | + /* After entering partial_power_down, hardware is no more accessible */ |
---|
4570 | 4385 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
---|
4571 | 4386 | } |
---|
4572 | 4387 | |
---|
.. | .. |
---|
4589 | 4404 | { |
---|
4590 | 4405 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); |
---|
4591 | 4406 | unsigned long flags; |
---|
4592 | | - int ret = 0; |
---|
4593 | 4407 | u32 pcgctl; |
---|
| 4408 | + int ret = 0; |
---|
4594 | 4409 | |
---|
4595 | 4410 | spin_lock_irqsave(&hsotg->lock, flags); |
---|
4596 | 4411 | |
---|
.. | .. |
---|
4599 | 4414 | |
---|
4600 | 4415 | if (hsotg->lx_state != DWC2_L2) |
---|
4601 | 4416 | goto unlock; |
---|
| 4417 | + |
---|
| 4418 | + if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) { |
---|
| 4419 | + hsotg->lx_state = DWC2_L0; |
---|
| 4420 | + goto unlock; |
---|
| 4421 | + } |
---|
4602 | 4422 | |
---|
4603 | 4423 | /* |
---|
4604 | 4424 | * Enable power if not already done. |
---|
.. | .. |
---|
4618 | 4438 | */ |
---|
4619 | 4439 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
---|
4620 | 4440 | |
---|
| 4441 | + |
---|
4621 | 4442 | /* Exit partial_power_down */ |
---|
4622 | 4443 | ret = dwc2_exit_partial_power_down(hsotg, true); |
---|
4623 | 4444 | if (ret && (ret != -ENOTSUPP)) |
---|
4624 | 4445 | dev_err(hsotg->dev, "exit partial_power_down failed\n"); |
---|
4625 | 4446 | } else { |
---|
4626 | | - pcgctl = dwc2_readl(hsotg, PCGCTL); |
---|
| 4447 | + pcgctl = readl(hsotg->regs + PCGCTL); |
---|
4627 | 4448 | pcgctl &= ~PCGCTL_STOPPCLK; |
---|
4628 | | - dwc2_writel(hsotg, pcgctl, PCGCTL); |
---|
| 4449 | + writel(pcgctl, hsotg->regs + PCGCTL); |
---|
4629 | 4450 | } |
---|
4630 | 4451 | |
---|
4631 | 4452 | hsotg->lx_state = DWC2_L0; |
---|
.. | .. |
---|
4641 | 4462 | if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { |
---|
4642 | 4463 | dwc2_vbus_supply_init(hsotg); |
---|
4643 | 4464 | |
---|
4644 | | - /* |
---|
4645 | | - * Wait for controller to correctly |
---|
4646 | | - * update D+/D- level. |
---|
4647 | | - */ |
---|
| 4465 | + /* Wait for controller to correctly update D+/D- level */ |
---|
4648 | 4466 | usleep_range(3000, 5000); |
---|
4649 | 4467 | } |
---|
4650 | 4468 | |
---|
.. | .. |
---|
4814 | 4632 | |
---|
4815 | 4633 | buf = urb->transfer_buffer; |
---|
4816 | 4634 | |
---|
4817 | | - if (hcd->self.uses_dma) { |
---|
| 4635 | + if (hcd_uses_dma(hcd)) { |
---|
4818 | 4636 | if (!buf && (urb->transfer_dma & 3)) { |
---|
4819 | 4637 | dev_err(hsotg->dev, |
---|
4820 | 4638 | "%s: unaligned transfer with no transfer_buffer", |
---|
.. | .. |
---|
4891 | 4709 | spin_unlock_irqrestore(&hsotg->lock, flags); |
---|
4892 | 4710 | urb->hcpriv = NULL; |
---|
4893 | 4711 | kfree(qtd); |
---|
4894 | | - qtd = NULL; |
---|
4895 | 4712 | fail1: |
---|
4896 | 4713 | if (qh_allocated) { |
---|
4897 | 4714 | struct dwc2_qtd *qtd2, *qtd2_tmp; |
---|
.. | .. |
---|
5194 | 5011 | destroy_workqueue(hsotg->wq_otg); |
---|
5195 | 5012 | } |
---|
5196 | 5013 | |
---|
| 5014 | + cancel_work_sync(&hsotg->phy_reset_work); |
---|
| 5015 | + |
---|
5197 | 5016 | del_timer(&hsotg->wkp_timer); |
---|
5198 | 5017 | } |
---|
5199 | 5018 | |
---|
.. | .. |
---|
5267 | 5086 | dwc2_hc_driver.reset_device = dwc2_reset_device; |
---|
5268 | 5087 | } |
---|
5269 | 5088 | |
---|
| 5089 | + if (hsotg->params.host_dma) |
---|
| 5090 | + dwc2_hc_driver.flags |= HCD_DMA; |
---|
| 5091 | + |
---|
5270 | 5092 | hcd = usb_create_hcd(&dwc2_hc_driver, hsotg->dev, dev_name(hsotg->dev)); |
---|
5271 | 5093 | if (!hcd) |
---|
5272 | 5094 | goto error1; |
---|
5273 | | - |
---|
5274 | | - if (!hsotg->params.host_dma) |
---|
5275 | | - hcd->self.uses_dma = 0; |
---|
5276 | 5095 | |
---|
5277 | 5096 | hcd->has_tt = 1; |
---|
5278 | 5097 | |
---|
5279 | 5098 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
5280 | 5099 | if (!res) { |
---|
5281 | 5100 | retval = -EINVAL; |
---|
5282 | | - goto error1; |
---|
| 5101 | + goto error2; |
---|
5283 | 5102 | } |
---|
5284 | 5103 | hcd->rsrc_start = res->start; |
---|
5285 | 5104 | hcd->rsrc_len = resource_size(res); |
---|
.. | .. |
---|
5339 | 5158 | hsotg->hc_ptr_array[i] = channel; |
---|
5340 | 5159 | } |
---|
5341 | 5160 | |
---|
5342 | | - /* Initialize hsotg start work */ |
---|
| 5161 | + /* Initialize work */ |
---|
5343 | 5162 | INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func); |
---|
5344 | | - |
---|
5345 | | - /* Initialize port reset work */ |
---|
5346 | 5163 | INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func); |
---|
| 5164 | + INIT_WORK(&hsotg->phy_reset_work, dwc2_hcd_phy_reset_func); |
---|
5347 | 5165 | |
---|
5348 | 5166 | /* |
---|
5349 | 5167 | * Allocate space for storing data on status transactions. Normally no |
---|
.. | .. |
---|
5811 | 5629 | dev_dbg(hsotg->dev, "Host hibernation restore complete\n"); |
---|
5812 | 5630 | return ret; |
---|
5813 | 5631 | } |
---|
| 5632 | + |
---|
| 5633 | +bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2) |
---|
| 5634 | +{ |
---|
| 5635 | + struct usb_device *root_hub = dwc2_hsotg_to_hcd(dwc2)->self.root_hub; |
---|
| 5636 | + |
---|
| 5637 | + /* If the controller isn't allowed to wakeup then we can power off. */ |
---|
| 5638 | + if (!device_may_wakeup(dwc2->dev)) |
---|
| 5639 | + return true; |
---|
| 5640 | + |
---|
| 5641 | + /* |
---|
| 5642 | + * We don't want to power off the PHY if something under the |
---|
| 5643 | + * root hub has wakeup enabled. |
---|
| 5644 | + */ |
---|
| 5645 | + if (usb_wakeup_enabled_descendants(root_hub)) |
---|
| 5646 | + return false; |
---|
| 5647 | + |
---|
| 5648 | + /* No reason to keep the PHY powered, so allow poweroff */ |
---|
| 5649 | + return true; |
---|
| 5650 | +} |
---|