core.c 17.6 KB
Newer Older
1 2 3 4 5 6 7 8
/**
 * core.c - DesignWare USB3 DRD Controller Core file
 *
 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
 *
 * Authors: Felipe Balbi <balbi@ti.com>,
 *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 *
F
Felipe Balbi 已提交
9 10 11
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2  of
 * the License as published by the Free Software Foundation.
12
 *
F
Felipe Balbi 已提交
13 14 15 16
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
17
 *
F
Felipe Balbi 已提交
18 19
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 21
 */

22
#include <linux/module.h>
23 24 25 26 27 28 29 30 31 32 33
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
34
#include <linux/of.h>
35

F
Felipe Balbi 已提交
36
#include <linux/usb/otg.h>
37 38
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
39
#include <linux/usb/of.h>
40

41
#include "platform_data.h"
42 43 44 45 46 47
#include "core.h"
#include "gadget.h"
#include "io.h"

#include "debug.h"

48 49
/* -------------------------------------------------------------------------- */

50 51 52 53 54 55 56 57 58
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
{
	u32 reg;

	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
	reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
	reg |= DWC3_GCTL_PRTCAPDIR(mode);
	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
}
59

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
/**
 * dwc3_core_soft_reset - Issues core soft reset and PHY reset
 * @dwc: pointer to our context structure
 */
static void dwc3_core_soft_reset(struct dwc3 *dwc)
{
	u32		reg;

	/* Before Resetting PHY, put Core in Reset */
	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
	reg |= DWC3_GCTL_CORESOFTRESET;
	dwc3_writel(dwc->regs, DWC3_GCTL, reg);

	/* Assert USB3 PHY reset */
	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
	reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);

	/* Assert USB2 PHY reset */
	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
	reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);

F
Felipe Balbi 已提交
83 84
	usb_phy_init(dwc->usb2_phy);
	usb_phy_init(dwc->usb3_phy);
85 86 87 88 89 90 91 92 93 94 95 96
	mdelay(100);

	/* Clear USB3 PHY reset */
	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
	reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);

	/* Clear USB2 PHY reset */
	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
	reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);

97 98
	mdelay(100);

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
	/* After PHYs are stable we can take Core out of reset state */
	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
	reg &= ~DWC3_GCTL_CORESOFTRESET;
	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
}

/**
 * dwc3_free_one_event_buffer - Frees one event buffer
 * @dwc: Pointer to our controller context structure
 * @evt: Pointer to event buffer to be freed
 */
static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
		struct dwc3_event_buffer *evt)
{
	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
}

/**
117
 * dwc3_alloc_one_event_buffer - Allocates one event buffer structure
118 119 120
 * @dwc: Pointer to our controller context structure
 * @length: size of the event buffer
 *
121
 * Returns a pointer to the allocated event buffer structure on success
122 123
 * otherwise ERR_PTR(errno).
 */
124 125
static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
		unsigned length)
126 127 128
{
	struct dwc3_event_buffer	*evt;

129
	evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
130 131 132 133 134 135 136
	if (!evt)
		return ERR_PTR(-ENOMEM);

	evt->dwc	= dwc;
	evt->length	= length;
	evt->buf	= dma_alloc_coherent(dwc->dev, length,
			&evt->dma, GFP_KERNEL);
137
	if (!evt->buf)
138 139 140 141 142 143 144 145 146 147 148 149 150 151
		return ERR_PTR(-ENOMEM);

	return evt;
}

/**
 * dwc3_free_event_buffers - frees all allocated event buffers
 * @dwc: Pointer to our controller context structure
 */
static void dwc3_free_event_buffers(struct dwc3 *dwc)
{
	struct dwc3_event_buffer	*evt;
	int i;

152
	for (i = 0; i < dwc->num_event_buffers; i++) {
153
		evt = dwc->ev_buffs[i];
154
		if (evt)
155 156 157 158 159 160
			dwc3_free_one_event_buffer(dwc, evt);
	}
}

/**
 * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
161
 * @dwc: pointer to our controller context structure
162 163
 * @length: size of event buffer
 *
164
 * Returns 0 on success otherwise negative errno. In the error case, dwc
165 166
 * may contain some buffers allocated but not all which were requested.
 */
B
Bill Pemberton 已提交
167
static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
168
{
169
	int			num;
170 171
	int			i;

172 173 174
	num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
	dwc->num_event_buffers = num;

175 176
	dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
			GFP_KERNEL);
