diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-21 14:33:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-21 14:33:41 -0400 |
commit | 61fe2d75f138992f116ee70e83f10ff2d7e79143 (patch) | |
tree | c08ba135803a93852583a2916cd96981f53cfd06 /drivers/usb/dwc3 | |
parent | 499b3803d3e2f062f73bf22372b38393369ffcbf (diff) | |
parent | 8346b33fad01cfe93f0fd0e64cd32ff40bd4ba41 (diff) |
Merge tag 'usb-for-v3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes:
usb: patches for v3.17 merge window
Surprisingly enough, while a big set of patches, the majority is
composed of cleanups (using devm_*, fixing sparse errors, moving
code around, adding const, etc).
The highlights are addition of new support for PLX USB338x devices,
and support for USB 2.0-only configurations of the DWC3 IP core.
Signed-of-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r-- | drivers/usb/dwc3/core.c | 51 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 13 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-omap.c | 172 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 7 |
4 files changed, 134 insertions, 109 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index eb69eb9f06c8..b769c1faaf03 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -386,6 +386,13 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
386 | } | 386 | } |
387 | dwc->revision = reg; | 387 | dwc->revision = reg; |
388 | 388 | ||
389 | /* Handle USB2.0-only core configuration */ | ||
390 | if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == | ||
391 | DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { | ||
392 | if (dwc->maximum_speed == USB_SPEED_SUPER) | ||
393 | dwc->maximum_speed = USB_SPEED_HIGH; | ||
394 | } | ||
395 | |||
389 | /* issue device SoftReset too */ | 396 | /* issue device SoftReset too */ |
390 | timeout = jiffies + msecs_to_jiffies(500); | 397 | timeout = jiffies + msecs_to_jiffies(500); |
391 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); | 398 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); |
@@ -656,6 +663,31 @@ static int dwc3_probe(struct platform_device *pdev) | |||
656 | return -ENODEV; | 663 | return -ENODEV; |
657 | } | 664 | } |
658 | 665 | ||
666 | dwc->xhci_resources[0].start = res->start; | ||
667 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | ||
668 | DWC3_XHCI_REGS_END; | ||
669 | dwc->xhci_resources[0].flags = res->flags; | ||
670 | dwc->xhci_resources[0].name = res->name; | ||
671 | |||
672 | res->start += DWC3_GLOBALS_REGS_START; | ||
673 | |||
674 | /* | ||
675 | * Request memory region but exclude xHCI regs, | ||
676 | * since it will be requested by the xhci-plat driver. | ||
677 | */ | ||
678 | regs = devm_ioremap_resource(dev, res); | ||
679 | if (IS_ERR(regs)) | ||
680 | return PTR_ERR(regs); | ||
681 | |||
682 | dwc->regs = regs; | ||
683 | dwc->regs_size = resource_size(res); | ||
684 | /* | ||
685 | * restore res->start back to its original value so that, | ||
686 | * in case the probe is deferred, we don't end up getting error in | ||
687 | * request the memory region the next time probe is called. | ||
688 | */ | ||
689 | res->start -= DWC3_GLOBALS_REGS_START; | ||
690 | |||
659 | if (node) { | 691 | if (node) { |
660 | dwc->maximum_speed = of_usb_get_maximum_speed(node); | 692 | dwc->maximum_speed = of_usb_get_maximum_speed(node); |
661 | 693 | ||
@@ -676,28 +708,9 @@ static int dwc3_probe(struct platform_device *pdev) | |||
676 | if (ret) | 708 | if (ret) |
677 | return ret; | 709 | return ret; |
678 | 710 | ||
679 | dwc->xhci_resources[0].start = res->start; | ||
680 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | ||
681 | DWC3_XHCI_REGS_END; | ||
682 | dwc->xhci_resources[0].flags = res->flags; | ||
683 | dwc->xhci_resources[0].name = res->name; | ||
684 | |||
685 | res->start += DWC3_GLOBALS_REGS_START; | ||
686 | |||
687 | /* | ||
688 | * Request memory region but exclude xHCI regs, | ||
689 | * since it will be requested by the xhci-plat driver. | ||
690 | */ | ||
691 | regs = devm_ioremap_resource(dev, res); | ||
692 | if (IS_ERR(regs)) | ||
693 | return PTR_ERR(regs); | ||
694 | |||
695 | spin_lock_init(&dwc->lock); | 711 | spin_lock_init(&dwc->lock); |
696 | platform_set_drvdata(pdev, dwc); | 712 | platform_set_drvdata(pdev, dwc); |
697 | 713 | ||
698 | dwc->regs = regs; | ||
699 | dwc->regs_size = resource_size(res); | ||
700 | |||
701 | dev->dma_mask = dev->parent->dma_mask; | 714 | dev->dma_mask = dev->parent->dma_mask; |
702 | dev->dma_parms = dev->parent->dma_parms; | 715 | dev->dma_parms = dev->parent->dma_parms; |
703 | dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); | 716 | dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 57332e3768e4..48fb264065db 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -191,6 +191,19 @@ | |||
191 | #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) | 191 | #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) |
192 | #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) | 192 | #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) |
193 | 193 | ||
194 | /* Global HWPARAMS3 Register */ | ||
195 | #define DWC3_GHWPARAMS3_SSPHY_IFC(n) ((n) & 3) | ||
196 | #define DWC3_GHWPARAMS3_SSPHY_IFC_DIS 0 | ||
197 | #define DWC3_GHWPARAMS3_SSPHY_IFC_ENA 1 | ||
198 | #define DWC3_GHWPARAMS3_HSPHY_IFC(n) (((n) & (3 << 2)) >> 2) | ||
199 | #define DWC3_GHWPARAMS3_HSPHY_IFC_DIS 0 | ||
200 | #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI 1 | ||
201 | #define DWC3_GHWPARAMS3_HSPHY_IFC_ULPI 2 | ||
202 | #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI 3 | ||
203 | #define DWC3_GHWPARAMS3_FSPHY_IFC(n) (((n) & (3 << 4)) >> 4) | ||
204 | #define DWC3_GHWPARAMS3_FSPHY_IFC_DIS 0 | ||
205 | #define DWC3_GHWPARAMS3_FSPHY_IFC_ENA 1 | ||
206 | |||
194 | /* Global HWPARAMS4 Register */ | 207 | /* Global HWPARAMS4 Register */ |
195 | #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) | 208 | #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) |
196 | #define DWC3_MAX_HIBER_SCRATCHBUFS 15 | 209 | #define DWC3_MAX_HIBER_SCRATCHBUFS 15 |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 07a736acd0f2..ef4936ff626c 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
@@ -77,10 +77,6 @@ | |||
77 | #define USBOTGSS_DEV_EBC_EN 0x0110 | 77 | #define USBOTGSS_DEV_EBC_EN 0x0110 |
78 | #define USBOTGSS_DEBUG_OFFSET 0x0600 | 78 | #define USBOTGSS_DEBUG_OFFSET 0x0600 |
79 | 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 */ | 80 | /* SYSCONFIG REGISTER */ |
85 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) | 81 | #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) |
86 | 82 | ||
@@ -129,7 +125,6 @@ struct dwc3_omap { | |||
129 | u32 irq_eoi_offset; | 125 | u32 irq_eoi_offset; |
130 | u32 debug_offset; | 126 | u32 debug_offset; |
131 | u32 irq0_offset; | 127 | u32 irq0_offset; |
132 | u32 revision; | ||
133 | 128 | ||
134 | u32 dma_status:1; | 129 | u32 dma_status:1; |
135 | 130 | ||
@@ -383,6 +378,87 @@ static int dwc3_omap_vbus_notifier(struct notifier_block *nb, | |||
383 | return NOTIFY_DONE; | 378 | return NOTIFY_DONE; |
384 | } | 379 | } |
385 | 380 | ||
381 | static void dwc3_omap_map_offset(struct dwc3_omap *omap) | ||
382 | { | ||
383 | struct device_node *node = omap->dev->of_node; | ||
384 | |||
385 | /* | ||
386 | * Differentiate between OMAP5 and AM437x. | ||
387 | * | ||
388 | * For OMAP5(ES2.0) and AM437x wrapper revision is same, even | ||
389 | * though there are changes in wrapper register offsets. | ||
390 | * | ||
391 | * Using dt compatible to differentiate AM437x. | ||
392 | */ | ||
393 | if (of_device_is_compatible(node, "ti,am437x-dwc3")) { | ||
394 | omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; | ||
395 | omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; | ||
396 | omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; | ||
397 | omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; | ||
398 | omap->debug_offset = USBOTGSS_DEBUG_OFFSET; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) | ||
403 | { | ||
404 | u32 reg; | ||
405 | struct device_node *node = omap->dev->of_node; | ||
406 | int utmi_mode = 0; | ||
407 | |||
408 | reg = dwc3_omap_read_utmi_status(omap); | ||
409 | |||
410 | of_property_read_u32(node, "utmi-mode", &utmi_mode); | ||
411 | |||
412 | switch (utmi_mode) { | ||
413 | case DWC3_OMAP_UTMI_MODE_SW: | ||
414 | reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
415 | break; | ||
416 | case DWC3_OMAP_UTMI_MODE_HW: | ||
417 | reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; | ||
418 | break; | ||
419 | default: | ||
420 | dev_dbg(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode); | ||
421 | } | ||
422 | |||
423 | dwc3_omap_write_utmi_status(omap, reg); | ||
424 | } | ||
425 | |||
426 | static int dwc3_omap_extcon_register(struct dwc3_omap *omap) | ||
427 | { | ||
428 | u32 ret; | ||
429 | struct device_node *node = omap->dev->of_node; | ||
430 | struct extcon_dev *edev; | ||
431 | |||
432 | if (of_property_read_bool(node, "extcon")) { | ||
433 | edev = extcon_get_edev_by_phandle(omap->dev, 0); | ||
434 | if (IS_ERR(edev)) { | ||
435 | dev_vdbg(omap->dev, "couldn't get extcon device\n"); | ||
436 | return -EPROBE_DEFER; | ||
437 | } | ||
438 | |||
439 | omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; | ||
440 | ret = extcon_register_interest(&omap->extcon_vbus_dev, | ||
441 | edev->name, "USB", | ||
442 | &omap->vbus_nb); | ||
443 | if (ret < 0) | ||
444 | dev_vdbg(omap->dev, "failed to register notifier for USB\n"); | ||
445 | |||
446 | omap->id_nb.notifier_call = dwc3_omap_id_notifier; | ||
447 | ret = extcon_register_interest(&omap->extcon_id_dev, | ||
448 | edev->name, "USB-HOST", | ||
449 | &omap->id_nb); | ||
450 | if (ret < 0) | ||
451 | dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n"); | ||
452 | |||
453 | if (extcon_get_cable_state(edev, "USB") == true) | ||
454 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); | ||
455 | if (extcon_get_cable_state(edev, "USB-HOST") == true) | ||
456 | dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
386 | static int dwc3_omap_probe(struct platform_device *pdev) | 462 | static int dwc3_omap_probe(struct platform_device *pdev) |
387 | { | 463 | { |
388 | struct device_node *node = pdev->dev.of_node; | 464 | struct device_node *node = pdev->dev.of_node; |
@@ -390,15 +466,11 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
390 | struct dwc3_omap *omap; | 466 | struct dwc3_omap *omap; |
391 | struct resource *res; | 467 | struct resource *res; |
392 | struct device *dev = &pdev->dev; | 468 | struct device *dev = &pdev->dev; |
393 | struct extcon_dev *edev; | ||
394 | struct regulator *vbus_reg = NULL; | 469 | struct regulator *vbus_reg = NULL; |
395 | 470 | ||
396 | int ret; | 471 | int ret; |
397 | int irq; | 472 | int irq; |
398 | 473 | ||
399 | int utmi_mode = 0; | ||
400 | int x_major; | ||
401 | |||
402 | u32 reg; | 474 | u32 reg; |
403 | 475 | ||
404 | void __iomem *base; | 476 | void __iomem *base; |
@@ -448,58 +520,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
448 | goto err0; | 520 | goto err0; |
449 | } | 521 | } |
450 | 522 | ||
451 | reg = dwc3_omap_readl(omap->base, USBOTGSS_REVISION); | 523 | dwc3_omap_map_offset(omap); |
452 | omap->revision = reg; | 524 | dwc3_omap_set_utmi_mode(omap); |
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 | 525 | ||
504 | /* check the DMA Status */ | 526 | /* check the DMA Status */ |
505 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); | 527 | reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); |
@@ -515,31 +537,9 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
515 | 537 | ||
516 | dwc3_omap_enable_irqs(omap); | 538 | dwc3_omap_enable_irqs(omap); |
517 | 539 | ||
518 | if (of_property_read_bool(node, "extcon")) { | 540 | ret = dwc3_omap_extcon_register(omap); |
519 | edev = extcon_get_edev_by_phandle(dev, 0); | 541 | if (ret < 0) |
520 | if (IS_ERR(edev)) { | 542 | goto err2; |
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 | 543 | ||
544 | ret = of_platform_populate(node, NULL, NULL, dev); | 544 | ret = of_platform_populate(node, NULL, NULL, dev); |
545 | if (ret) { | 545 | if (ret) { |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index dab7927d1009..349cacc577d8 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -1971,8 +1971,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1971 | } | 1971 | } |
1972 | 1972 | ||
1973 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | 1973 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, |
1974 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event, | 1974 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) |
1975 | int start_new) | ||
1976 | { | 1975 | { |
1977 | unsigned status = 0; | 1976 | unsigned status = 0; |
1978 | int clean_busy; | 1977 | int clean_busy; |
@@ -2039,7 +2038,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
2039 | return; | 2038 | return; |
2040 | } | 2039 | } |
2041 | 2040 | ||
2042 | dwc3_endpoint_transfer_complete(dwc, dep, event, 1); | 2041 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
2043 | break; | 2042 | break; |
2044 | case DWC3_DEPEVT_XFERINPROGRESS: | 2043 | case DWC3_DEPEVT_XFERINPROGRESS: |
2045 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 2044 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
@@ -2048,7 +2047,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
2048 | return; | 2047 | return; |
2049 | } | 2048 | } |
2050 | 2049 | ||
2051 | dwc3_endpoint_transfer_complete(dwc, dep, event, 0); | 2050 | dwc3_endpoint_transfer_complete(dwc, dep, event); |
2052 | break; | 2051 | break; |
2053 | case DWC3_DEPEVT_XFERNOTREADY: | 2052 | case DWC3_DEPEVT_XFERNOTREADY: |
2054 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 2053 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |