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/interrupt.h> 23 #include <linux/platform_device.h> 24 #include <linux/platform_data/dwc3-omap.h> 25 #include <linux/pm_runtime.h> 26 #include <linux/dma-mapping.h> 27 #include <linux/ioport.h> 28 #include <linux/io.h> 29 #include <linux/of.h> 30 #include <linux/of_platform.h> 31 #include <linux/extcon.h> 32 #include <linux/extcon/of_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_CTRL 0x0080 70 #define USBOTGSS_UTMI_OTG_STATUS 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 /* REVISION REGISTER */ 82 #define USBOTGSS_REVISION_XMAJOR(reg) ((reg >> 8) & 0x7) 83 #define USBOTGSS_REVISION_XMAJOR1 1 84 #define USBOTGSS_REVISION_XMAJOR2 2 85 /* SYSCONFIG REGISTER */ 86 #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) 87 88 /* IRQ_EOI REGISTER */ 89 #define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0) 90 91 /* IRQS0 BITS */ 92 #define USBOTGSS_IRQO_COREIRQ_ST (1 << 0) 93 94 /* IRQMISC BITS */ 95 #define USBOTGSS_IRQMISC_DMADISABLECLR (1 << 17) 96 #define USBOTGSS_IRQMISC_OEVT (1 << 16) 97 #define USBOTGSS_IRQMISC_DRVVBUS_RISE (1 << 13) 98 #define USBOTGSS_IRQMISC_CHRGVBUS_RISE (1 << 12) 99 #define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE (1 << 11) 100 #define USBOTGSS_IRQMISC_IDPULLUP_RISE (1 << 8) 101 #define USBOTGSS_IRQMISC_DRVVBUS_FALL (1 << 5) 102 #define USBOTGSS_IRQMISC_CHRGVBUS_FALL (1 << 4) 103 #define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL (1 << 3) 104 #define USBOTGSS_IRQMISC_IDPULLUP_FALL (1 << 0) 105 106 /* UTMI_OTG_CTRL REGISTER */ 107 #define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5) 108 #define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4) 109 #define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS (1 << 3) 110 #define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP (1 << 0) 111 112 /* UTMI_OTG_STATUS REGISTER */ 113 #define USBOTGSS_UTMI_OTG_STATUS_SW_MODE (1 << 31) 114 #define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT (1 << 9) 115 #define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8) 116 #define USBOTGSS_UTMI_OTG_STATUS_IDDIG (1 << 4) 117 #define USBOTGSS_UTMI_OTG_STATUS_SESSEND (1 << 3) 118 #define USBOTGSS_UTMI_OTG_STATUS_SESSVALID (1 << 2) 119 #define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID (1 << 1) 120 121 struct dwc3_omap { 122 struct device *dev; 123 124 int irq; 125 void __iomem *base; 126 127 u32 utmi_otg_status; 128 u32 utmi_otg_offset; 129 u32 irqmisc_offset; 130 u32 irq_eoi_offset; 131 u32 debug_offset; 132 u32 irq0_offset; 133 u32 revision; 134 135 u32 dma_status:1; 136 137 struct extcon_specific_cable_nb extcon_vbus_dev; 138 struct extcon_specific_cable_nb extcon_id_dev; 139 struct notifier_block vbus_nb; 140 struct notifier_block id_nb; 141 142 struct regulator *vbus_reg; 143 }; 144 145 enum omap_dwc3_vbus_id_status { 146 OMAP_DWC3_ID_FLOAT, 147 OMAP_DWC3_ID_GROUND, 148 OMAP_DWC3_VBUS_OFF, 149 OMAP_DWC3_VBUS_VALID, 150 }; 151 152 static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) 153 { 154 return readl(base + offset); 155 } 156 157 static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) 158 { 159 writel(value, base + offset); 160 } 161 162 static u32 dwc3_omap_read_utmi_status(struct dwc3_omap *omap) 163 { 164 return dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS + 165 omap->utmi_otg_offset); 166 } 167 168 static void dwc3_omap_write_utmi_status(struct dwc3_omap *omap, u32 value) 169 { 170 dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS + 171 omap->utmi_otg_offset, value); 172 173 } 174 175 static u32 dwc3_omap_read_irq0_status(struct dwc3_omap *omap) 176 { 177 return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_0 - 178 omap->irq0_offset); 179 } 180 181 static void dwc3_omap_write_irq0_status(struct dwc3_omap *omap, u32 value) 182 { 183 dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0 - 184 omap->irq0_offset, value); 185 186 } 187 188 static u32 dwc3_omap_read_irqmisc_status(struct dwc3_omap *omap) 189 { 190 return dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_MISC + 191 omap->irqmisc_offset); 192 } 193 194 static void dwc3_omap_write_irqmisc_status(struct dwc3_omap *omap, u32 value) 195 { 196 dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_MISC + 197 omap->irqmisc_offset, value); 198 199 } 200 201 static void dwc3_omap_write_irqmisc_set(struct dwc3_omap *omap, u32 value) 202 { 203 dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_MISC + 204 omap->irqmisc_offset, value); 205 206 } 207 208 static void dwc3_omap_write_irq0_set(struct dwc3_omap *omap, u32 value) 209 { 210 dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0 - 211 omap->irq0_offset, value); 212 } 213 214 static void dwc3_omap_set_mailbox(struct dwc3_omap *omap, 215 enum omap_dwc3_vbus_id_status status) 216 { 217 int ret; 218 u32 val; 219 220 switch (status) { 221 case OMAP_DWC3_ID_GROUND: 222 dev_dbg(omap->dev, "ID GND\n"); 223 224 if (omap->vbus_reg) { 225 ret = regulator_enable(omap->vbus_reg); 226 if (ret) { 227 dev_dbg(omap->dev, "regulator enable failed\n"); 228 return; 229 } 230 } 231 232 val = dwc3_omap_read_utmi_status(omap); 233 val &= ~(USBOTGSS_UTMI_OTG_STATUS_IDDIG 234 | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID 235 | USBOTGSS_UTMI_OTG_STATUS_SESSEND); 236 val |= USBOTGSS_UTMI_OTG_STATUS_SESSVALID 237 | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; 238 dwc3_omap_write_utmi_status(omap, val); 239 break; 240 241 case OMAP_DWC3_VBUS_VALID: 242 dev_dbg(omap->dev, "VBUS Connect\n"); 243 244 val = dwc3_omap_read_utmi_status(omap); 245 val &= ~USBOTGSS_UTMI_OTG_STATUS_SESSEND; 246 val |= USBOTGSS_UTMI_OTG_STATUS_IDDIG 247 | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID 248 | USBOTGSS_UTMI_OTG_STATUS_SESSVALID 249 | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT; 250 dwc3_omap_write_utmi_status(omap, val); 251 break; 252 253 case OMAP_DWC3_ID_FLOAT: 254 if (omap->vbus_reg) 255 regulator_disable(omap->vbus_reg); 256 257 case OMAP_DWC3_VBUS_OFF: 258 dev_dbg(omap->dev, "VBUS Disconnect\n"); 259 260 val = dwc3_omap_read_utmi_status(omap); 261 val &= ~(USBOTGSS_UTMI_OTG_STATUS_SESSVALID 262 | USBOTGSS_UTMI_OTG_STATUS_VBUSVALID 263 | USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT); 264 val |= USBOTGSS_UTMI_OTG_STATUS_SESSEND 265 | USBOTGSS_UTMI_OTG_STATUS_IDDIG; 266 dwc3_omap_write_utmi_status(omap, val); 267 break; 268 269 default: 270 dev_dbg(omap->dev, "invalid state\n"); 271 } 272 } 273 274 static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) 275 { 276 struct dwc3_omap *omap = _omap; 277 u32 reg; 278 279 reg = dwc3_omap_read_irqmisc_status(omap); 280 281 if (reg & USBOTGSS_IRQMISC_DMADISABLECLR) { 282 dev_dbg(omap->dev, "DMA Disable was Cleared\n"); 283 omap->dma_status = false; 284 } 285 286 if (reg & USBOTGSS_IRQMISC_OEVT) 287 dev_dbg(omap->dev, "OTG Event\n"); 288 289 if (reg & USBOTGSS_IRQMISC_DRVVBUS_RISE) 290 dev_dbg(omap->dev, "DRVVBUS Rise\n"); 291 292 if (reg & USBOTGSS_IRQMISC_CHRGVBUS_RISE) 293 dev_dbg(omap->dev, "CHRGVBUS Rise\n"); 294 295 if (reg & USBOTGSS_IRQMISC_DISCHRGVBUS_RISE) 296 dev_dbg(omap->dev, "DISCHRGVBUS Rise\n"); 297 298 if (reg & USBOTGSS_IRQMISC_IDPULLUP_RISE) 299 dev_dbg(omap->dev, "IDPULLUP Rise\n"); 300 301 if (reg & USBOTGSS_IRQMISC_DRVVBUS_FALL) 302 dev_dbg(omap->dev, "DRVVBUS Fall\n"); 303 304 if (reg & USBOTGSS_IRQMISC_CHRGVBUS_FALL) 305 dev_dbg(omap->dev, "CHRGVBUS Fall\n"); 306 307 if (reg & USBOTGSS_IRQMISC_DISCHRGVBUS_FALL) 308 dev_dbg(omap->dev, "DISCHRGVBUS Fall\n"); 309 310 if (reg & USBOTGSS_IRQMISC_IDPULLUP_FALL) 311 dev_dbg(omap->dev, "IDPULLUP Fall\n"); 312 313 dwc3_omap_write_irqmisc_status(omap, reg); 314 315 reg = dwc3_omap_read_irq0_status(omap); 316 317 dwc3_omap_write_irq0_status(omap, reg); 318 319 return IRQ_HANDLED; 320 } 321 322 static int dwc3_omap_remove_core(struct device *dev, void *c) 323 { 324 struct platform_device *pdev = to_platform_device(dev); 325 326 platform_device_unregister(pdev); 327 328 return 0; 329 } 330 331 static void dwc3_omap_enable_irqs(struct dwc3_omap *omap) 332 { 333 u32 reg; 334 335 /* enable all IRQs */ 336 reg = USBOTGSS_IRQO_COREIRQ_ST; 337 dwc3_omap_write_irq0_set(omap, reg); 338 339 reg = (USBOTGSS_IRQMISC_OEVT | 340 USBOTGSS_IRQMISC_DRVVBUS_RISE | 341 USBOTGSS_IRQMISC_CHRGVBUS_RISE | 342 USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | 343 USBOTGSS_IRQMISC_IDPULLUP_RISE | 344 USBOTGSS_IRQMISC_DRVVBUS_FALL | 345 USBOTGSS_IRQMISC_CHRGVBUS_FALL | 346 USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | 347 USBOTGSS_IRQMISC_IDPULLUP_FALL); 348 349 dwc3_omap_write_irqmisc_set(omap, reg); 350 } 351 352 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap) 353 { 354 /* disable all IRQs */ 355 dwc3_omap_write_irqmisc_set(omap, 0x00); 356 dwc3_omap_write_irq0_set(omap, 0x00); 357 } 358 359 static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32); 360 361 static int dwc3_omap_id_notifier(struct notifier_block *nb, 362 unsigned long event, void *ptr) 363 { 364 struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, id_nb); 365 366 if (event) 367 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); 368 else 369 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT); 370 371 return NOTIFY_DONE; 372 } 373 374 static int dwc3_omap_vbus_notifier(struct notifier_block *nb, 375 unsigned long event, void *ptr) 376 { 377 struct dwc3_omap *omap = container_of(nb, struct dwc3_omap, vbus_nb); 378 379 if (event) 380 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); 381 else 382 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF); 383 384 return NOTIFY_DONE; 385 } 386 387 static int dwc3_omap_probe(struct platform_device *pdev) 388 { 389 struct device_node *node = pdev->dev.of_node; 390 391 struct dwc3_omap *omap; 392 struct resource *res; 393 struct device *dev = &pdev->dev; 394 struct extcon_dev *edev; 395 struct regulator *vbus_reg = NULL; 396 397 int ret = -ENOMEM; 398 int irq; 399 400 int utmi_mode = 0; 401 int x_major; 402 403 u32 reg; 404 405 void __iomem *base; 406 407 if (!node) { 408 dev_err(dev, "device node not found\n"); 409 return -EINVAL; 410 } 411 412 omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL); 413 if (!omap) { 414 dev_err(dev, "not enough memory\n"); 415 return -ENOMEM; 416 } 417 418 platform_set_drvdata(pdev, omap); 419 420 irq = platform_get_irq(pdev, 0); 421 if (irq < 0) { 422 dev_err(dev, "missing IRQ resource\n"); 423 return -EINVAL; 424 } 425 426 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 427 if (!res) { 428 dev_err(dev, "missing memory base resource\n"); 429 return -EINVAL; 430 } 431 432 base = devm_ioremap_resource(dev, res); 433 if (IS_ERR(base)) 434 return PTR_ERR(base); 435 436 if (of_property_read_bool(node, "vbus-supply")) { 437 vbus_reg = devm_regulator_get(dev, "vbus"); 438 if (IS_ERR(vbus_reg)) { 439 dev_err(dev, "vbus init failed\n"); 440 return PTR_ERR(vbus_reg); 441 } 442 } 443 444 omap->dev = dev; 445 omap->irq = irq; 446 omap->base = base; 447 omap->vbus_reg = vbus_reg; 448 dev->dma_mask = &dwc3_omap_dma_mask; 449 450 pm_runtime_enable(dev); 451 ret = pm_runtime_get_sync(dev); 452 if (ret < 0) { 453 dev_err(dev, "get_sync failed with err %d\n", ret); 454 goto err0; 455 } 456 457 reg = dwc3_omap_readl(omap->base, USBOTGSS_REVISION); 458 omap->revision = reg; 459 x_major = USBOTGSS_REVISION_XMAJOR(reg); 460 461 /* Differentiate between OMAP5 and AM437x */ 462 switch (x_major) { 463 case USBOTGSS_REVISION_XMAJOR1: 464 case USBOTGSS_REVISION_XMAJOR2: 465 omap->irq_eoi_offset = 0; 466 omap->irq0_offset = 0; 467 omap->irqmisc_offset = 0; 468 omap->utmi_otg_offset = 0; 469 omap->debug_offset = 0; 470 break; 471 default: 472 /* Default to the latest revision */ 473 omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; 474 omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; 475 omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; 476 omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; 477 omap->debug_offset = USBOTGSS_DEBUG_OFFSET; 478 break; 479 } 480 481 /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are 482 * changes in wrapper registers, Using dt compatible for aegis 483 */ 484 485 if (of_device_is_compatible(node, "ti,am437x-dwc3")) { 486 omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; 487 omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; 488 omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; 489 omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; 490 omap->debug_offset = USBOTGSS_DEBUG_OFFSET; 491 } 492 493 reg = dwc3_omap_read_utmi_status(omap); 494 495 of_property_read_u32(node, "utmi-mode", &utmi_mode); 496 497 switch (utmi_mode) { 498 case DWC3_OMAP_UTMI_MODE_SW: 499 reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; 500 break; 501 case DWC3_OMAP_UTMI_MODE_HW: 502 reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; 503 break; 504 default: 505 dev_dbg(dev, "UNKNOWN utmi mode %d\n", utmi_mode); 506 } 507 508 dwc3_omap_write_utmi_status(omap, reg); 509 510 /* check the DMA Status */ 511 reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); 512 omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); 513 514 ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0, 515 "dwc3-omap", omap); 516 if (ret) { 517 dev_err(dev, "failed to request IRQ #%d --> %d\n", 518 omap->irq, ret); 519 goto err1; 520 } 521 522 dwc3_omap_enable_irqs(omap); 523 524 if (of_property_read_bool(node, "extcon")) { 525 edev = of_extcon_get_extcon_dev(dev, 0); 526 if (IS_ERR(edev)) { 527 dev_vdbg(dev, "couldn't get extcon device\n"); 528 ret = -EPROBE_DEFER; 529 goto err2; 530 } 531 532 omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; 533 ret = extcon_register_interest(&omap->extcon_vbus_dev, 534 edev->name, "USB", &omap->vbus_nb); 535 if (ret < 0) 536 dev_vdbg(dev, "failed to register notifier for USB\n"); 537 omap->id_nb.notifier_call = dwc3_omap_id_notifier; 538 ret = extcon_register_interest(&omap->extcon_id_dev, edev->name, 539 "USB-HOST", &omap->id_nb); 540 if (ret < 0) 541 dev_vdbg(dev, 542 "failed to register notifier for USB-HOST\n"); 543 544 if (extcon_get_cable_state(edev, "USB") == true) 545 dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); 546 if (extcon_get_cable_state(edev, "USB-HOST") == true) 547 dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); 548 } 549 550 ret = of_platform_populate(node, NULL, NULL, dev); 551 if (ret) { 552 dev_err(&pdev->dev, "failed to create dwc3 core\n"); 553 goto err3; 554 } 555 556 return 0; 557 558 err3: 559 if (omap->extcon_vbus_dev.edev) 560 extcon_unregister_interest(&omap->extcon_vbus_dev); 561 if (omap->extcon_id_dev.edev) 562 extcon_unregister_interest(&omap->extcon_id_dev); 563 564 err2: 565 dwc3_omap_disable_irqs(omap); 566 567 err1: 568 pm_runtime_put_sync(dev); 569 570 err0: 571 pm_runtime_disable(dev); 572 573 return ret; 574 } 575 576 static int dwc3_omap_remove(struct platform_device *pdev) 577 { 578 struct dwc3_omap *omap = platform_get_drvdata(pdev); 579 580 if (omap->extcon_vbus_dev.edev) 581 extcon_unregister_interest(&omap->extcon_vbus_dev); 582 if (omap->extcon_id_dev.edev) 583 extcon_unregister_interest(&omap->extcon_id_dev); 584 dwc3_omap_disable_irqs(omap); 585 pm_runtime_put_sync(&pdev->dev); 586 pm_runtime_disable(&pdev->dev); 587 device_for_each_child(&pdev->dev, NULL, dwc3_omap_remove_core); 588 589 return 0; 590 } 591 592 static const struct of_device_id of_dwc3_match[] = { 593 { 594 .compatible = "ti,dwc3" 595 }, 596 { 597 .compatible = "ti,am437x-dwc3" 598 }, 599 { }, 600 }; 601 MODULE_DEVICE_TABLE(of, of_dwc3_match); 602 603 #ifdef CONFIG_PM_SLEEP 604 static int dwc3_omap_prepare(struct device *dev) 605 { 606 struct dwc3_omap *omap = dev_get_drvdata(dev); 607 608 dwc3_omap_disable_irqs(omap); 609 610 return 0; 611 } 612 613 static void dwc3_omap_complete(struct device *dev) 614 { 615 struct dwc3_omap *omap = dev_get_drvdata(dev); 616 617 dwc3_omap_enable_irqs(omap); 618 } 619 620 static int dwc3_omap_suspend(struct device *dev) 621 { 622 struct dwc3_omap *omap = dev_get_drvdata(dev); 623 624 omap->utmi_otg_status = dwc3_omap_read_utmi_status(omap); 625 626 return 0; 627 } 628 629 static int dwc3_omap_resume(struct device *dev) 630 { 631 struct dwc3_omap *omap = dev_get_drvdata(dev); 632 633 dwc3_omap_write_utmi_status(omap, omap->utmi_otg_status); 634 635 pm_runtime_disable(dev); 636 pm_runtime_set_active(dev); 637 pm_runtime_enable(dev); 638 639 return 0; 640 } 641 642 static const struct dev_pm_ops dwc3_omap_dev_pm_ops = { 643 .prepare = dwc3_omap_prepare, 644 .complete = dwc3_omap_complete, 645 646 SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume) 647 }; 648 649 #define DEV_PM_OPS (&dwc3_omap_dev_pm_ops) 650 #else 651 #define DEV_PM_OPS NULL 652 #endif /* CONFIG_PM_SLEEP */ 653 654 static struct platform_driver dwc3_omap_driver = { 655 .probe = dwc3_omap_probe, 656 .remove = dwc3_omap_remove, 657 .driver = { 658 .name = "omap-dwc3", 659 .of_match_table = of_dwc3_match, 660 .pm = DEV_PM_OPS, 661 }, 662 }; 663 664 module_platform_driver(dwc3_omap_driver); 665 666 MODULE_ALIAS("platform:omap-dwc3"); 667 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 668 MODULE_LICENSE("GPL v2"); 669 MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer"); 670