177 178 179 180 181
	if (!dwc->ev_buffs) {
		dev_err(dwc->dev, "can't allocate event buffers array\n");
		return -ENOMEM;
	}

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
	for (i = 0; i < num; i++) {
		struct dwc3_event_buffer	*evt;

		evt = dwc3_alloc_one_event_buffer(dwc, length);
		if (IS_ERR(evt)) {
			dev_err(dwc->dev, "can't allocate event buffer\n");
			return PTR_ERR(evt);
		}
		dwc->ev_buffs[i] = evt;
	}

	return 0;
}

/**
 * dwc3_event_buffers_setup - setup our allocated event buffers
198
 * @dwc: pointer to our controller context structure
199 200 201
 *
 * Returns 0 on success otherwise negative errno.
 */
202
static int dwc3_event_buffers_setup(struct dwc3 *dwc)
203 204 205 206
{
	struct dwc3_event_buffer	*evt;
	int				n;

207
	for (n = 0; n < dwc->num_event_buffers; n++) {
208 209 210 211 212
		evt = dwc->ev_buffs[n];
		dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
				evt->buf, (unsigned long long) evt->dma,
				evt->length);

213 214
		evt->lpos = 0;

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
				lower_32_bits(evt->dma));
		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
				upper_32_bits(evt->dma));
		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
				evt->length & 0xffff);
		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
	}

	return 0;
}

static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
{
	struct dwc3_event_buffer	*evt;
	int				n;

232
	for (n = 0; n < dwc->num_event_buffers; n++) {
233
		evt = dwc->ev_buffs[n];
234 235 236

		evt->lpos = 0;

237 238 239 240 241 242 243
		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0);
		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
	}
}

244 245 246 247 248 249 250 251 252 253 254
static void dwc3_core_num_eps(struct dwc3 *dwc)
{
	struct dwc3_hwparams	*parms = &dwc->hwparams;

	dwc->num_in_eps = DWC3_NUM_IN_EPS(parms);
	dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps;

	dev_vdbg(dwc->dev, "found %d IN and %d OUT endpoints\n",
			dwc->num_in_eps, dwc->num_out_eps);
}

B
Bill Pemberton 已提交
255
static void dwc3_cache_hwparams(struct dwc3 *dwc)
256 257 258 259 260 261 262 263 264 265 266 267 268 269
{
	struct dwc3_hwparams	*parms = &dwc->hwparams;

	parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
	parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
	parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
	parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
	parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
	parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
	parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
	parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
	parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
}

270 271 272 273 274 275
/**
 * dwc3_core_init - Low-level initialization of DWC3 Core
 * @dwc: Pointer to our controller context structure
 *
 * Returns 0 on success otherwise negative errno.
 */
B
Bill Pemberton 已提交
276
static int dwc3_core_init(struct dwc3 *dwc)
277 278 279 280 281
{
	unsigned long		timeout;
	u32			reg;
	int			ret;

282 283 284 285 286 287 288
	reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
	/* This should read as U3 followed by revision number */
	if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
		ret = -ENODEV;
		goto err0;
	}
289
	dwc->revision = reg;
290

291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
	/* issue device SoftReset too */
	timeout = jiffies + msecs_to_jiffies(500);
	dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
	do {
		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
		if (!(reg & DWC3_DCTL_CSFTRST))
			break;

		if (time_after(jiffies, timeout)) {
			dev_err(dwc->dev, "Reset Timed Out\n");
			ret = -ETIMEDOUT;
			goto err0;
		}

		cpu_relax();
	} while (true);

308 309
	dwc3_core_soft_reset(dwc);

310
	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
311
	reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
312 313
	reg &= ~DWC3_GCTL_DISSCRAMBLE;

314
	switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) {
315 316 317 318 319 320 321 322 323
	case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
		reg &= ~DWC3_GCTL_DSBLCLKGTNG;
		break;
	default:
		dev_dbg(dwc->dev, "No power optimization available\n");
	}

	/*
	 * WORKAROUND: DWC3 revisions <1.90a have a bug
324
	 * where the device can fail to connect at SuperSpeed
325
	 * and falls back to high-speed mode which causes
326
	 * the device to enter a Connect/Disconnect loop
327 328 329 330
	 */
	if (dwc->revision < DWC3_REVISION_190A)
		reg |= DWC3_GCTL_U2RSTECN;

331 332
	dwc3_core_num_eps(dwc);

333 334
	dwc3_writel(dwc->regs, DWC3_GCTL, reg);

335 336 337 338 339 340 341 342
	return 0;

err0:
	return ret;
}

static void dwc3_core_exit(struct dwc3 *dwc)
{
343 344
	usb_phy_shutdown(dwc->usb2_phy);
	usb_phy_shutdown(dwc->usb3_phy);
345 346 347 348
}

