blob: 8bdaa5d03dfbb9513b3aa0e54b4a39bb7e526f74 [file] [log] [blame]
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001/**
2 * dwc3_otg.c - DesignWare USB3 DRD Controller OTG
3 *
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +05304 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/usb.h>
17#include <linux/usb/hcd.h>
18#include <linux/platform_device.h>
Manu Gautamf1fceddf2012-10-12 14:02:50 +053019#include <linux/regulator/consumer.h>
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020020
21#include "core.h"
22#include "dwc3_otg.h"
23#include "io.h"
24#include "xhci.h"
25
Manu Gautamf1fceddf2012-10-12 14:02:50 +053026static void dwc3_otg_reset(struct dwc3_otg *dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020027
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +053028static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode);
29static void dwc3_otg_reset(struct dwc3_otg *dotg);
30
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020031/**
32 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
33 *
34 * This function sets the OTG registers to work in A-Device host mode.
35 * This function should be called just before entering to A-Device mode.
36 *
Manu Gautamf1fceddf2012-10-12 14:02:50 +053037 * @w: Pointer to the dwc3 otg struct
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020038 */
39static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
40{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053041 u32 reg;
42 struct dwc3 *dwc = dotg->dwc;
43 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020044
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053045 if (ext_xceiv && !ext_xceiv->otg_capability) {
46 /* Set OCTL[6](PeriMode) to 0 (host) */
47 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
48 reg &= ~DWC3_OTG_OCTL_PERIMODE;
49 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
50 } else {
51 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
52 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
53 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST);
54 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
55 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +053056}
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020057
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +053058static int dwc3_otg_set_suspend(struct usb_phy *phy, int suspend)
59{
60 struct usb_otg *otg = phy->otg;
61 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
62
63 if (dotg->host_bus_suspend == suspend)
64 return 0;
65
66 dotg->host_bus_suspend = suspend;
67 if (suspend) {
68 pm_runtime_put_sync(phy->dev);
69 } else {
70 pm_runtime_get_noresume(phy->dev);
71 pm_runtime_resume(phy->dev);
72 }
73
74 return 0;
75}
76
Manu Gautamf1fceddf2012-10-12 14:02:50 +053077/**
78 * dwc3_otg_set_host_power - Enable port power control for host operation
79 *
80 * This function enables the OTG Port Power required to operate in Host mode
81 * This function should be called only after XHCI driver has set the port
82 * power in PORTSC register.
83 *
84 * @w: Pointer to the dwc3 otg struct
85 */
86void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
87{
88 u32 osts;
89
90 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
91 if (!(osts & 0x8))
92 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
93
94 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020095}
96
97/**
98 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
99 *
100 * This function sets the OTG registers to work in B-Device peripheral mode.
101 * This function should be called just before entering to B-Device mode.
102 *
103 * @w: Pointer to the dwc3 otg workqueue.
104 */
105static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
106{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530107 u32 reg;
108 struct dwc3 *dwc = dotg->dwc;
109 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200110
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530111 if (ext_xceiv && !ext_xceiv->otg_capability) {
112 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
113 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
114 reg |= DWC3_OTG_OCTL_PERIMODE;
115 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
116 /*
117 * TODO: add more OTG registers writes for PERIPHERAL mode here,
118 * see figure 12-19 B-device flow in dwc3 Synopsis spec
119 */
120 } else {
121 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
122 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
123 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
124 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
125 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200126}
127
128/**
129 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
130 *
131 * @otg: Pointer to the otg_transceiver structure.
132 * @on: start / stop the host controller driver.
133 *
134 * Returns 0 on success otherwise negative errno.
135 */
136static int dwc3_otg_start_host(struct usb_otg *otg, int on)
137{
138 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530139 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530140 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200141 int ret = 0;
142
Manu Gautam61721592012-11-06 18:09:39 +0530143 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200144 return -EINVAL;
145
Manu Gautam61721592012-11-06 18:09:39 +0530146 if (!dotg->vbus_otg) {
147 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
148 "vbus_dwc3");
149 if (IS_ERR(dotg->vbus_otg)) {
150 dev_err(dwc->dev, "Failed to get vbus regulator\n");
151 ret = PTR_ERR(dotg->vbus_otg);
152 dotg->vbus_otg = 0;
153 return ret;
154 }
155 }
156
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200157 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530158 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200159
160 /*
161 * This should be revisited for more testing post-silicon.
162 * In worst case we may need to disconnect the root hub
163 * before stopping the controller so that it does not
164 * interfere with runtime pm/system pm.
165 * We can also consider registering and unregistering xhci
166 * platform device. It is almost similar to add_hcd and
167 * remove_hcd, But we may not use standard set_host method
168 * anymore.
169 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530170 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530171 /*
172 * FIXME If micro A cable is disconnected during system suspend,
173 * xhci platform device will be removed before runtime pm is
174 * enabled for xhci device. Due to this, disable_depth becomes
175 * greater than one and runtimepm is not enabled for next microA
176 * connect. Fix this by calling pm_runtime_init for xhci device.
177 */
178 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530179 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200180 if (ret) {
181 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530182 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200183 __func__, ret);
184 return ret;
185 }
186
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530187 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530188 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200189 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530190 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
Manu Gautam61721592012-11-06 18:09:39 +0530191 platform_device_del(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200192 return ret;
193 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530194
195 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530196 if (ext_xceiv && !ext_xceiv->otg_capability)
197 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200198 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530199 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
200
Manu Gautam61721592012-11-06 18:09:39 +0530201 platform_device_del(dwc->xhci);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530202
203 ret = regulator_disable(dotg->vbus_otg);
204 if (ret) {
205 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
206 return ret;
207 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530208 dwc3_otg_notify_host_mode(otg, on);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200209 }
210
211 return 0;
212}
213
214/**
215 * dwc3_otg_set_host - bind/unbind the host controller driver.
216 *
217 * @otg: Pointer to the otg_transceiver structure.
218 * @host: Pointer to the usb_bus structure.
219 *
220 * Returns 0 on success otherwise negative errno.
221 */
222static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
223{
224 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
225
226 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530227 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200228 __func__, host->bus_name);
229 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200230 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530231 * Though XHCI power would be set by now, but some delay is
232 * required for XHCI controller before setting OTG Port Power
233 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200234 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530235 msleep(300);
236 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200237 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530238 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200239 }
240
241 return 0;
242}
243
244/**
245 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
246 *
247 * @otg: Pointer to the otg_transceiver structure.
248 * @gadget: pointer to the usb_gadget structure.
249 *
250 * Returns 0 on success otherwise negative errno.
251 */
252static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
253{
254 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530255 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
256 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200257
258 if (!otg->gadget)
259 return -EINVAL;
260
261 if (on) {
262 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
263 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530264
265 /*
266 * Hardware reset is required to support below scenarios:
267 * 1. Host <-> peripheral switching
268 * 2. Once an endpoint is configured in DBM (BAM) mode, it
269 * can be unconfigured only after RESET
270 */
271 if (ext_xceiv && ext_xceiv->otg_capability &&
272 ext_xceiv->ext_block_reset)
273 ext_xceiv->ext_block_reset();
274
275 /* re-init core and OTG registers as block reset clears these */
276 dwc3_post_host_reset_core_init(dwc);
277 if (ext_xceiv && !ext_xceiv->otg_capability)
278 dwc3_otg_reset(dotg);
279
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200280 dwc3_otg_set_peripheral_regs(dotg);
281 usb_gadget_vbus_connect(otg->gadget);
282 } else {
283 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
284 __func__, otg->gadget->name);
285 usb_gadget_vbus_disconnect(otg->gadget);
286 }
287
288 return 0;
289}
290
291/**
292 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
293 *
294 * @otg: Pointer to the otg_transceiver structure.
295 * @gadget: pointer to the usb_gadget structure.
296 *
297 * Returns 0 on success otherwise negative errno.
298 */
299static int dwc3_otg_set_peripheral(struct usb_otg *otg,
300 struct usb_gadget *gadget)
301{
302 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
303
304 if (gadget) {
305 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
306 __func__, gadget->name);
307 otg->gadget = gadget;
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530308 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200309 } else {
310 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
311 dwc3_otg_start_peripheral(otg, 0);
312 otg->gadget = NULL;
313 otg->phy->state = OTG_STATE_UNDEFINED;
314 schedule_work(&dotg->sm_work);
315 } else {
316 otg->gadget = NULL;
317 }
318 }
319
320 return 0;
321}
322
323/**
Manu Gautam8c642812012-06-07 10:35:10 +0530324 * dwc3_ext_chg_det_done - callback to handle charger detection completion
325 * @otg: Pointer to the otg transceiver structure
326 * @charger: Pointer to the external charger structure
327 *
328 * Returns 0 on success
329 */
330static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
331{
332 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
333
334 /*
335 * Ignore chg_detection notification if BSV has gone off by this time.
336 * STOP chg_det as part of !BSV handling would reset the chg_det flags
337 */
338 if (test_bit(B_SESS_VLD, &dotg->inputs))
339 schedule_work(&dotg->sm_work);
340}
341
342/**
343 * dwc3_set_charger - bind/unbind external charger driver
344 * @otg: Pointer to the otg transceiver structure
345 * @charger: Pointer to the external charger structure
346 *
347 * Returns 0 on success
348 */
349int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
350{
351 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
352
353 dotg->charger = charger;
354 if (charger)
355 charger->notify_detection_complete = dwc3_ext_chg_det_done;
356
357 return 0;
358}
359
Manu Gautamb5067272012-07-02 09:53:41 +0530360/**
361 * dwc3_ext_event_notify - callback to handle events from external transceiver
362 * @otg: Pointer to the otg transceiver structure
363 * @event: Event reported by transceiver
364 *
365 * Returns 0 on success
366 */
367static void dwc3_ext_event_notify(struct usb_otg *otg,
368 enum dwc3_ext_events event)
369{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530370 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530371 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
372 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
373 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530374 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530375
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530376 /* Flush processing any pending events before handling new ones */
377 if (init)
378 flush_work(&dotg->sm_work);
379
Manu Gautamb5067272012-07-02 09:53:41 +0530380 if (event == DWC3_EVENT_PHY_RESUME) {
381 if (!pm_runtime_status_suspended(phy->dev)) {
382 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
383 } else {
384 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
385 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530386 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530387 if ((phy->state == OTG_STATE_A_HOST) &&
388 dotg->host_bus_suspend)
389 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530390 if (ret == -EACCES) {
391 /* pm_runtime_get may fail during system
392 resume with -EACCES error */
393 pm_runtime_disable(phy->dev);
394 pm_runtime_set_active(phy->dev);
395 pm_runtime_enable(phy->dev);
396 } else if (ret < 0) {
397 dev_warn(phy->dev, "pm_runtime_get failed!\n");
398 }
Manu Gautamb5067272012-07-02 09:53:41 +0530399 }
Manu Gautam377821c2012-09-28 16:53:24 +0530400 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530401 if (pm_runtime_status_suspended(phy->dev)) {
402 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
403 ret = pm_runtime_get(phy->dev);
404 if (ret < 0)
405 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
406 }
Jack Pham0fc12332012-11-19 13:14:22 -0800407 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530408 dev_dbg(phy->dev, "XCVR: ID set\n");
409 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800410 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530411 dev_dbg(phy->dev, "XCVR: ID clear\n");
412 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800413 }
Manu Gautam377821c2012-09-28 16:53:24 +0530414
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530415 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530416 dev_dbg(phy->dev, "XCVR: BSV set\n");
417 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530418 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530419 dev_dbg(phy->dev, "XCVR: BSV clear\n");
420 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530421 }
Manu Gautam377821c2012-09-28 16:53:24 +0530422
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530423 if (!init) {
424 init = true;
425 complete(&dotg->dwc3_xcvr_vbus_init);
426 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
427 return;
428 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530429
430 schedule_work(&dotg->sm_work);
Manu Gautamb5067272012-07-02 09:53:41 +0530431 }
Manu Gautamb5067272012-07-02 09:53:41 +0530432}
433
434/**
435 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
436 * @otg: Pointer to the otg transceiver structure
437 * @ext_xceiv: Pointer to the external transceiver struccture
438 *
439 * Returns 0 on success
440 */
441int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
442{
443 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
444
445 dotg->ext_xceiv = ext_xceiv;
446 if (ext_xceiv)
447 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
448
449 return 0;
450}
451
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530452static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
453{
454 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
455
456 if (!dotg->psy) {
457 dev_err(otg->phy->dev, "no usb power supply registered\n");
458 return;
459 }
460
461 if (host_mode)
462 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
463 else
464 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
465}
466
467static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
468{
469 static int power_supply_type;
470 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
471
472
Manu Gautam6c0ff032012-11-02 14:55:35 +0530473 if (!dotg->psy || !dotg->charger) {
474 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530475 return 0;
476 }
477
Manu Gautam6c0ff032012-11-02 14:55:35 +0530478 if (dotg->charger->charging_disabled)
479 return 0;
480
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530481 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
482 power_supply_type = POWER_SUPPLY_TYPE_USB;
483 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
484 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
485 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER)
486 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
487 else
488 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
489
490 power_supply_set_supply_type(dotg->psy, power_supply_type);
491
492 if (dotg->charger->max_power == mA)
493 return 0;
494
495 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
496
497 if (dotg->charger->max_power <= 2 && mA > 2) {
498 /* Enable charging */
499 if (power_supply_set_online(dotg->psy, true))
500 goto psy_error;
501 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
502 goto psy_error;
503 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
504 /* Disable charging */
505 if (power_supply_set_online(dotg->psy, false))
506 goto psy_error;
507 /* Set max current limit */
508 if (power_supply_set_current_limit(dotg->psy, 0))
509 goto psy_error;
510 }
511
512 power_supply_changed(dotg->psy);
513 dotg->charger->max_power = mA;
514 return 0;
515
516psy_error:
517 dev_dbg(phy->dev, "power supply error when setting property\n");
518 return -ENXIO;
519}
520
Manu Gautam8c642812012-06-07 10:35:10 +0530521/* IRQs which OTG driver is interested in handling */
522#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
523 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
524
525/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200526 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
527 * @_dotg: Pointer to out controller context structure
528 *
529 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
530 */
531static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
532{
533 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530534 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200535 int ret = IRQ_NONE;
536 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530537 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200538
539 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
540
Manu Gautam8c642812012-06-07 10:35:10 +0530541 if (!(oevt_reg & DWC3_OEVT_MASK))
542 return IRQ_NONE;
543
544 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
545
546 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
547 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200548 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530549 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200550 * function, switch from A to B or from B to A.
551 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200552
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530553 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
554 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
555 dev_dbg(phy->dev, "ID set\n");
556 set_bit(ID, &dotg->inputs);
557 } else {
558 dev_dbg(phy->dev, "ID clear\n");
559 clear_bit(ID, &dotg->inputs);
560 }
561 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
562 }
Manu Gautam8c642812012-06-07 10:35:10 +0530563
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530564 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
565 if (osts & DWC3_OTG_OSTS_BSESVALID) {
566 dev_dbg(phy->dev, "BSV set\n");
567 set_bit(B_SESS_VLD, &dotg->inputs);
568 } else {
569 dev_dbg(phy->dev, "BSV clear\n");
570 clear_bit(B_SESS_VLD, &dotg->inputs);
571 }
572 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
573 }
Manu Gautam8c642812012-06-07 10:35:10 +0530574
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200575 schedule_work(&dotg->sm_work);
576
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200577 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530578
579 /* Clear the interrupts we handled */
580 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200581 }
582
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200583 return ret;
584}
585
586/**
Manu Gautam8c642812012-06-07 10:35:10 +0530587 * dwc3_otg_init_sm - initialize OTG statemachine input
588 * @dotg: Pointer to the dwc3_otg structure
589 *
590 */
591void dwc3_otg_init_sm(struct dwc3_otg *dotg)
592{
593 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
594 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530595 struct dwc3_ext_xceiv *ext_xceiv;
596 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530597
598 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
599
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530600 /*
601 * VBUS initial state is reported after PMIC
602 * driver initialization. Wait for it.
603 */
604 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
605 if (!ret)
606 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam8c642812012-06-07 10:35:10 +0530607
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530608 ext_xceiv = dotg->ext_xceiv;
609 dwc3_otg_reset(dotg);
610 if (ext_xceiv && !ext_xceiv->otg_capability) {
611 if (osts & DWC3_OTG_OSTS_CONIDSTS)
612 set_bit(ID, &dotg->inputs);
613 else
614 clear_bit(ID, &dotg->inputs);
615
616 if (osts & DWC3_OTG_OSTS_BSESVALID)
617 set_bit(B_SESS_VLD, &dotg->inputs);
618 else
619 clear_bit(B_SESS_VLD, &dotg->inputs);
620 }
Manu Gautam8c642812012-06-07 10:35:10 +0530621}
622
623/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200624 * dwc3_otg_sm_work - workqueue function.
625 *
626 * @w: Pointer to the dwc3 otg workqueue
627 *
628 * NOTE: After any change in phy->state,
629 * we must reschdule the state machine.
630 */
631static void dwc3_otg_sm_work(struct work_struct *w)
632{
633 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
634 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530635 struct dwc3_charger *charger = dotg->charger;
636 bool work = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200637
Manu Gautamb5067272012-07-02 09:53:41 +0530638 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200639 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
640
641 /* Check OTG state */
642 switch (phy->state) {
643 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530644 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530645 if (!dotg->psy) {
646 dotg->psy = power_supply_get_by_name("usb");
647
648 if (!dotg->psy)
649 dev_err(phy->dev,
650 "couldn't get usb power supply\n");
651 }
652
Manu Gautam8c642812012-06-07 10:35:10 +0530653 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530654 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530655 dev_dbg(phy->dev, "!id\n");
656 phy->state = OTG_STATE_A_IDLE;
657 work = 1;
658 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
659 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200660 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530661 work = 1;
662 } else {
663 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530664 dev_dbg(phy->dev, "No device, trying to suspend\n");
665 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200666 }
667 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530668
669 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530670 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530671 dev_dbg(phy->dev, "!id\n");
672 phy->state = OTG_STATE_A_IDLE;
673 work = 1;
674 if (charger) {
675 if (charger->chg_type == DWC3_INVALID_CHARGER)
676 charger->start_detection(dotg->charger,
677 false);
678 else
679 charger->chg_type =
680 DWC3_INVALID_CHARGER;
681 }
682 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
683 dev_dbg(phy->dev, "b_sess_vld\n");
684 if (charger) {
685 /* Has charger been detected? If no detect it */
686 switch (charger->chg_type) {
687 case DWC3_DCP_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530688 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530689 dwc3_otg_set_power(phy,
690 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530691 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530692 break;
693 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530694 dwc3_otg_set_power(phy,
695 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530696 dwc3_otg_start_peripheral(&dotg->otg,
697 1);
698 phy->state = OTG_STATE_B_PERIPHERAL;
699 work = 1;
700 break;
701 case DWC3_SDP_CHARGER:
702 dwc3_otg_start_peripheral(&dotg->otg,
703 1);
704 phy->state = OTG_STATE_B_PERIPHERAL;
705 work = 1;
706 break;
707 default:
708 dev_dbg(phy->dev, "chg_det started\n");
709 charger->start_detection(charger, true);
710 break;
711 }
712 } else {
713 /* no charger registered, start peripheral */
714 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
715 /*
716 * Probably set_peripheral not called
717 * yet. We will re-try as soon as it
718 * will be called
719 */
Manu Gautamb5067272012-07-02 09:53:41 +0530720 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530721 "unable to start B-device\n");
722 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530723 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530724 return;
725 }
726 }
727 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530728 if (charger)
729 charger->start_detection(dotg->charger, false);
730
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530731 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530732 dev_dbg(phy->dev, "No device, trying to suspend\n");
733 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530734 }
735 break;
736
737 case OTG_STATE_B_PERIPHERAL:
738 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
739 !test_bit(ID, &dotg->inputs)) {
740 dev_dbg(phy->dev, "!id || !bsv\n");
741 dwc3_otg_start_peripheral(&dotg->otg, 0);
742 phy->state = OTG_STATE_B_IDLE;
743 if (charger)
744 charger->chg_type = DWC3_INVALID_CHARGER;
745 work = 1;
746 }
747 break;
748
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200749 case OTG_STATE_A_IDLE:
750 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530751 if (test_bit(ID, &dotg->inputs)) {
752 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200753 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530754 work = 1;
755 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530756 phy->state = OTG_STATE_A_HOST;
757 if (dwc3_otg_start_host(&dotg->otg, 1)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530758 /*
759 * Probably set_host was not called yet.
760 * We will re-try as soon as it will be called
761 */
Manu Gautamb5067272012-07-02 09:53:41 +0530762 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530763 "unable to start A-device\n");
764 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530765 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530766 return;
767 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200768 }
769 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530770
771 case OTG_STATE_A_HOST:
772 if (test_bit(ID, &dotg->inputs)) {
773 dev_dbg(phy->dev, "id\n");
774 dwc3_otg_start_host(&dotg->otg, 0);
775 phy->state = OTG_STATE_B_IDLE;
776 work = 1;
777 }
778 break;
779
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200780 default:
781 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
782
783 }
Manu Gautam8c642812012-06-07 10:35:10 +0530784
785 if (work)
786 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200787}
788
789
790/**
791 * dwc3_otg_reset - reset dwc3 otg registers.
792 *
793 * @w: Pointer to the dwc3 otg workqueue
794 */
795static void dwc3_otg_reset(struct dwc3_otg *dotg)
796{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530797 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530798 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
799
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200800 /*
801 * OCFG[2] - OTG-Version = 1
802 * OCFG[1] - HNPCap = 0
803 * OCFG[0] - SRPCap = 0
804 */
805 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
806
807 /*
808 * OCTL[6] - PeriMode = 1
809 * OCTL[5] - PrtPwrCtl = 0
810 * OCTL[4] - HNPReq = 0
811 * OCTL[3] - SesReq = 0
812 * OCTL[2] - TermSelDLPulse = 0
813 * OCTL[1] - DevSetHNPEn = 0
814 * OCTL[0] - HstSetHNPEn = 0
815 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530816 if (!once) {
817 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
818 once++;
819 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200820
821 /* Clear all otg events (interrupts) indications */
822 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
823
Manu Gautam8c642812012-06-07 10:35:10 +0530824 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530825 if (ext_xceiv && !ext_xceiv->otg_capability)
826 dwc3_writel(dotg->regs, DWC3_OEVTEN,
827 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
828 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200829}
830
831/**
832 * dwc3_otg_init - Initializes otg related registers
833 * @dwc: Pointer to out controller context structure
834 *
835 * Returns 0 on success otherwise negative errno.
836 */
837int dwc3_otg_init(struct dwc3 *dwc)
838{
839 u32 reg;
840 int ret = 0;
841 struct dwc3_otg *dotg;
842
843 dev_dbg(dwc->dev, "dwc3_otg_init\n");
844
845 /*
846 * GHWPARAMS6[10] bit is SRPSupport.
847 * This bit also reflects DWC_USB3_EN_OTG
848 */
849 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
850 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
851 /*
852 * No OTG support in the HW core.
853 * We return 0 to indicate no error, since this is acceptable
854 * situation, just continue probe the dwc3 driver without otg.
855 */
856 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
857 return 0;
858 }
859
860 /* Allocate and init otg instance */
861 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
862 if (!dotg) {
863 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
864 return -ENOMEM;
865 }
866
Manu Gautam17206c22012-06-21 10:17:53 +0530867 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
868 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
869 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200870 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530871 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200872 ret = -ENODEV;
873 goto err1;
874 }
875
876 dotg->regs = dwc->regs;
877
878 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
879 dotg->otg.set_host = dwc3_otg_set_host;
880
881 /* This reference is used by dwc3 modules for checking otg existance */
882 dwc->dotg = dotg;
883
884 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
885 if (!dotg->otg.phy) {
886 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
887 ret = -ENOMEM;
888 goto err1;
889 }
890
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530891 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200892 dotg->otg.phy->otg = &dotg->otg;
893 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530894 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530895 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200896
897 ret = usb_set_transceiver(dotg->otg.phy);
898 if (ret) {
899 dev_err(dotg->otg.phy->dev,
900 "%s: failed to set transceiver, already exists\n",
901 __func__);
902 goto err2;
903 }
904
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200905 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
906
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530907 init_completion(&dotg->dwc3_xcvr_vbus_init);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200908 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
909
910 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
911 "dwc3_otg", dotg);
912 if (ret) {
913 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
914 dotg->irq, ret);
915 goto err3;
916 }
917
Manu Gautamb5067272012-07-02 09:53:41 +0530918 pm_runtime_get(dwc->dev);
919
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200920 return 0;
921
922err3:
923 cancel_work_sync(&dotg->sm_work);
924 usb_set_transceiver(NULL);
925err2:
926 kfree(dotg->otg.phy);
927err1:
928 dwc->dotg = NULL;
929 kfree(dotg);
930
931 return ret;
932}
933
934/**
935 * dwc3_otg_exit
936 * @dwc: Pointer to out controller context structure
937 *
938 * Returns 0 on success otherwise negative errno.
939 */
940void dwc3_otg_exit(struct dwc3 *dwc)
941{
942 struct dwc3_otg *dotg = dwc->dotg;
943
944 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
945 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +0530946 if (dotg->charger)
947 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200948 cancel_work_sync(&dotg->sm_work);
949 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +0530950 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200951 free_irq(dotg->irq, dotg);
952 kfree(dotg->otg.phy);
953 kfree(dotg);
954 dwc->dotg = NULL;
955 }
956}