Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/usb/dwc3/dwc3-omap.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us