#define DWC3_ALIGN_MASK		(16 - 1)

B
Bill Pemberton 已提交
349
static int dwc3_probe(struct platform_device *pdev)
350
{
351
	struct dwc3_platform_data *pdata = pdev->dev.platform_data;
352
	struct device_node	*node = pdev->dev.of_node;
353 354
	struct resource		*res;
	struct dwc3		*dwc;
C
Chanho Park 已提交
355
	struct device		*dev = &pdev->dev;
356

357
	int			ret = -ENOMEM;
358 359

	void __iomem		*regs;
360 361
	void			*mem;

362 363
	u8			mode;

C
Chanho Park 已提交
364
	mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
365
	if (!mem) {
C
Chanho Park 已提交
366 367
		dev_err(dev, "not enough memory\n");
		return -ENOMEM;
368 369 370 371
	}
	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
	dwc->mem = mem;

372
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
373
	if (!res) {
374
		dev_err(dev, "missing IRQ\n");
C
Chanho Park 已提交
375
		return -ENODEV;
376
	}
377 378 379 380
	dwc->xhci_resources[1].start = res->start;
	dwc->xhci_resources[1].end = res->end;
	dwc->xhci_resources[1].flags = res->flags;
	dwc->xhci_resources[1].name = res->name;
381

382 383 384 385 386
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "missing memory resource\n");
		return -ENODEV;
	}
387
	dwc->xhci_resources[0].start = res->start;
388 389
	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
					DWC3_XHCI_REGS_END;
390 391
	dwc->xhci_resources[0].flags = res->flags;
	dwc->xhci_resources[0].name = res->name;
392 393 394 395 396 397 398

	 /*
	  * Request memory region but exclude xHCI regs,
	  * since it will be requested by the xhci-plat driver.
	  */
	res = devm_request_mem_region(dev, res->start + DWC3_GLOBALS_REGS_START,
			resource_size(res) - DWC3_GLOBALS_REGS_START,
C
Chanho Park 已提交
399
			dev_name(dev));
400
	if (!res) {
C
Chanho Park 已提交
401 402
		dev_err(dev, "can't request mem region\n");
		return -ENOMEM;
403 404
	}

405
	regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
406
	if (!regs) {
C
Chanho Park 已提交
407 408
		dev_err(dev, "ioremap failed\n");
		return -ENOMEM;
409 410
	}

411
	if (node) {
412 413
		dwc->maximum_speed = of_usb_get_maximum_speed(node);

414 415
		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
416 417

		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
418
	} else {
419 420
		dwc->maximum_speed = pdata->maximum_speed;

421 422
		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
423 424

		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
425 426
	}

427 428 429 430
	/* default to superspeed if no maximum_speed passed */
	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
		dwc->maximum_speed = USB_SPEED_SUPER;

F
Felipe Balbi 已提交
431 432 433 434 435 436 437 438 439 440 441
	if (IS_ERR(dwc->usb2_phy)) {
		ret = PTR_ERR(dwc->usb2_phy);

		/*
		 * if -ENXIO is returned, it means PHY layer wasn't
		 * enabled, so it makes no sense to return -EPROBE_DEFER
		 * in that case, since no PHY driver will ever probe.
		 */
		if (ret == -ENXIO)
			return ret;

F
Felipe Balbi 已提交
442 443 444 445
		dev_err(dev, "no usb2 phy configured\n");
		return -EPROBE_DEFER;
	}

F
Felipe Balbi 已提交
446
	if (IS_ERR(dwc->usb3_phy)) {
447
		ret = PTR_ERR(dwc->usb3_phy);
F
Felipe Balbi 已提交
448 449 450 451 452 453 454 455 456

		/*
		 * if -ENXIO is returned, it means PHY layer wasn't
		 * enabled, so it makes no sense to return -EPROBE_DEFER
		 * in that case, since no PHY driver will ever probe.
		 */
		if (ret == -ENXIO)
			return ret;

F
Felipe Balbi 已提交
457 458 459 460
		dev_err(dev, "no usb3 phy configured\n");
		return -EPROBE_DEFER;
	}

461 462 463
	usb_phy_set_suspend(dwc->usb2_phy, 0);
	usb_phy_set_suspend(dwc->usb3_phy, 0);

464 465 466 467 468
	spin_lock_init(&dwc->lock);
	platform_set_drvdata(pdev, dwc);

	dwc->regs	= regs;
	dwc->regs_size	= resource_size(res);
C
Chanho Park 已提交
469
	dwc->dev	= dev;
