Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * dwc3-omap.c - OMAP Specific Glue layer
0004  *
0005  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
0006  *
0007  * Authors: Felipe Balbi <balbi@ti.com>,
0008  *      Sebastian Andrzej Siewior <bigeasy@linutronix.de>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/irq.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/pm_runtime.h>
0018 #include <linux/dma-mapping.h>
0019 #include <linux/ioport.h>
0020 #include <linux/io.h>
0021 #include <linux/of.h>
0022 #include <linux/of_platform.h>
0023 #include <linux/extcon.h>
0024 #include <linux/regulator/consumer.h>
0025 
0026 #include <linux/usb/otg.h>
0027 
0028 /*
0029  * All these registers belong to OMAP's Wrapper around the
0030  * DesignWare USB3 Core.
0031  */
0032 
0033 #define USBOTGSS_REVISION           0x0000
0034 #define USBOTGSS_SYSCONFIG          0x0010
0035 #define USBOTGSS_IRQ_EOI            0x0020
0036 #define USBOTGSS_EOI_OFFSET         0x0008
0037 #define USBOTGSS_IRQSTATUS_RAW_0        0x0024
0038 #define USBOTGSS_IRQSTATUS_0            0x0028
0039 #define USBOTGSS_IRQENABLE_SET_0        0x002c
0040 #define USBOTGSS_IRQENABLE_CLR_0        0x0030
0041 #define USBOTGSS_IRQ0_OFFSET            0x0004
0042 #define USBOTGSS_IRQSTATUS_RAW_1        0x0030
0043 #define USBOTGSS_IRQSTATUS_1            0x0034
0044 #define USBOTGSS_IRQENABLE_SET_1        0x0038
0045 #define USBOTGSS_IRQENABLE_CLR_1        0x003c
0046 #define USBOTGSS_IRQSTATUS_RAW_2        0x0040
0047 #define USBOTGSS_IRQSTATUS_2            0x0044
0048 #define USBOTGSS_IRQENABLE_SET_2        0x0048
0049 #define USBOTGSS_IRQENABLE_CLR_2        0x004c
0050 #define USBOTGSS_IRQSTATUS_RAW_3        0x0050
0051 #define USBOTGSS_IRQSTATUS_3            0x0054
0052 #define USBOTGSS_IRQENABLE_SET_3        0x0058
0053 #define USBOTGSS_IRQENABLE_CLR_3        0x005c
0054 #define USBOTGSS_IRQSTATUS_EOI_MISC     0x0030
0055 #define USBOTGSS_IRQSTATUS_RAW_MISC     0x0034
0056 #define USBOTGSS_IRQSTATUS_MISC         0x0038
0057 #define USBOTGSS_IRQENABLE_SET_MISC     0x003c
0058 #define USBOTGSS_IRQENABLE_CLR_MISC     0x0040
0059 #define USBOTGSS_IRQMISC_OFFSET         0x03fc
0060 #define USBOTGSS_UTMI_OTG_STATUS        0x0080
0061 #define USBOTGSS_UTMI_OTG_CTRL          0x0084
0062 #define USBOTGSS_UTMI_OTG_OFFSET        0x0480
0063 #define USBOTGSS_TXFIFO_DEPTH           0x0508
0064 #define USBOTGSS_RXFIFO_DEPTH           0x050c
0065 #define USBOTGSS_MMRAM_OFFSET           0x0100
0066 #define USBOTGSS_FLADJ              0x0104
0067 #define USBOTGSS_DEBUG_CFG          0x0108
0068 #define USBOTGSS_DEBUG_DATA         0x010c
0069 #define USBOTGSS_DEV_EBC_EN         0x0110
0070 #define USBOTGSS_DEBUG_OFFSET           0x0600
0071 
0072 /* SYSCONFIG REGISTER */
0073 #define USBOTGSS_SYSCONFIG_DMADISABLE       BIT(16)
0074 
0075 /* IRQ_EOI REGISTER */
0076 #define USBOTGSS_IRQ_EOI_LINE_NUMBER        BIT(0)
0077 
0078 /* IRQS0 BITS */
0079 #define USBOTGSS_IRQO_COREIRQ_ST        BIT(0)
0080 
0081 /* IRQMISC BITS */
0082 #define USBOTGSS_IRQMISC_DMADISABLECLR      BIT(17)
0083 #define USBOTGSS_IRQMISC_OEVT           BIT(16)
0084 #define USBOTGSS_IRQMISC_DRVVBUS_RISE       BIT(13)
0085 #define USBOTGSS_IRQMISC_CHRGVBUS_RISE      BIT(12)
0086 #define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE   BIT(11)
0087 #define USBOTGSS_IRQMISC_IDPULLUP_RISE      BIT(8)
0088 #define USBOTGSS_IRQMISC_DRVVBUS_FALL       BIT(5)
0089 #define USBOTGSS_IRQMISC_CHRGVBUS_FALL      BIT(4)
0090 #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL       BIT(3)
0091 #define USBOTGSS_IRQMISC_IDPULLUP_FALL      BIT(0)
0092 
0093 /* UTMI_OTG_STATUS REGISTER */
0094 #define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS    BIT(5)
0095 #define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS   BIT(4)
0096 #define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS    BIT(3)
0097 #define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP   BIT(0)
0098 
0099 /* UTMI_OTG_CTRL REGISTER */
0100 #define USBOTGSS_UTMI_OTG_CTRL_SW_MODE      BIT(31)
0101 #define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT BIT(9)
0102 #define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE BIT(8)
0103 #define USBOTGSS_UTMI_OTG_CTRL_IDDIG        BIT(4)
0104 #define USBOTGSS_UTMI_OTG_CTRL_SESSEND      BIT(3)
0105 #define USBOTGSS_UTMI_OTG_CTRL_SESSVALID    BIT(2)
0106 #define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID    BIT(1)
0107 
0108 enum dwc3_omap_utmi_mode {
0109     DWC3_OMAP_UTMI_MODE_UNKNOWN = 0,
0110     DWC3_OMAP_UTMI_MODE_HW,
0111     DWC3_OMAP_UTMI_MODE_SW,
0112 };
0113 
0114 struct dwc3_omap {
0115     struct device       *dev;
0116 
0117     int         irq;
0118     void __iomem        *base;
0119 
0120     u32         utmi_otg_ctrl;
0121     u32         utmi_otg_offset;
0122     u32         irqmisc_offset;
0123     u32         irq_eoi_offset;
0124     u32         debug_offset;
0125     u32         irq0_offset;
0126 
0127     struct extcon_dev   *edev;
0128     struct notifier_block   vbus_nb;
0129     struct notifier_block   id_nb;
0130 
0131     struct regulator    *vbus_reg;
0132 };
0133 
0134 enum omap_dwc3_vbus_id_status {
0135     OMAP_DWC3_ID_FLOAT,
0136     OMAP_DWC3_ID_GROUND,
0137     OMAP_DWC3_VBUS_OFF,
0138     OMAP_DWC3_VBUS_VALID,
0139 };
0140 
0141 static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
0142 {
0143     return readl(base + offset);
0144 }
0145 
0146 static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
0147 {
0148     writel(value, base + offset);
0149 }
0150 
0151 static u32 dwc3_omap_read_utmi_ctrl(struct dwc3_omap *omap)
0152 {
0153     return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL +
0154                             omap->utmi_otg_offset);
0155 }
0156 
0157 static void dwc3_omap_write_utmi_ctrl(struct dwc3_omap *omap, u32 value)
0158 {
0159     dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL +
0160                     omap->utmi_otg_offset, value);
0161 
0162 }
0163 
0164 static u32 dwc3_omap_read_irq0_status(struct dwc3_omap *omap)
0165 {
0166     return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_0 -
0167                         omap->irq0_offset);
0168 }
0169 
0170 static void dwc3_omap_write_irq0_status(struct dwc3_omap *omap, u32 value)
0171 {
0172     dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0 -
0173                         omap->irq0_offset, value);
0174 
0175 }
0176 
0177 static u32 dwc3_omap_read_irqmisc_status(struct dwc3_omap *omap)
0178 {
0179     return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_RAW_MISC +
0180                         omap->irqmisc_offset);
0181 }
0182 
0183 static void dwc3_omap_write_irqmisc_status(struct dwc3_omap *omap, u32 value)
0184 {
0185     dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_MISC +
0186                     omap->irqmisc_offset, value);
0187 
0188 }
0189 
0190 static void dwc3_omap_write_irqmisc_set(struct dwc3_omap *omap, u32 value)
0191 {
0192     dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_MISC +
0193                         omap->irqmisc_offset, value);
0194 
0195 }
0196 
0197 static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value)
0198 {
0199     dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0 -
0200                         omap->irq0_offset, value);
0201 }
0202 
0203 static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
0204 {
0205     dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_MISC +
0206                         omap->irqmisc_offset, value);
0207 }
0208 
0209 static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
0210 {
0211     dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_CLR_0 -
0212                         omap->irq0_offset, value);
0213 }
0214 
0215 static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
0216     enum omap_dwc3_vbus_id_status status)
0217 {
0218     int ret;
0219     u32 val;
0220 
0221     switch (status) {
0222     case OMAP_DWC3_ID_GROUND:
0223         if (omap->vbus_reg) {
0224             ret = regulator_enable(omap->vbus_reg);
0225             if (ret) {
0226                 dev_err(omap->dev, "regulator enable failed\n");
0227                 return;
0228             }
0229         }
0230 
0231         val = dwc3_omap_read_utmi_ctrl(omap);
0232         val &= ~USBOTGSS_UTMI_OTG_CTRL_IDDIG;
0233         dwc3_omap_write_utmi_ctrl(omap, val);
0234         break;
0235 
0236     case OMAP_DWC3_VBUS_VALID:
0237         val = dwc3_omap_read_utmi_ctrl(omap);
0238         val &= ~USBOTGSS_UTMI_OTG_CTRL_SESSEND;
0239         val |= USBOTGSS_UTMI_OTG_CTRL_VBUSVALID
0240                 | USBOTGSS_UTMI_OTG_CTRL_SESSVALID;
0241         dwc3_omap_write_utmi_ctrl(omap, val);
0242         break;
0243 
0244     case OMAP_DWC3_ID_FLOAT:
0245         if (omap->vbus_reg && regulator_is_enabled(omap->vbus_reg))
0246             regulator_disable(omap->vbus_reg);
0247         val = dwc3_omap_read_utmi_ctrl(omap);
0248         val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
0249         dwc3_omap_write_utmi_ctrl(omap, val);
0250         break;
0251 
0252     case OMAP_DWC3_VBUS_OFF:
0253         val = dwc3_omap_read_utmi_ctrl(omap);
0254         val &= ~(USBOTGSS_UTMI_OTG_CTRL_SESSVALID
0255                 | USBOTGSS_UTMI_OTG_CTRL_VBUSVALID);
0256         val |= USBOTGSS_UTMI_OTG_CTRL_SESSEND;
0257         dwc3_omap_write_utmi_ctrl(omap, val);
0258         break;
0259 
0260     default:
0261         dev_WARN(omap->dev, "invalid state\n");
0262     }
0263 }
0264 
0265 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap);
0266 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap);
0267 
0268 static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
0269 {
0270     struct dwc3_omap    *omap = _omap;
0271 
0272     if (dwc3_omap_read_irqmisc_status(omap) ||
0273         dwc3_omap_read_irq0_status(omap)) {
0274         /* mask irqs */
0275         dwc3_omap_disable_irqs(omap);
0276         return IRQ_WAKE_THREAD;
0277     }
0278 
0279     return IRQ_NONE;
0280 }
0281 
0282 static irqreturn_t dwc3_omap_interrupt_thread(int irq, void *_omap)
0283 {
0284     struct dwc3_omap    *omap = _omap;
0285     u32         reg;
0286 
0287     /* clear irq status flags */
0288     reg = dwc3_omap_read_irqmisc_status(omap);
0289     dwc3_omap_write_irqmisc_status(omap, reg);
0290 
0291     reg = dwc3_omap_read_irq0_status(omap);
0292     dwc3_omap_write_irq0_status(omap, reg);
0293 
0294     /* unmask irqs */
0295     dwc3_omap_enable_irqs(omap);
0296 
0297     return IRQ_HANDLED;
0298 }
0299 
0300 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
0301 {
0302     u32         reg;
0303 
0304     /* enable all IRQs */
0305     reg = USBOTGSS_IRQO_COREIRQ_ST;
0306     dwc3_omap_write_irq0_set(omap, reg);
0307 
0308     reg = (USBOTGSS_IRQMISC_OEVT |
0309             USBOTGSS_IRQMISC_DRVVBUS_RISE |
0310             USBOTGSS_IRQMISC_CHRGVBUS_RISE |
0311             USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
0312             USBOTGSS_IRQMISC_IDPULLUP_RISE |
0313             USBOTGSS_IRQMISC_DRVVBUS_FALL |
0314             USBOTGSS_IRQMISC_CHRGVBUS_FALL |
0315             USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
0316             USBOTGSS_IRQMISC_IDPULLUP_FALL);
0317 
0318     dwc3_omap_write_irqmisc_set(omap, reg);
0319 }
0320 
0321 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
0322 {
0323     u32         reg;
0324 
0325     /* disable all IRQs */
0326     reg = USBOTGSS_IRQO_COREIRQ_ST;
0327     dwc3_omap_write_irq0_clr(omap, reg);
0328 
0329     reg = (USBOTGSS_IRQMISC_OEVT |
0330             USBOTGSS_IRQMISC_DRVVBUS_RISE |
0331             USBOTGSS_IRQMISC_CHRGVBUS_RISE |
0332             USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
0333             USBOTGSS_IRQMISC_IDPULLUP_RISE |
0334             USBOTGSS_IRQMISC_DRVVBUS_FALL |
0335             USBOTGSS_IRQMISC_CHRGVBUS_FALL |
0336             USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
0337             USBOTGSS_IRQMISC_IDPULLUP_FALL);
0338 
0339     dwc3_omap_write_irqmisc_clr(omap, reg);
0340 }
0341 
0342 static int dwc3_omap_id_notifier(struct notifier_block *nb,
0343     unsigned long event, void *ptr)
0344 {
0345     struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, id_nb);
0346 
0347     if (event)
0348         dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
0349     else
0350         dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
0351 
0352     return NOTIFY_DONE;
0353 }
0354 
0355 static int dwc3_omap_vbus_notifier(struct notifier_block *nb,
0356     unsigned long event, void *ptr)
0357 {
0358     struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, vbus_nb);
0359 
0360     if (event)
0361         dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
0362     else
0363         dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
0364 
0365     return NOTIFY_DONE;
0366 }
0367 
0368 static void dwc3_omap_map_offset(struct dwc3_omap *omap)
0369 {
0370     struct device_node  *node = omap->dev->of_node;
0371 
0372     /*
0373      * Differentiate between OMAP5 and AM437x.
0374      *
0375      * For OMAP5(ES2.0) and AM437x wrapper revision is same, even
0376      * though there are changes in wrapper register offsets.
0377      *
0378      * Using dt compatible to differentiate AM437x.
0379      */
0380     if (of_device_is_compatible(node, "ti,am437x-dwc3")) {
0381         omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET;
0382         omap->irq0_offset = USBOTGSS_IRQ0_OFFSET;
0383         omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
0384         omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
0385         omap->debug_offset = USBOTGSS_DEBUG_OFFSET;
0386     }
0387 }
0388 
0389 static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
0390 {
0391     u32         reg;
0392     struct device_node  *node = omap->dev->of_node;
0393     u32         utmi_mode = 0;
0394 
0395     reg = dwc3_omap_read_utmi_ctrl(omap);
0396 
0397     of_property_read_u32(node, "utmi-mode", &utmi_mode);
0398 
0399     switch (utmi_mode) {
0400     case DWC3_OMAP_UTMI_MODE_SW:
0401         reg |= USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
0402         break;
0403     case DWC3_OMAP_UTMI_MODE_HW:
0404         reg &= ~USBOTGSS_UTMI_OTG_CTRL_SW_MODE;
0405         break;
0406     default:
0407         dev_WARN(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode);
0408     }
0409 
0410     dwc3_omap_write_utmi_ctrl(omap, reg);
0411 }
0412 
0413 static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
0414 {
0415     int         ret;
0416     struct device_node  *node = omap->dev->of_node;
0417     struct extcon_dev   *edev;
0418 
0419     if (of_property_read_bool(node, "extcon")) {
0420         edev = extcon_get_edev_by_phandle(omap->dev, 0);
0421         if (IS_ERR(edev)) {
0422             dev_vdbg(omap->dev, "couldn't get extcon device\n");
0423             return -EPROBE_DEFER;
0424         }
0425 
0426         omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
0427         ret = devm_extcon_register_notifier(omap->dev, edev,
0428                         EXTCON_USB, &omap->vbus_nb);
0429         if (ret < 0)
0430             dev_vdbg(omap->dev, "failed to register notifier for USB\n");
0431 
0432         omap->id_nb.notifier_call = dwc3_omap_id_notifier;
0433         ret = devm_extcon_register_notifier(omap->dev, edev,
0434                         EXTCON_USB_HOST, &omap->id_nb);
0435         if (ret < 0)
0436             dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n");
0437 
0438         if (extcon_get_state(edev, EXTCON_USB) == true)
0439             dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
0440         else
0441             dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
0442 
0443         if (extcon_get_state(edev, EXTCON_USB_HOST) == true)
0444             dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
0445         else
0446             dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
0447 
0448         omap->edev = edev;
0449     }
0450 
0451     return 0;
0452 }
0453 
0454 static int dwc3_omap_probe(struct platform_device *pdev)
0455 {
0456     struct device_node  *node = pdev->dev.of_node;
0457 
0458     struct dwc3_omap    *omap;
0459     struct device       *dev = &pdev->dev;
0460     struct regulator    *vbus_reg = NULL;
0461 
0462     int         ret;
0463     int         irq;
0464 
0465     void __iomem        *base;
0466 
0467     if (!node) {
0468         dev_err(dev, "device node not found\n");
0469         return -EINVAL;
0470     }
0471 
0472     omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
0473     if (!omap)
0474         return -ENOMEM;
0475 
0476     platform_set_drvdata(pdev, omap);
0477 
0478     irq = platform_get_irq(pdev, 0);
0479     if (irq < 0)
0480         return irq;
0481 
0482     base = devm_platform_ioremap_resource(pdev, 0);
0483     if (IS_ERR(base))
0484         return PTR_ERR(base);
0485 
0486     if (of_property_read_bool(node, "vbus-supply")) {
0487         vbus_reg = devm_regulator_get(dev, "vbus");
0488         if (IS_ERR(vbus_reg)) {
0489             dev_err(dev, "vbus init failed\n");
0490             return PTR_ERR(vbus_reg);
0491         }
0492     }
0493 
0494     omap->dev   = dev;
0495     omap->irq   = irq;
0496     omap->base  = base;
0497     omap->vbus_reg  = vbus_reg;
0498 
0499     pm_runtime_enable(dev);
0500     ret = pm_runtime_get_sync(dev);
0501     if (ret < 0) {
0502         dev_err(dev, "get_sync failed with err %d\n", ret);
0503         goto err1;
0504     }
0505 
0506     dwc3_omap_map_offset(omap);
0507     dwc3_omap_set_utmi_mode(omap);
0508 
0509     ret = dwc3_omap_extcon_register(omap);
0510     if (ret < 0)
0511         goto err1;
0512 
0513     ret = of_platform_populate(node, NULL, NULL, dev);
0514     if (ret) {
0515         dev_err(&pdev->dev, "failed to create dwc3 core\n");
0516         goto err1;
0517     }
0518 
0519     ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
0520                     dwc3_omap_interrupt_thread, IRQF_SHARED,
0521                     "dwc3-omap", omap);
0522     if (ret) {
0523         dev_err(dev, "failed to request IRQ #%d --> %d\n",
0524             omap->irq, ret);
0525         goto err1;
0526     }
0527     dwc3_omap_enable_irqs(omap);
0528     return 0;
0529 
0530 err1:
0531     pm_runtime_put_sync(dev);
0532     pm_runtime_disable(dev);
0533 
0534     return ret;
0535 }
0536 
0537 static int dwc3_omap_remove(struct platform_device *pdev)
0538 {
0539     struct dwc3_omap    *omap = platform_get_drvdata(pdev);
0540 
0541     dwc3_omap_disable_irqs(omap);
0542     disable_irq(omap->irq);
0543     of_platform_depopulate(omap->dev);
0544     pm_runtime_put_sync(&pdev->dev);
0545     pm_runtime_disable(&pdev->dev);
0546 
0547     return 0;
0548 }
0549 
0550 static const struct of_device_id of_dwc3_match[] = {
0551     {
0552         .compatible =   "ti,dwc3"
0553     },
0554     {
0555         .compatible =   "ti,am437x-dwc3"
0556     },
0557     { },
0558 };
0559 MODULE_DEVICE_TABLE(of, of_dwc3_match);
0560 
0561 #ifdef CONFIG_PM_SLEEP
0562 static int dwc3_omap_suspend(struct device *dev)
0563 {
0564     struct dwc3_omap    *omap = dev_get_drvdata(dev);
0565 
0566     omap->utmi_otg_ctrl = dwc3_omap_read_utmi_ctrl(omap);
0567     dwc3_omap_disable_irqs(omap);
0568 
0569     return 0;
0570 }
0571 
0572 static int dwc3_omap_resume(struct device *dev)
0573 {
0574     struct dwc3_omap    *omap = dev_get_drvdata(dev);
0575 
0576     dwc3_omap_write_utmi_ctrl(omap, omap->utmi_otg_ctrl);
0577     dwc3_omap_enable_irqs(omap);
0578 
0579     pm_runtime_disable(dev);
0580     pm_runtime_set_active(dev);
0581     pm_runtime_enable(dev);
0582 
0583     return 0;
0584 }
0585 
0586 static void dwc3_omap_complete(struct device *dev)
0587 {
0588     struct dwc3_omap    *omap = dev_get_drvdata(dev);
0589 
0590     if (extcon_get_state(omap->edev, EXTCON_USB))
0591         dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
0592     else
0593         dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
0594 
0595     if (extcon_get_state(omap->edev, EXTCON_USB_HOST))
0596         dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
0597     else
0598         dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
0599 }
0600 
0601 static const struct dev_pm_ops dwc3_omap_dev_pm_ops = {
0602 
0603     SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
0604     .complete = dwc3_omap_complete,
0605 };
0606 
0607 #define DEV_PM_OPS  (&dwc3_omap_dev_pm_ops)
0608 #else
0609 #define DEV_PM_OPS  NULL
0610 #endif /* CONFIG_PM_SLEEP */
0611 
0612 static struct platform_driver dwc3_omap_driver = {
0613     .probe      = dwc3_omap_probe,
0614     .remove     = dwc3_omap_remove,
0615     .driver     = {
0616         .name   = "omap-dwc3",
0617         .of_match_table = of_dwc3_match,
0618         .pm = DEV_PM_OPS,
0619     },
0620 };
0621 
0622 module_platform_driver(dwc3_omap_driver);
0623 
0624 MODULE_ALIAS("platform:omap-dwc3");
0625 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
0626 MODULE_LICENSE("GPL v2");
0627 MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");