xref: /openbmc/linux/drivers/usb/dwc3/dwc3-omap.c (revision 5d0e4d78)
1 /**
2  * dwc3-omap.c - OMAP Specific Glue layer
3  *
4  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
5  *
6  * Authors: Felipe Balbi <balbi@ti.com>,
7  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2  of
11  * the License as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18 
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/irq.h>
23 #include <linux/interrupt.h>
24 #include <linux/platform_device.h>
25 #include <linux/platform_data/dwc3-omap.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/ioport.h>
29 #include <linux/io.h>
30 #include <linux/of.h>
31 #include <linux/of_platform.h>
32 #include <linux/extcon.h>
33 #include <linux/regulator/consumer.h>
34 
35 #include <linux/usb/otg.h>
36 
37 /*
38  * All these registers belong to OMAP's Wrapper around the
39  * DesignWare USB3 Core.
40  */
41 
42 #define USBOTGSS_REVISION			0x0000
43 #define USBOTGSS_SYSCONFIG			0x0010
44 #define USBOTGSS_IRQ_EOI			0x0020
45 #define USBOTGSS_EOI_OFFSET			0x0008
46 #define USBOTGSS_IRQSTATUS_RAW_0		0x0024
47 #define USBOTGSS_IRQSTATUS_0			0x0028
48 #define USBOTGSS_IRQENABLE_SET_0		0x002c
49 #define USBOTGSS_IRQENABLE_CLR_0		0x0030
50 #define USBOTGSS_IRQ0_OFFSET			0x0004
51 #define USBOTGSS_IRQSTATUS_RAW_1		0x0030
52 #define USBOTGSS_IRQSTATUS_1			0x0034
53 #define USBOTGSS_IRQENABLE_SET_1		0x0038
54 #define USBOTGSS_IRQENABLE_CLR_1		0x003c
55 #define USBOTGSS_IRQSTATUS_RAW_2		0x0040
56 #define USBOTGSS_IRQSTATUS_2			0x0044
57 #define USBOTGSS_IRQENABLE_SET_2		0x0048
58 #define USBOTGSS_IRQENABLE_CLR_2		0x004c
59 #define USBOTGSS_IRQSTATUS_RAW_3		0x0050
60 #define USBOTGSS_IRQSTATUS_3			0x0054
61 #define USBOTGSS_IRQENABLE_SET_3		0x0058
62 #define USBOTGSS_IRQENABLE_CLR_3		0x005c
63 #define USBOTGSS_IRQSTATUS_EOI_MISC		0x0030
64 #define USBOTGSS_IRQSTATUS_RAW_MISC		0x0034
65 #define USBOTGSS_IRQSTATUS_MISC			0x0038
66 #define USBOTGSS_IRQENABLE_SET_MISC		0x003c
67 #define USBOTGSS_IRQENABLE_CLR_MISC		0x0040
68 #define USBOTGSS_IRQMISC_OFFSET			0x03fc
69 #define USBOTGSS_UTMI_OTG_STATUS		0x0080
70 #define USBOTGSS_UTMI_OTG_CTRL			0x0084
71 #define USBOTGSS_UTMI_OTG_OFFSET		0x0480
72 #define USBOTGSS_TXFIFO_DEPTH			0x0508
73 #define USBOTGSS_RXFIFO_DEPTH			0x050c
74 #define USBOTGSS_MMRAM_OFFSET			0x0100
75 #define USBOTGSS_FLADJ				0x0104
76 #define USBOTGSS_DEBUG_CFG			0x0108
77 #define USBOTGSS_DEBUG_DATA			0x010c
78 #define USBOTGSS_DEV_EBC_EN			0x0110
79 #define USBOTGSS_DEBUG_OFFSET			0x0600
80 
81 /* SYSCONFIG REGISTER */
82 #define USBOTGSS_SYSCONFIG_DMADISABLE		BIT(16)
83 
84 /* IRQ_EOI REGISTER */
85 #define USBOTGSS_IRQ_EOI_LINE_NUMBER		BIT(0)
86 
87 /* IRQS0 BITS */
88 #define USBOTGSS_IRQO_COREIRQ_ST		BIT(0)
89 
90 /* IRQMISC BITS */
91 #define USBOTGSS_IRQMISC_DMADISABLECLR		BIT(17)
92 #define USBOTGSS_IRQMISC_OEVT			BIT(16)
93 #define USBOTGSS_IRQMISC_DRVVBUS_RISE		BIT(13)
94 #define USBOTGSS_IRQMISC_CHRGVBUS_RISE		BIT(12)
95 #define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE	BIT(11)
96 #define USBOTGSS_IRQMISC_IDPULLUP_RISE		BIT(8)
97 #define USBOTGSS_IRQMISC_DRVVBUS_FALL		BIT(5)
98 #define USBOTGSS_IRQMISC_CHRGVBUS_FALL		BIT(4)
99 #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL		BIT(3)
100 #define USBOTGSS_IRQMISC_IDPULLUP_FALL		BIT(0)
101 
102 /* UTMI_OTG_STATUS REGISTER */
103 #define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS	BIT(5)
104 #define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS	BIT(4)
105 #define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS	BIT(3)
106 #define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP	BIT(0)
107 
108 /* UTMI_OTG_CTRL REGISTER */
109 #define USBOTGSS_UTMI_OTG_CTRL_SW_MODE		BIT(31)
110 #define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT	BIT(9)
111 #define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE BIT(8)
112 #define USBOTGSS_UTMI_OTG_CTRL_IDDIG		BIT(4)
113 #define USBOTGSS_UTMI_OTG_CTRL_SESSEND		BIT(3)
114 #define USBOTGSS_UTMI_OTG_CTRL_SESSVALID	BIT(2)
115 #define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID	BIT(1)
116 
117 struct dwc3_omap {
118 	struct device		*dev;
119 
120 	int			irq;
121 	void __iomem		*base;
122 
123 	u32			utmi_otg_ctrl;
124 	u32			utmi_otg_offset;
125 	u32			irqmisc_offset;
126 	u32			irq_eoi_offset;
127 	u32			debug_offset;
128 	u32			irq0_offset;
129 
130 	struct extcon_dev	*edev;
131 	struct notifier_block	vbus_nb;
132 	struct notifier_block	id_nb;
133 
134 	struct regulator	*vbus_reg;
135 };
136 
137 enum omap_dwc3_vbus_id_status {
138 	OMAP_DWC3_ID_FLOAT,
139 	OMAP_DWC3_ID_GROUND,
140 	OMAP_DWC3_VBUS_OFF,
141 	OMAP_DWC3_VBUS_VALID,
142 };
143 
144 static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
145 {
146 	return readl(base + offset);
147 }
148 
149 static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
150 {
151 	writel(value, base + offset);
152 }
153 
154 static u32 dwc3_omap_read_utmi_ctrl(struct dwc3_omap *omap)
155 {
156 	return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL +
157 							omap->utmi_otg_offset);
158 }
159 
160 static void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value)
161 {
162 	dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL +
163 					omap->utmi_otg_offset, value);
164 
165 }
166 
167 static u32 dwc3_omap_read_irq0_status(struct dwc3_omap *omap)
168 {
169 	return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_0 -
170 						omap->irq0_offset);
171 }
172 
173 static void dwc3_omap_write_irq0_status(struct dwc3_omap *omap, u32 value)
174 {
175 	dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0 -
176 						omap->irq0_offset, value);
177 
178 }
179 
180 static u32 dwc3_omap_read_irqmisc_status(struct dwc3_omap *omap)
181 {
182 	return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_MISC +
183 						omap->irqmisc_offset);
184 }
185 
186 static void dwc3_omap_write_irqmisc_status(struct dwc3_omap *omap, u32 value)
187 {
188 	dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_MISC +
189 					omap->irqmisc_offset, value);
190 
191 }
192 
193 static void dwc3_omap_write_irqmisc_set(struct dwc3_omap *omap, u32 value)
194 {
195 	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_MISC +
196 						omap->irqmisc_offset, value);
197 
198 }
199 
200 static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)
201 {
202 	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0 -
203 						omap->irq0_offset, value);
204 }
205 
206 static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
207 {
208 	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC +
209 						omap->irqmisc_offset, value);
210 }
211 
212 static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
213 {
214 	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 -
215 						omap->irq0_offset, value);
216 }
217 
218 static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
219 	enum omap_dwc3_vbus_id_status status)
220 {
221 	int	ret;
222 	u32	val;
223 
224 	switch (status) {
225 	case OMAP_DWC3_ID_GROUND:
226 		if (omap->vbus_reg) {
227 			ret = regulator_enable(omap->vbus_reg);
228 			if (ret) {
229 				dev_err(omap->dev, "regulator enable failed\n");
230 				return;
231 			}
232 		}
233 
234 		val = dwc3_omap_read_utmi_ctrl(omap);
235 		val &= ~USBOTGSS_UTMI_OTG_CTRL_IDDIG;
236 		dwc3_omap_write_utmi_ctrl(omap, val);
237 		break;
238 
239 	case OMAP_DWC3_VBUS_VALID:
240 		val = dwc3_omap_read_utmi_ctrl(omap);
241 		val &= ~USBOTGSS_UTMI_OTG_CTRL_SESSEND;
242 		val |= USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
243 				| USBOTGSS_UTMI_OTG_CTRL_SESSVALID;
244 		dwc3_omap_write_utmi_ctrl(omap, val);
245 		break;
246 
247 	case OMAP_DWC3_ID_FLOAT:
248 		if (omap->vbus_reg)
249 			regulator_disable(omap->vbus_reg);
250 		val = dwc3_omap_read_utmi_ctrl(omap);
251 		val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
252 		dwc3_omap_write_utmi_ctrl(omap, val);
253 		break;
254 
255 	case OMAP_DWC3_VBUS_OFF:
256 		val = dwc3_omap_read_utmi_ctrl(omap);
257 		val &= ~(USBOTGSS_UTMI_OTG_CTRL_SESSVALID
258 				| USBOTGSS_UTMI_OTG_CTRL_VBUSVALID);
259 		val |= USBOTGSS_UTMI_OTG_CTRL_SESSEND;
260 		dwc3_omap_write_utmi_ctrl(omap, val);
261 		break;
262 
263 	default:
264 		dev_WARN(omap->dev, "invalid state\n");
265 	}
266 }
267 
268 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap);
269 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap);
270 
271 static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
272 {
273 	struct dwc3_omap	*omap = _omap;
274 
275 	if (dwc3_omap_read_irqmisc_status(omap) ||
276 	    dwc3_omap_read_irq0_status(omap)) {
277 		/* mask irqs */
278 		dwc3_omap_disable_irqs(omap);
279 		return IRQ_WAKE_THREAD;
280 	}
281 
282 	return IRQ_NONE;
283 }
284 
285 static irqreturn_t dwc3_omap_interrupt_thread(int irq, void *_omap)
286 {
287 	struct dwc3_omap	*omap = _omap;
288 	u32			reg;
289 
290 	/* clear irq status flags */
291 	reg = dwc3_omap_read_irqmisc_status(omap);
292 	dwc3_omap_write_irqmisc_status(omap, reg);
293 
294 	reg = dwc3_omap_read_irq0_status(omap);
295 	dwc3_omap_write_irq0_status(omap, reg);
296 
297 	/* unmask irqs */
298 	dwc3_omap_enable_irqs(omap);
299 
300 	return IRQ_HANDLED;
301 }
302 
303 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
304 {
305 	u32			reg;
306 
307 	/* enable all IRQs */
308 	reg = USBOTGSS_IRQO_COREIRQ_ST;
309 	dwc3_omap_write_irq0_set(omap, reg);
310 
311 	reg = (USBOTGSS_IRQMISC_OEVT |
312 			USBOTGSS_IRQMISC_DRVVBUS_RISE |
313 			USBOTGSS_IRQMISC_CHRGVBUS_RISE |
314 			USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
315 			USBOTGSS_IRQMISC_IDPULLUP_RISE |
316 			USBOTGSS_IRQMISC_DRVVBUS_FALL |
317 			USBOTGSS_IRQMISC_CHRGVBUS_FALL |
318 			USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
319 			USBOTGSS_IRQMISC_IDPULLUP_FALL);
320 
321 	dwc3_omap_write_irqmisc_set(omap, reg);
322 }
323 
324 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
325 {
326 	u32			reg;
327 
328 	/* disable all IRQs */
329 	reg = USBOTGSS_IRQO_COREIRQ_ST;
330 	dwc3_omap_write_irq0_clr(omap, reg);
331 
332 	reg = (USBOTGSS_IRQMISC_OEVT |
333 			USBOTGSS_IRQMISC_DRVVBUS_RISE |
334 			USBOTGSS_IRQMISC_CHRGVBUS_RISE |
335 			USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
336 			USBOTGSS_IRQMISC_IDPULLUP_RISE |
337 			USBOTGSS_IRQMISC_DRVVBUS_FALL |
338 			USBOTGSS_IRQMISC_CHRGVBUS_FALL |
339 			USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
340 			USBOTGSS_IRQMISC_IDPULLUP_FALL);
341 
342 	dwc3_omap_write_irqmisc_clr(omap, reg);
343 }
344 
345 static int dwc3_omap_id_notifier(struct notifier_block *nb,
346 	unsigned long event, void *ptr)
347 {
348 	struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, id_nb);
349 
350 	if (event)
351 		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
352 	else
353 		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
354 
355 	return NOTIFY_DONE;
356 }
357 
358 static int dwc3_omap_vbus_notifier(struct notifier_block *nb,
359 	unsigned long event, void *ptr)
360 {
361 	struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, vbus_nb);
362 
363 	if (event)
364 		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
365 	else
366 		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
367 
368 	return NOTIFY_DONE;
369 }
370 
371 static void dwc3_omap_map_offset(struct dwc3_omap *omap)
372 {
373 	struct device_node	*node = omap->dev->of_node;
374 
375 	/*
376 	 * Differentiate between OMAP5 and AM437x.
377 	 *
378 	 * For OMAP5(ES2.0) and AM437x wrapper revision is same, even
379 	 * though there are changes in wrapper register offsets.
380 	 *
381 	 * Using dt compatible to differentiate AM437x.
382 	 */
383 	if (of_device_is_compatible(node, "ti,am437x-dwc3")) {
384 		omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET;
385 		omap->irq0_offset = USBOTGSS_IRQ0_OFFSET;
386 		omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
387 		omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
388 		omap->debug_offset = USBOTGSS_DEBUG_OFFSET;
389 	}
390 }
391 
392 static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
393 {
394 	u32			reg;
395 	struct device_node	*node = omap->dev->of_node;
396 	u32			utmi_mode = 0;
397 
398 	reg = dwc3_omap_read_utmi_ctrl(omap);
399 
400 	of_property_read_u32(node, "utmi-mode", &utmi_mode);
401 
402 	switch (utmi_mode) {
403 	case DWC3_OMAP_UTMI_MODE_SW:
404 		reg |= USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
405 		break;
406 	case DWC3_OMAP_UTMI_MODE_HW:
407 		reg &= ~USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
408 		break;
409 	default:
410 		dev_WARN(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode);
411 	}
412 
413 	dwc3_omap_write_utmi_ctrl(omap, reg);
414 }
415 
416 static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
417 {
418 	int			ret;
419 	struct device_node	*node = omap->dev->of_node;
420 	struct extcon_dev	*edev;
421 
422 	if (of_property_read_bool(node, "extcon")) {
423 		edev = extcon_get_edev_by_phandle(omap->dev, 0);
424 		if (IS_ERR(edev)) {
425 			dev_vdbg(omap->dev, "couldn't get extcon device\n");
426 			return -EPROBE_DEFER;
427 		}
428 
429 		omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
430 		ret = devm_extcon_register_notifier(omap->dev, edev,
431 						EXTCON_USB, &omap->vbus_nb);
432 		if (ret < 0)
433 			dev_vdbg(omap->dev, "failed to register notifier for USB\n");
434 
435 		omap->id_nb.notifier_call = dwc3_omap_id_notifier;
436 		ret = devm_extcon_register_notifier(omap->dev, edev,
437 						EXTCON_USB_HOST, &omap->id_nb);
438 		if (ret < 0)
439 			dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n");
440 
441 		if (extcon_get_state(edev, EXTCON_USB) == true)
442 			dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
443 		if (extcon_get_state(edev, EXTCON_USB_HOST) == true)
444 			dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
445 
446 		omap->edev = edev;
447 	}
448 
449 	return 0;
450 }
451 
452 static int dwc3_omap_probe(struct platform_device *pdev)
453 {
454 	struct device_node	*node = pdev->dev.of_node;
455 
456 	struct dwc3_omap	*omap;
457 	struct resource		*res;
458 	struct device		*dev = &pdev->dev;
459 	struct regulator	*vbus_reg = NULL;
460 
461 	int			ret;
462 	int			irq;
463 
464 	u32			reg;
465 
466 	void __iomem		*base;
467 
468 	if (!node) {
469 		dev_err(dev, "device node not found\n");
470 		return -EINVAL;
471 	}
472 
473 	omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
474 	if (!omap)
475 		return -ENOMEM;
476 
477 	platform_set_drvdata(pdev, omap);
478 
479 	irq = platform_get_irq(pdev, 0);
480 	if (irq < 0) {
481 		dev_err(dev, "missing IRQ resource\n");
482 		return -EINVAL;
483 	}
484 
485 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
486 	base = devm_ioremap_resource(dev, res);
487 	if (IS_ERR(base))
488 		return PTR_ERR(base);
489 
490 	if (of_property_read_bool(node, "vbus-supply")) {
491 		vbus_reg = devm_regulator_get(dev, "vbus");
492 		if (IS_ERR(vbus_reg)) {
493 			dev_err(dev, "vbus init failed\n");
494 			return PTR_ERR(vbus_reg);
495 		}
496 	}
497 
498 	omap->dev	= dev;
499 	omap->irq	= irq;
500 	omap->base	= base;
501 	omap->vbus_reg	= vbus_reg;
502 
503 	pm_runtime_enable(dev);
504 	ret = pm_runtime_get_sync(dev);
505 	if (ret < 0) {
506 		dev_err(dev, "get_sync failed with err %d\n", ret);
507 		goto err1;
508 	}
509 
510 	dwc3_omap_map_offset(omap);
511 	dwc3_omap_set_utmi_mode(omap);
512 
513 	/* check the DMA Status */
514 	reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
515 
516 	ret = dwc3_omap_extcon_register(omap);
517 	if (ret < 0)
518 		goto err1;
519 
520 	ret = of_platform_populate(node, NULL, NULL, dev);
521 	if (ret) {
522 		dev_err(&pdev->dev, "failed to create dwc3 core\n");
523 		goto err1;
524 	}
525 
526 	ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
527 					dwc3_omap_interrupt_thread, IRQF_SHARED,
528 					"dwc3-omap", omap);
529 	if (ret) {
530 		dev_err(dev, "failed to request IRQ #%d --> %d\n",
531 			omap->irq, ret);
532 		goto err1;
533 	}
534 	dwc3_omap_enable_irqs(omap);
535 	return 0;
536 
537 err1:
538 	pm_runtime_put_sync(dev);
539 	pm_runtime_disable(dev);
540 
541 	return ret;
542 }
543 
544 static int dwc3_omap_remove(struct platform_device *pdev)
545 {
546 	struct dwc3_omap	*omap = platform_get_drvdata(pdev);
547 
548 	dwc3_omap_disable_irqs(omap);
549 	disable_irq(omap->irq);
550 	of_platform_depopulate(omap->dev);
551 	pm_runtime_put_sync(&pdev->dev);
552 	pm_runtime_disable(&pdev->dev);
553 
554 	return 0;
555 }
556 
557 static const struct of_device_id of_dwc3_match[] = {
558 	{
559 		.compatible =	"ti,dwc3"
560 	},
561 	{
562 		.compatible =	"ti,am437x-dwc3"
563 	},
564 	{ },
565 };
566 MODULE_DEVICE_TABLE(of, of_dwc3_match);
567 
568 #ifdef CONFIG_PM_SLEEP
569 static int dwc3_omap_suspend(struct device *dev)
570 {
571 	struct dwc3_omap	*omap = dev_get_drvdata(dev);
572 
573 	omap->utmi_otg_ctrl = dwc3_omap_read_utmi_ctrl(omap);
574 	dwc3_omap_disable_irqs(omap);
575 
576 	return 0;
577 }
578 
579 static int dwc3_omap_resume(struct device *dev)
580 {
581 	struct dwc3_omap	*omap = dev_get_drvdata(dev);
582 
583 	dwc3_omap_write_utmi_ctrl(omap, omap->utmi_otg_ctrl);
584 	dwc3_omap_enable_irqs(omap);
585 
586 	pm_runtime_disable(dev);
587 	pm_runtime_set_active(dev);
588 	pm_runtime_enable(dev);
589 
590 	return 0;
591 }
592 
593 static const struct dev_pm_ops dwc3_omap_dev_pm_ops = {
594 
595 	SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
596 };
597 
598 #define DEV_PM_OPS	(&dwc3_omap_dev_pm_ops)
599 #else
600 #define DEV_PM_OPS	NULL
601 #endif /* CONFIG_PM_SLEEP */
602 
603 static struct platform_driver dwc3_omap_driver = {
604 	.probe		= dwc3_omap_probe,
605 	.remove		= dwc3_omap_remove,
606 	.driver		= {
607 		.name	= "omap-dwc3",
608 		.of_match_table	= of_dwc3_match,
609 		.pm	= DEV_PM_OPS,
610 	},
611 };
612 
613 module_platform_driver(dwc3_omap_driver);
614 
615 MODULE_ALIAS("platform:omap-dwc3");
616 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
617 MODULE_LICENSE("GPL v2");
618 MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");
619