470

471 472 473 474
	dev->dma_mask	= dev->parent->dma_mask;
	dev->dma_parms	= dev->parent->dma_parms;
	dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);

C
Chanho Park 已提交
475 476 477
	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);
	pm_runtime_forbid(dev);
478

479 480
	dwc3_cache_hwparams(dwc);

481 482 483 484 485 486 487
	ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
	if (ret) {
		dev_err(dwc->dev, "failed to allocate event buffers\n");
		ret = -ENOMEM;
		goto err0;
	}

488 489
	ret = dwc3_core_init(dwc);
	if (ret) {
C
Chanho Park 已提交
490
		dev_err(dev, "failed to initialize core\n");
491
		goto err0;
492 493
	}

494 495 496 497 498 499
	ret = dwc3_event_buffers_setup(dwc);
	if (ret) {
		dev_err(dwc->dev, "failed to setup event buffers\n");
		goto err1;
	}

500 501 502 503 504 505
	if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
		mode = DWC3_MODE_HOST;
	else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
		mode = DWC3_MODE_DEVICE;
	else
		mode = DWC3_MODE_DRD;
506 507 508

	switch (mode) {
	case DWC3_MODE_DEVICE:
509
		dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
510 511
		ret = dwc3_gadget_init(dwc);
		if (ret) {
C
Chanho Park 已提交
512
			dev_err(dev, "failed to initialize gadget\n");
513
			goto err2;
514
		}
F
Felipe Balbi 已提交
515 516
		break;
	case DWC3_MODE_HOST:
517
		dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
F
Felipe Balbi 已提交
518 519
		ret = dwc3_host_init(dwc);
		if (ret) {
C
Chanho Park 已提交
520
			dev_err(dev, "failed to initialize host\n");
521
			goto err2;
F
Felipe Balbi 已提交
522 523 524
		}
		break;
	case DWC3_MODE_DRD:
525
		dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
F
Felipe Balbi 已提交
526 527
		ret = dwc3_host_init(dwc);
		if (ret) {
C
Chanho Park 已提交
528
			dev_err(dev, "failed to initialize host\n");
529
			goto err2;
F
Felipe Balbi 已提交
530 531
		}

532 533
		ret = dwc3_gadget_init(dwc);
		if (ret) {
C
Chanho Park 已提交
534
			dev_err(dev, "failed to initialize gadget\n");
535
			goto err2;
536
		}
537 538
		break;
	default:
C
Chanho Park 已提交
539
		dev_err(dev, "Unsupported mode of operation %d\n", mode);
540
		goto err2;
541
	}
542
	dwc->mode = mode;
543 544 545

	ret = dwc3_debugfs_init(dwc);
	if (ret) {
C
Chanho Park 已提交
546
		dev_err(dev, "failed to initialize debugfs\n");
547
		goto err3;
548 549
	}

C
Chanho Park 已提交
550
	pm_runtime_allow(dev);
551 552 553

	return 0;

554
err3:
555 556
	switch (mode) {
	case DWC3_MODE_DEVICE:
557
		dwc3_gadget_exit(dwc);
558
		break;
F
Felipe Balbi 已提交
559 560 561 562 563
	case DWC3_MODE_HOST:
		dwc3_host_exit(dwc);
		break;
	case DWC3_MODE_DRD:
		dwc3_host_exit(dwc);
564
		dwc3_gadget_exit(dwc);
F
Felipe Balbi 已提交
565
		break;
566 567 568 569
	default:
		/* do nothing */
		break;
	}
570

571 572 573
err2:
	dwc3_event_buffers_cleanup(dwc);

574
err1:
C
Chanho Park 已提交
575
	dwc3_core_exit(dwc);
576

577 578 579
err0:
	dwc3_free_event_buffers(dwc);

580 581 582
	return ret;
}

B
Bill Pemberton 已提交
583
static int dwc3_remove(struct platform_device *pdev)
584 585 586
{
	struct dwc3	*dwc = platform_get_drvdata(pdev);

587 588 589
	usb_phy_set_suspend(dwc->usb2_phy, 1);
	usb_phy_set_suspend(dwc->usb3_phy, 1);

590 591 592 593 594
	pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	dwc3_debugfs_exit(dwc);

595 596
	switch (dwc->mode) {
	case DWC3_MODE_DEVICE:
597
		dwc3_gadget_exit(dwc);
598
		break;
F
Felipe Balbi 已提交
599 600 601 602 603
	case DWC3_MODE_HOST:
		dwc3_host_exit(dwc);
		break;
	case DWC3_MODE_DRD:
		dwc3_host_exit(dwc);
604
		dwc3_gadget_exit(dwc);
F
Felipe Balbi 已提交
605
		break;
606 607 608 609
	default:
		/* do nothing */
		break;
	}
610

611
	dwc3_event_buffers_cleanup(dwc);
612
	dwc3_free_event_buffers(dwc);
613 614 615 616 617
	dwc3_core_exit(dwc);

	return 0;
}

