18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * dwc3-omap.c - OMAP Specific Glue layer
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Authors: Felipe Balbi <balbi@ti.com>,
88c2ecf20Sopenharmony_ci *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/module.h>
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/slab.h>
148c2ecf20Sopenharmony_ci#include <linux/irq.h>
158c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
168c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
178c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
188c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
198c2ecf20Sopenharmony_ci#include <linux/ioport.h>
208c2ecf20Sopenharmony_ci#include <linux/io.h>
218c2ecf20Sopenharmony_ci#include <linux/of.h>
228c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
238c2ecf20Sopenharmony_ci#include <linux/extcon.h>
248c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#include <linux/usb/otg.h>
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/*
298c2ecf20Sopenharmony_ci * All these registers belong to OMAP's Wrapper around the
308c2ecf20Sopenharmony_ci * DesignWare USB3 Core.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#define USBOTGSS_REVISION			0x0000
348c2ecf20Sopenharmony_ci#define USBOTGSS_SYSCONFIG			0x0010
358c2ecf20Sopenharmony_ci#define USBOTGSS_IRQ_EOI			0x0020
368c2ecf20Sopenharmony_ci#define USBOTGSS_EOI_OFFSET			0x0008
378c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_RAW_0		0x0024
388c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_0			0x0028
398c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_SET_0		0x002c
408c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_CLR_0		0x0030
418c2ecf20Sopenharmony_ci#define USBOTGSS_IRQ0_OFFSET			0x0004
428c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_RAW_1		0x0030
438c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_1			0x0034
448c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_SET_1		0x0038
458c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_CLR_1		0x003c
468c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_RAW_2		0x0040
478c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_2			0x0044
488c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_SET_2		0x0048
498c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_CLR_2		0x004c
508c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_RAW_3		0x0050
518c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_3			0x0054
528c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_SET_3		0x0058
538c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_CLR_3		0x005c
548c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_EOI_MISC		0x0030
558c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_RAW_MISC		0x0034
568c2ecf20Sopenharmony_ci#define USBOTGSS_IRQSTATUS_MISC			0x0038
578c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_SET_MISC		0x003c
588c2ecf20Sopenharmony_ci#define USBOTGSS_IRQENABLE_CLR_MISC		0x0040
598c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_OFFSET			0x03fc
608c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_STATUS		0x0080
618c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL			0x0084
628c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_OFFSET		0x0480
638c2ecf20Sopenharmony_ci#define USBOTGSS_TXFIFO_DEPTH			0x0508
648c2ecf20Sopenharmony_ci#define USBOTGSS_RXFIFO_DEPTH			0x050c
658c2ecf20Sopenharmony_ci#define USBOTGSS_MMRAM_OFFSET			0x0100
668c2ecf20Sopenharmony_ci#define USBOTGSS_FLADJ				0x0104
678c2ecf20Sopenharmony_ci#define USBOTGSS_DEBUG_CFG			0x0108
688c2ecf20Sopenharmony_ci#define USBOTGSS_DEBUG_DATA			0x010c
698c2ecf20Sopenharmony_ci#define USBOTGSS_DEV_EBC_EN			0x0110
708c2ecf20Sopenharmony_ci#define USBOTGSS_DEBUG_OFFSET			0x0600
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/* SYSCONFIG REGISTER */
738c2ecf20Sopenharmony_ci#define USBOTGSS_SYSCONFIG_DMADISABLE		BIT(16)
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/* IRQ_EOI REGISTER */
768c2ecf20Sopenharmony_ci#define USBOTGSS_IRQ_EOI_LINE_NUMBER		BIT(0)
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* IRQS0 BITS */
798c2ecf20Sopenharmony_ci#define USBOTGSS_IRQO_COREIRQ_ST		BIT(0)
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/* IRQMISC BITS */
828c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_DMADISABLECLR		BIT(17)
838c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_OEVT			BIT(16)
848c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_DRVVBUS_RISE		BIT(13)
858c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_CHRGVBUS_RISE		BIT(12)
868c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE	BIT(11)
878c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_IDPULLUP_RISE		BIT(8)
888c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_DRVVBUS_FALL		BIT(5)
898c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_CHRGVBUS_FALL		BIT(4)
908c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL		BIT(3)
918c2ecf20Sopenharmony_ci#define USBOTGSS_IRQMISC_IDPULLUP_FALL		BIT(0)
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci/* UTMI_OTG_STATUS REGISTER */
948c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS	BIT(5)
958c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS	BIT(4)
968c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS	BIT(3)
978c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP	BIT(0)
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci/* UTMI_OTG_CTRL REGISTER */
1008c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_SW_MODE		BIT(31)
1018c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT	BIT(9)
1028c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE BIT(8)
1038c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_IDDIG		BIT(4)
1048c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_SESSEND		BIT(3)
1058c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_SESSVALID	BIT(2)
1068c2ecf20Sopenharmony_ci#define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID	BIT(1)
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cienum dwc3_omap_utmi_mode {
1098c2ecf20Sopenharmony_ci	DWC3_OMAP_UTMI_MODE_UNKNOWN = 0,
1108c2ecf20Sopenharmony_ci	DWC3_OMAP_UTMI_MODE_HW,
1118c2ecf20Sopenharmony_ci	DWC3_OMAP_UTMI_MODE_SW,
1128c2ecf20Sopenharmony_ci};
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistruct dwc3_omap {
1158c2ecf20Sopenharmony_ci	struct device		*dev;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	int			irq;
1188c2ecf20Sopenharmony_ci	void __iomem		*base;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	u32			utmi_otg_ctrl;
1218c2ecf20Sopenharmony_ci	u32			utmi_otg_offset;
1228c2ecf20Sopenharmony_ci	u32			irqmisc_offset;
1238c2ecf20Sopenharmony_ci	u32			irq_eoi_offset;
1248c2ecf20Sopenharmony_ci	u32			debug_offset;
1258c2ecf20Sopenharmony_ci	u32			irq0_offset;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	struct extcon_dev	*edev;
1288c2ecf20Sopenharmony_ci	struct notifier_block	vbus_nb;
1298c2ecf20Sopenharmony_ci	struct notifier_block	id_nb;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	struct regulator	*vbus_reg;
1328c2ecf20Sopenharmony_ci};
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cienum omap_dwc3_vbus_id_status {
1358c2ecf20Sopenharmony_ci	OMAP_DWC3_ID_FLOAT,
1368c2ecf20Sopenharmony_ci	OMAP_DWC3_ID_GROUND,
1378c2ecf20Sopenharmony_ci	OMAP_DWC3_VBUS_OFF,
1388c2ecf20Sopenharmony_ci	OMAP_DWC3_VBUS_VALID,
1398c2ecf20Sopenharmony_ci};
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	return readl(base + offset);
1448c2ecf20Sopenharmony_ci}
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cistatic inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	writel(value, base + offset);
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic u32 dwc3_omap_read_utmi_ctrl(struct dwc3_omap *omap)
1528c2ecf20Sopenharmony_ci{
1538c2ecf20Sopenharmony_ci	return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL +
1548c2ecf20Sopenharmony_ci							omap->utmi_otg_offset);
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL +
1608c2ecf20Sopenharmony_ci					omap->utmi_otg_offset, value);
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_cistatic u32 dwc3_omap_read_irq0_status(struct dwc3_omap *omap)
1658c2ecf20Sopenharmony_ci{
1668c2ecf20Sopenharmony_ci	return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_0 -
1678c2ecf20Sopenharmony_ci						omap->irq0_offset);
1688c2ecf20Sopenharmony_ci}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic void dwc3_omap_write_irq0_status(struct dwc3_omap *omap, u32 value)
1718c2ecf20Sopenharmony_ci{
1728c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0 -
1738c2ecf20Sopenharmony_ci						omap->irq0_offset, value);
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_cistatic u32 dwc3_omap_read_irqmisc_status(struct dwc3_omap *omap)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_MISC +
1808c2ecf20Sopenharmony_ci						omap->irqmisc_offset);
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cistatic void dwc3_omap_write_irqmisc_status(struct dwc3_omap *omap, u32 value)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_MISC +
1868c2ecf20Sopenharmony_ci					omap->irqmisc_offset, value);
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic void dwc3_omap_write_irqmisc_set(struct dwc3_omap *omap, u32 value)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_MISC +
1938c2ecf20Sopenharmony_ci						omap->irqmisc_offset, value);
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci}
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_cistatic void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)
1988c2ecf20Sopenharmony_ci{
1998c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0 -
2008c2ecf20Sopenharmony_ci						omap->irq0_offset, value);
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC +
2068c2ecf20Sopenharmony_ci						omap->irqmisc_offset, value);
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
2108c2ecf20Sopenharmony_ci{
2118c2ecf20Sopenharmony_ci	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 -
2128c2ecf20Sopenharmony_ci						omap->irq0_offset, value);
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistatic void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
2168c2ecf20Sopenharmony_ci	enum omap_dwc3_vbus_id_status status)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	int	ret;
2198c2ecf20Sopenharmony_ci	u32	val;
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	switch (status) {
2228c2ecf20Sopenharmony_ci	case OMAP_DWC3_ID_GROUND:
2238c2ecf20Sopenharmony_ci		if (omap->vbus_reg) {
2248c2ecf20Sopenharmony_ci			ret = regulator_enable(omap->vbus_reg);
2258c2ecf20Sopenharmony_ci			if (ret) {
2268c2ecf20Sopenharmony_ci				dev_err(omap->dev, "regulator enable failed\n");
2278c2ecf20Sopenharmony_ci				return;
2288c2ecf20Sopenharmony_ci			}
2298c2ecf20Sopenharmony_ci		}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci		val = dwc3_omap_read_utmi_ctrl(omap);
2328c2ecf20Sopenharmony_ci		val &= ~USBOTGSS_UTMI_OTG_CTRL_IDDIG;
2338c2ecf20Sopenharmony_ci		dwc3_omap_write_utmi_ctrl(omap, val);
2348c2ecf20Sopenharmony_ci		break;
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	case OMAP_DWC3_VBUS_VALID:
2378c2ecf20Sopenharmony_ci		val = dwc3_omap_read_utmi_ctrl(omap);
2388c2ecf20Sopenharmony_ci		val &= ~USBOTGSS_UTMI_OTG_CTRL_SESSEND;
2398c2ecf20Sopenharmony_ci		val |= USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
2408c2ecf20Sopenharmony_ci				| USBOTGSS_UTMI_OTG_CTRL_SESSVALID;
2418c2ecf20Sopenharmony_ci		dwc3_omap_write_utmi_ctrl(omap, val);
2428c2ecf20Sopenharmony_ci		break;
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	case OMAP_DWC3_ID_FLOAT:
2458c2ecf20Sopenharmony_ci		if (omap->vbus_reg && regulator_is_enabled(omap->vbus_reg))
2468c2ecf20Sopenharmony_ci			regulator_disable(omap->vbus_reg);
2478c2ecf20Sopenharmony_ci		val = dwc3_omap_read_utmi_ctrl(omap);
2488c2ecf20Sopenharmony_ci		val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
2498c2ecf20Sopenharmony_ci		dwc3_omap_write_utmi_ctrl(omap, val);
2508c2ecf20Sopenharmony_ci		break;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	case OMAP_DWC3_VBUS_OFF:
2538c2ecf20Sopenharmony_ci		val = dwc3_omap_read_utmi_ctrl(omap);
2548c2ecf20Sopenharmony_ci		val &= ~(USBOTGSS_UTMI_OTG_CTRL_SESSVALID
2558c2ecf20Sopenharmony_ci				| USBOTGSS_UTMI_OTG_CTRL_VBUSVALID);
2568c2ecf20Sopenharmony_ci		val |= USBOTGSS_UTMI_OTG_CTRL_SESSEND;
2578c2ecf20Sopenharmony_ci		dwc3_omap_write_utmi_ctrl(omap, val);
2588c2ecf20Sopenharmony_ci		break;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	default:
2618c2ecf20Sopenharmony_ci		dev_WARN(omap->dev, "invalid state\n");
2628c2ecf20Sopenharmony_ci	}
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_cistatic void dwc3_omap_enable_irqs(struct dwc3_omap *omap);
2668c2ecf20Sopenharmony_cistatic void dwc3_omap_disable_irqs(struct dwc3_omap *omap);
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_cistatic irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
2698c2ecf20Sopenharmony_ci{
2708c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap = _omap;
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	if (dwc3_omap_read_irqmisc_status(omap) ||
2738c2ecf20Sopenharmony_ci	    dwc3_omap_read_irq0_status(omap)) {
2748c2ecf20Sopenharmony_ci		/* mask irqs */
2758c2ecf20Sopenharmony_ci		dwc3_omap_disable_irqs(omap);
2768c2ecf20Sopenharmony_ci		return IRQ_WAKE_THREAD;
2778c2ecf20Sopenharmony_ci	}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	return IRQ_NONE;
2808c2ecf20Sopenharmony_ci}
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_cistatic irqreturn_t dwc3_omap_interrupt_thread(int irq, void *_omap)
2838c2ecf20Sopenharmony_ci{
2848c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap = _omap;
2858c2ecf20Sopenharmony_ci	u32			reg;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	/* clear irq status flags */
2888c2ecf20Sopenharmony_ci	reg = dwc3_omap_read_irqmisc_status(omap);
2898c2ecf20Sopenharmony_ci	dwc3_omap_write_irqmisc_status(omap, reg);
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	reg = dwc3_omap_read_irq0_status(omap);
2928c2ecf20Sopenharmony_ci	dwc3_omap_write_irq0_status(omap, reg);
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	/* unmask irqs */
2958c2ecf20Sopenharmony_ci	dwc3_omap_enable_irqs(omap);
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
2988c2ecf20Sopenharmony_ci}
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_cistatic void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
3018c2ecf20Sopenharmony_ci{
3028c2ecf20Sopenharmony_ci	u32			reg;
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	/* enable all IRQs */
3058c2ecf20Sopenharmony_ci	reg = USBOTGSS_IRQO_COREIRQ_ST;
3068c2ecf20Sopenharmony_ci	dwc3_omap_write_irq0_set(omap, reg);
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	reg = (USBOTGSS_IRQMISC_OEVT |
3098c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DRVVBUS_RISE |
3108c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_CHRGVBUS_RISE |
3118c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
3128c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_IDPULLUP_RISE |
3138c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DRVVBUS_FALL |
3148c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_CHRGVBUS_FALL |
3158c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
3168c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_IDPULLUP_FALL);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	dwc3_omap_write_irqmisc_set(omap, reg);
3198c2ecf20Sopenharmony_ci}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_cistatic void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
3228c2ecf20Sopenharmony_ci{
3238c2ecf20Sopenharmony_ci	u32			reg;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	/* disable all IRQs */
3268c2ecf20Sopenharmony_ci	reg = USBOTGSS_IRQO_COREIRQ_ST;
3278c2ecf20Sopenharmony_ci	dwc3_omap_write_irq0_clr(omap, reg);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	reg = (USBOTGSS_IRQMISC_OEVT |
3308c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DRVVBUS_RISE |
3318c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_CHRGVBUS_RISE |
3328c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
3338c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_IDPULLUP_RISE |
3348c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DRVVBUS_FALL |
3358c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_CHRGVBUS_FALL |
3368c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
3378c2ecf20Sopenharmony_ci			USBOTGSS_IRQMISC_IDPULLUP_FALL);
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci	dwc3_omap_write_irqmisc_clr(omap, reg);
3408c2ecf20Sopenharmony_ci}
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_cistatic int dwc3_omap_id_notifier(struct notifier_block *nb,
3438c2ecf20Sopenharmony_ci	unsigned long event, void *ptr)
3448c2ecf20Sopenharmony_ci{
3458c2ecf20Sopenharmony_ci	struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, id_nb);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	if (event)
3488c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
3498c2ecf20Sopenharmony_ci	else
3508c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	return NOTIFY_DONE;
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cistatic int dwc3_omap_vbus_notifier(struct notifier_block *nb,
3568c2ecf20Sopenharmony_ci	unsigned long event, void *ptr)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, vbus_nb);
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	if (event)
3618c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
3628c2ecf20Sopenharmony_ci	else
3638c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	return NOTIFY_DONE;
3668c2ecf20Sopenharmony_ci}
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_cistatic void dwc3_omap_map_offset(struct dwc3_omap *omap)
3698c2ecf20Sopenharmony_ci{
3708c2ecf20Sopenharmony_ci	struct device_node	*node = omap->dev->of_node;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	/*
3738c2ecf20Sopenharmony_ci	 * Differentiate between OMAP5 and AM437x.
3748c2ecf20Sopenharmony_ci	 *
3758c2ecf20Sopenharmony_ci	 * For OMAP5(ES2.0) and AM437x wrapper revision is same, even
3768c2ecf20Sopenharmony_ci	 * though there are changes in wrapper register offsets.
3778c2ecf20Sopenharmony_ci	 *
3788c2ecf20Sopenharmony_ci	 * Using dt compatible to differentiate AM437x.
3798c2ecf20Sopenharmony_ci	 */
3808c2ecf20Sopenharmony_ci	if (of_device_is_compatible(node, "ti,am437x-dwc3")) {
3818c2ecf20Sopenharmony_ci		omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET;
3828c2ecf20Sopenharmony_ci		omap->irq0_offset = USBOTGSS_IRQ0_OFFSET;
3838c2ecf20Sopenharmony_ci		omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
3848c2ecf20Sopenharmony_ci		omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
3858c2ecf20Sopenharmony_ci		omap->debug_offset = USBOTGSS_DEBUG_OFFSET;
3868c2ecf20Sopenharmony_ci	}
3878c2ecf20Sopenharmony_ci}
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_cistatic void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
3908c2ecf20Sopenharmony_ci{
3918c2ecf20Sopenharmony_ci	u32			reg;
3928c2ecf20Sopenharmony_ci	struct device_node	*node = omap->dev->of_node;
3938c2ecf20Sopenharmony_ci	u32			utmi_mode = 0;
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	reg = dwc3_omap_read_utmi_ctrl(omap);
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci	of_property_read_u32(node, "utmi-mode", &utmi_mode);
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	switch (utmi_mode) {
4008c2ecf20Sopenharmony_ci	case DWC3_OMAP_UTMI_MODE_SW:
4018c2ecf20Sopenharmony_ci		reg |= USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
4028c2ecf20Sopenharmony_ci		break;
4038c2ecf20Sopenharmony_ci	case DWC3_OMAP_UTMI_MODE_HW:
4048c2ecf20Sopenharmony_ci		reg &= ~USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
4058c2ecf20Sopenharmony_ci		break;
4068c2ecf20Sopenharmony_ci	default:
4078c2ecf20Sopenharmony_ci		dev_WARN(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode);
4088c2ecf20Sopenharmony_ci	}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci	dwc3_omap_write_utmi_ctrl(omap, reg);
4118c2ecf20Sopenharmony_ci}
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_cistatic int dwc3_omap_extcon_register(struct dwc3_omap *omap)
4148c2ecf20Sopenharmony_ci{
4158c2ecf20Sopenharmony_ci	int			ret;
4168c2ecf20Sopenharmony_ci	struct device_node	*node = omap->dev->of_node;
4178c2ecf20Sopenharmony_ci	struct extcon_dev	*edev;
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci	if (of_property_read_bool(node, "extcon")) {
4208c2ecf20Sopenharmony_ci		edev = extcon_get_edev_by_phandle(omap->dev, 0);
4218c2ecf20Sopenharmony_ci		if (IS_ERR(edev)) {
4228c2ecf20Sopenharmony_ci			dev_vdbg(omap->dev, "couldn't get extcon device\n");
4238c2ecf20Sopenharmony_ci			return -EPROBE_DEFER;
4248c2ecf20Sopenharmony_ci		}
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci		omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
4278c2ecf20Sopenharmony_ci		ret = devm_extcon_register_notifier(omap->dev, edev,
4288c2ecf20Sopenharmony_ci						EXTCON_USB, &omap->vbus_nb);
4298c2ecf20Sopenharmony_ci		if (ret < 0)
4308c2ecf20Sopenharmony_ci			dev_vdbg(omap->dev, "failed to register notifier for USB\n");
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_ci		omap->id_nb.notifier_call = dwc3_omap_id_notifier;
4338c2ecf20Sopenharmony_ci		ret = devm_extcon_register_notifier(omap->dev, edev,
4348c2ecf20Sopenharmony_ci						EXTCON_USB_HOST, &omap->id_nb);
4358c2ecf20Sopenharmony_ci		if (ret < 0)
4368c2ecf20Sopenharmony_ci			dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n");
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci		if (extcon_get_state(edev, EXTCON_USB) == true)
4398c2ecf20Sopenharmony_ci			dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
4408c2ecf20Sopenharmony_ci		else
4418c2ecf20Sopenharmony_ci			dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci		if (extcon_get_state(edev, EXTCON_USB_HOST) == true)
4448c2ecf20Sopenharmony_ci			dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
4458c2ecf20Sopenharmony_ci		else
4468c2ecf20Sopenharmony_ci			dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci		omap->edev = edev;
4498c2ecf20Sopenharmony_ci	}
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci	return 0;
4528c2ecf20Sopenharmony_ci}
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_cistatic int dwc3_omap_probe(struct platform_device *pdev)
4558c2ecf20Sopenharmony_ci{
4568c2ecf20Sopenharmony_ci	struct device_node	*node = pdev->dev.of_node;
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap;
4598c2ecf20Sopenharmony_ci	struct device		*dev = &pdev->dev;
4608c2ecf20Sopenharmony_ci	struct regulator	*vbus_reg = NULL;
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	int			ret;
4638c2ecf20Sopenharmony_ci	int			irq;
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	void __iomem		*base;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	if (!node) {
4688c2ecf20Sopenharmony_ci		dev_err(dev, "device node not found\n");
4698c2ecf20Sopenharmony_ci		return -EINVAL;
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
4738c2ecf20Sopenharmony_ci	if (!omap)
4748c2ecf20Sopenharmony_ci		return -ENOMEM;
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, omap);
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	irq = platform_get_irq(pdev, 0);
4798c2ecf20Sopenharmony_ci	if (irq < 0)
4808c2ecf20Sopenharmony_ci		return irq;
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	base = devm_platform_ioremap_resource(pdev, 0);
4838c2ecf20Sopenharmony_ci	if (IS_ERR(base))
4848c2ecf20Sopenharmony_ci		return PTR_ERR(base);
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	if (of_property_read_bool(node, "vbus-supply")) {
4878c2ecf20Sopenharmony_ci		vbus_reg = devm_regulator_get(dev, "vbus");
4888c2ecf20Sopenharmony_ci		if (IS_ERR(vbus_reg)) {
4898c2ecf20Sopenharmony_ci			dev_err(dev, "vbus init failed\n");
4908c2ecf20Sopenharmony_ci			return PTR_ERR(vbus_reg);
4918c2ecf20Sopenharmony_ci		}
4928c2ecf20Sopenharmony_ci	}
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	omap->dev	= dev;
4958c2ecf20Sopenharmony_ci	omap->irq	= irq;
4968c2ecf20Sopenharmony_ci	omap->base	= base;
4978c2ecf20Sopenharmony_ci	omap->vbus_reg	= vbus_reg;
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci	pm_runtime_enable(dev);
5008c2ecf20Sopenharmony_ci	ret = pm_runtime_get_sync(dev);
5018c2ecf20Sopenharmony_ci	if (ret < 0) {
5028c2ecf20Sopenharmony_ci		dev_err(dev, "get_sync failed with err %d\n", ret);
5038c2ecf20Sopenharmony_ci		goto err1;
5048c2ecf20Sopenharmony_ci	}
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_ci	dwc3_omap_map_offset(omap);
5078c2ecf20Sopenharmony_ci	dwc3_omap_set_utmi_mode(omap);
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci	ret = dwc3_omap_extcon_register(omap);
5108c2ecf20Sopenharmony_ci	if (ret < 0)
5118c2ecf20Sopenharmony_ci		goto err1;
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	ret = of_platform_populate(node, NULL, NULL, dev);
5148c2ecf20Sopenharmony_ci	if (ret) {
5158c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "failed to create dwc3 core\n");
5168c2ecf20Sopenharmony_ci		goto err1;
5178c2ecf20Sopenharmony_ci	}
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci	ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
5208c2ecf20Sopenharmony_ci					dwc3_omap_interrupt_thread, IRQF_SHARED,
5218c2ecf20Sopenharmony_ci					"dwc3-omap", omap);
5228c2ecf20Sopenharmony_ci	if (ret) {
5238c2ecf20Sopenharmony_ci		dev_err(dev, "failed to request IRQ #%d --> %d\n",
5248c2ecf20Sopenharmony_ci			omap->irq, ret);
5258c2ecf20Sopenharmony_ci		goto err1;
5268c2ecf20Sopenharmony_ci	}
5278c2ecf20Sopenharmony_ci	dwc3_omap_enable_irqs(omap);
5288c2ecf20Sopenharmony_ci	return 0;
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_cierr1:
5318c2ecf20Sopenharmony_ci	pm_runtime_put_sync(dev);
5328c2ecf20Sopenharmony_ci	pm_runtime_disable(dev);
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci	return ret;
5358c2ecf20Sopenharmony_ci}
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_cistatic int dwc3_omap_remove(struct platform_device *pdev)
5388c2ecf20Sopenharmony_ci{
5398c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap = platform_get_drvdata(pdev);
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci	dwc3_omap_disable_irqs(omap);
5428c2ecf20Sopenharmony_ci	disable_irq(omap->irq);
5438c2ecf20Sopenharmony_ci	of_platform_depopulate(omap->dev);
5448c2ecf20Sopenharmony_ci	pm_runtime_put_sync(&pdev->dev);
5458c2ecf20Sopenharmony_ci	pm_runtime_disable(&pdev->dev);
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	return 0;
5488c2ecf20Sopenharmony_ci}
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_cistatic const struct of_device_id of_dwc3_match[] = {
5518c2ecf20Sopenharmony_ci	{
5528c2ecf20Sopenharmony_ci		.compatible =	"ti,dwc3"
5538c2ecf20Sopenharmony_ci	},
5548c2ecf20Sopenharmony_ci	{
5558c2ecf20Sopenharmony_ci		.compatible =	"ti,am437x-dwc3"
5568c2ecf20Sopenharmony_ci	},
5578c2ecf20Sopenharmony_ci	{ },
5588c2ecf20Sopenharmony_ci};
5598c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, of_dwc3_match);
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP
5628c2ecf20Sopenharmony_cistatic int dwc3_omap_suspend(struct device *dev)
5638c2ecf20Sopenharmony_ci{
5648c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap = dev_get_drvdata(dev);
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	omap->utmi_otg_ctrl = dwc3_omap_read_utmi_ctrl(omap);
5678c2ecf20Sopenharmony_ci	dwc3_omap_disable_irqs(omap);
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	return 0;
5708c2ecf20Sopenharmony_ci}
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_cistatic int dwc3_omap_resume(struct device *dev)
5738c2ecf20Sopenharmony_ci{
5748c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap = dev_get_drvdata(dev);
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci	dwc3_omap_write_utmi_ctrl(omap, omap->utmi_otg_ctrl);
5778c2ecf20Sopenharmony_ci	dwc3_omap_enable_irqs(omap);
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_ci	pm_runtime_disable(dev);
5808c2ecf20Sopenharmony_ci	pm_runtime_set_active(dev);
5818c2ecf20Sopenharmony_ci	pm_runtime_enable(dev);
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci	return 0;
5848c2ecf20Sopenharmony_ci}
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_cistatic void dwc3_omap_complete(struct device *dev)
5878c2ecf20Sopenharmony_ci{
5888c2ecf20Sopenharmony_ci	struct dwc3_omap	*omap = dev_get_drvdata(dev);
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci	if (extcon_get_state(omap->edev, EXTCON_USB))
5918c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
5928c2ecf20Sopenharmony_ci	else
5938c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	if (extcon_get_state(omap->edev, EXTCON_USB_HOST))
5968c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
5978c2ecf20Sopenharmony_ci	else
5988c2ecf20Sopenharmony_ci		dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
5998c2ecf20Sopenharmony_ci}
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_cistatic const struct dev_pm_ops dwc3_omap_dev_pm_ops = {
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci	SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
6048c2ecf20Sopenharmony_ci	.complete = dwc3_omap_complete,
6058c2ecf20Sopenharmony_ci};
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci#define DEV_PM_OPS	(&dwc3_omap_dev_pm_ops)
6088c2ecf20Sopenharmony_ci#else
6098c2ecf20Sopenharmony_ci#define DEV_PM_OPS	NULL
6108c2ecf20Sopenharmony_ci#endif /* CONFIG_PM_SLEEP */
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_cistatic struct platform_driver dwc3_omap_driver = {
6138c2ecf20Sopenharmony_ci	.probe		= dwc3_omap_probe,
6148c2ecf20Sopenharmony_ci	.remove		= dwc3_omap_remove,
6158c2ecf20Sopenharmony_ci	.driver		= {
6168c2ecf20Sopenharmony_ci		.name	= "omap-dwc3",
6178c2ecf20Sopenharmony_ci		.of_match_table	= of_dwc3_match,
6188c2ecf20Sopenharmony_ci		.pm	= DEV_PM_OPS,
6198c2ecf20Sopenharmony_ci	},
6208c2ecf20Sopenharmony_ci};
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_cimodule_platform_driver(dwc3_omap_driver);
6238c2ecf20Sopenharmony_ci
6248c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:omap-dwc3");
6258c2ecf20Sopenharmony_ciMODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
6268c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
6278c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");
628