618
#ifdef CONFIG_PM_SLEEP
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
static int dwc3_prepare(struct device *dev)
{
	struct dwc3	*dwc = dev_get_drvdata(dev);
	unsigned long	flags;

	spin_lock_irqsave(&dwc->lock, flags);

	switch (dwc->mode) {
	case DWC3_MODE_DEVICE:
	case DWC3_MODE_DRD:
		dwc3_gadget_prepare(dwc);
		/* FALLTHROUGH */
	case DWC3_MODE_HOST:
	default:
		dwc3_event_buffers_cleanup(dwc);
		break;
	}

	spin_unlock_irqrestore(&dwc->lock, flags);

	return 0;
}

static void dwc3_complete(struct device *dev)
{
	struct dwc3	*dwc = dev_get_drvdata(dev);
	unsigned long	flags;

	spin_lock_irqsave(&dwc->lock, flags);

	switch (dwc->mode) {
	case DWC3_MODE_DEVICE:
	case DWC3_MODE_DRD:
		dwc3_gadget_complete(dwc);
		/* FALLTHROUGH */
	case DWC3_MODE_HOST:
	default:
		dwc3_event_buffers_setup(dwc);
		break;
	}

	spin_unlock_irqrestore(&dwc->lock, flags);
}

static int dwc3_suspend(struct device *dev)
{
	struct dwc3	*dwc = dev_get_drvdata(dev);
	unsigned long	flags;

	spin_lock_irqsave(&dwc->lock, flags);

	switch (dwc->mode) {
	case DWC3_MODE_DEVICE:
	case DWC3_MODE_DRD:
		dwc3_gadget_suspend(dwc);
		/* FALLTHROUGH */
	case DWC3_MODE_HOST:
	default:
		/* do nothing */
		break;
	}

	dwc->gctl = dwc3_readl(dwc->regs, DWC3_GCTL);
	spin_unlock_irqrestore(&dwc->lock, flags);

	usb_phy_shutdown(dwc->usb3_phy);
	usb_phy_shutdown(dwc->usb2_phy);

	return 0;
}

static int dwc3_resume(struct device *dev)
{
	struct dwc3	*dwc = dev_get_drvdata(dev);
	unsigned long	flags;

	usb_phy_init(dwc->usb3_phy);
	usb_phy_init(dwc->usb2_phy);
	msleep(100);

	spin_lock_irqsave(&dwc->lock, flags);

	dwc3_writel(dwc->regs, DWC3_GCTL, dwc->gctl);

	switch (dwc->mode) {
	case DWC3_MODE_DEVICE:
	case DWC3_MODE_DRD:
		dwc3_gadget_resume(dwc);
		/* FALLTHROUGH */
	case DWC3_MODE_HOST:
	default:
		/* do nothing */
		break;
	}

	spin_unlock_irqrestore(&dwc->lock, flags);

	pm_runtime_disable(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	return 0;
}

static const struct dev_pm_ops dwc3_dev_pm_ops = {
	.prepare	= dwc3_prepare,
	.complete	= dwc3_complete,

	SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
};

#define DWC3_PM_OPS	&(dwc3_dev_pm_ops)
#else
#define DWC3_PM_OPS	NULL
#endif

735 736
#ifdef CONFIG_OF
static const struct of_device_id of_dwc3_match[] = {
737 738 739
	{
		.compatible = "snps,dwc3"
	},
740 741 742 743 744 745 746 747
	{
		.compatible = "synopsys,dwc3"
	},
	{ },
};
MODULE_DEVICE_TABLE(of, of_dwc3_match);
#endif

748 749
static struct platform_driver dwc3_driver = {
	.probe		= dwc3_probe,
B
Bill Pemberton 已提交
750
	.remove		= dwc3_remove,
751 752
	.driver		= {
		.name	= "dwc3",
753
		.of_match_table	= of_match_ptr(of_dwc3_match),
754
		.pm	= DWC3_PM_OPS,
755 756 757
	},
};

758 759
module_platform_driver(dwc3_driver);

760
MODULE_ALIAS("platform:dwc3");
761
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
F
Felipe Balbi 已提交
762
MODULE_LICENSE("GPL v2");
763
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");