diff options
Diffstat (limited to 'drivers/usb')
38 files changed, 350 insertions, 141 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index f699abab1787..148f3ee70286 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
| @@ -19,6 +19,12 @@ config USB_EHCI_BIG_ENDIAN_MMIO | |||
| 19 | config USB_EHCI_BIG_ENDIAN_DESC | 19 | config USB_EHCI_BIG_ENDIAN_DESC |
| 20 | bool | 20 | bool |
| 21 | 21 | ||
| 22 | config USB_UHCI_BIG_ENDIAN_MMIO | ||
| 23 | bool | ||
| 24 | |||
| 25 | config USB_UHCI_BIG_ENDIAN_DESC | ||
| 26 | bool | ||
| 27 | |||
| 22 | menuconfig USB_SUPPORT | 28 | menuconfig USB_SUPPORT |
| 23 | bool "USB support" | 29 | bool "USB support" |
| 24 | depends on HAS_IOMEM | 30 | depends on HAS_IOMEM |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 06b3b54a0e68..7b366a6c0b49 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -174,6 +174,7 @@ static int acm_wb_alloc(struct acm *acm) | |||
| 174 | wb = &acm->wb[wbn]; | 174 | wb = &acm->wb[wbn]; |
| 175 | if (!wb->use) { | 175 | if (!wb->use) { |
| 176 | wb->use = 1; | 176 | wb->use = 1; |
| 177 | wb->len = 0; | ||
| 177 | return wbn; | 178 | return wbn; |
| 178 | } | 179 | } |
| 179 | wbn = (wbn + 1) % ACM_NW; | 180 | wbn = (wbn + 1) % ACM_NW; |
| @@ -805,16 +806,18 @@ static int acm_tty_write(struct tty_struct *tty, | |||
| 805 | static void acm_tty_flush_chars(struct tty_struct *tty) | 806 | static void acm_tty_flush_chars(struct tty_struct *tty) |
| 806 | { | 807 | { |
| 807 | struct acm *acm = tty->driver_data; | 808 | struct acm *acm = tty->driver_data; |
| 808 | struct acm_wb *cur = acm->putbuffer; | 809 | struct acm_wb *cur; |
| 809 | int err; | 810 | int err; |
| 810 | unsigned long flags; | 811 | unsigned long flags; |
| 811 | 812 | ||
| 813 | spin_lock_irqsave(&acm->write_lock, flags); | ||
| 814 | |||
| 815 | cur = acm->putbuffer; | ||
| 812 | if (!cur) /* nothing to do */ | 816 | if (!cur) /* nothing to do */ |
| 813 | return; | 817 | goto out; |
| 814 | 818 | ||
| 815 | acm->putbuffer = NULL; | 819 | acm->putbuffer = NULL; |
| 816 | err = usb_autopm_get_interface_async(acm->control); | 820 | err = usb_autopm_get_interface_async(acm->control); |
| 817 | spin_lock_irqsave(&acm->write_lock, flags); | ||
| 818 | if (err < 0) { | 821 | if (err < 0) { |
| 819 | cur->use = 0; | 822 | cur->use = 0; |
| 820 | acm->putbuffer = cur; | 823 | acm->putbuffer = cur; |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 4024926c1d68..f4a548471f0f 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -226,6 +226,9 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 226 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = | 226 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = |
| 227 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | 227 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, |
| 228 | 228 | ||
| 229 | /* Corsair K70 RGB */ | ||
| 230 | { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
| 231 | |||
| 229 | /* Corsair Strafe RGB */ | 232 | /* Corsair Strafe RGB */ |
| 230 | { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, | 233 | { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 231 | 234 | ||
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e4c3ce0de5de..5bcad1d869b5 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
| @@ -1917,7 +1917,9 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg, | |||
| 1917 | /* Not specific buffer needed for ep0 ZLP */ | 1917 | /* Not specific buffer needed for ep0 ZLP */ |
| 1918 | dma_addr_t dma = hs_ep->desc_list_dma; | 1918 | dma_addr_t dma = hs_ep->desc_list_dma; |
| 1919 | 1919 | ||
| 1920 | dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); | 1920 | if (!index) |
| 1921 | dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); | ||
| 1922 | |||
| 1921 | dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0); | 1923 | dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0); |
| 1922 | } else { | 1924 | } else { |
| 1923 | dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | | 1925 | dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | |
| @@ -2974,9 +2976,13 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, | |||
| 2974 | if (ints & DXEPINT_STSPHSERCVD) { | 2976 | if (ints & DXEPINT_STSPHSERCVD) { |
| 2975 | dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__); | 2977 | dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__); |
| 2976 | 2978 | ||
| 2977 | /* Move to STATUS IN for DDMA */ | 2979 | /* Safety check EP0 state when STSPHSERCVD asserted */ |
| 2978 | if (using_desc_dma(hsotg)) | 2980 | if (hsotg->ep0_state == DWC2_EP0_DATA_OUT) { |
| 2979 | dwc2_hsotg_ep0_zlp(hsotg, true); | 2981 | /* Move to STATUS IN for DDMA */ |
| 2982 | if (using_desc_dma(hsotg)) | ||
| 2983 | dwc2_hsotg_ep0_zlp(hsotg, true); | ||
| 2984 | } | ||
| 2985 | |||
| 2980 | } | 2986 | } |
| 2981 | 2987 | ||
| 2982 | if (ints & DXEPINT_BACK2BACKSETUP) | 2988 | if (ints & DXEPINT_BACK2BACKSETUP) |
| @@ -3375,12 +3381,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, | |||
| 3375 | dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | | 3381 | dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | |
| 3376 | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); | 3382 | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); |
| 3377 | 3383 | ||
| 3378 | dwc2_hsotg_enqueue_setup(hsotg); | ||
| 3379 | |||
| 3380 | dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
| 3381 | dwc2_readl(hsotg->regs + DIEPCTL0), | ||
| 3382 | dwc2_readl(hsotg->regs + DOEPCTL0)); | ||
| 3383 | |||
| 3384 | /* clear global NAKs */ | 3384 | /* clear global NAKs */ |
| 3385 | val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; | 3385 | val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; |
| 3386 | if (!is_usb_reset) | 3386 | if (!is_usb_reset) |
| @@ -3391,6 +3391,12 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, | |||
| 3391 | mdelay(3); | 3391 | mdelay(3); |
| 3392 | 3392 | ||
| 3393 | hsotg->lx_state = DWC2_L0; | 3393 | hsotg->lx_state = DWC2_L0; |
| 3394 | |||
| 3395 | dwc2_hsotg_enqueue_setup(hsotg); | ||
| 3396 | |||
| 3397 | dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", | ||
| 3398 | dwc2_readl(hsotg->regs + DIEPCTL0), | ||
| 3399 | dwc2_readl(hsotg->regs + DOEPCTL0)); | ||
| 3394 | } | 3400 | } |
| 3395 | 3401 | ||
| 3396 | static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) | 3402 | static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ade2ab00d37a..f1d838a4acd6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
| @@ -100,6 +100,8 @@ static void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) | |||
| 100 | reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); | 100 | reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); |
| 101 | reg |= DWC3_GCTL_PRTCAPDIR(mode); | 101 | reg |= DWC3_GCTL_PRTCAPDIR(mode); |
| 102 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 102 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
| 103 | |||
| 104 | dwc->current_dr_role = mode; | ||
| 103 | } | 105 | } |
| 104 | 106 | ||
| 105 | static void __dwc3_set_mode(struct work_struct *work) | 107 | static void __dwc3_set_mode(struct work_struct *work) |
| @@ -133,8 +135,6 @@ static void __dwc3_set_mode(struct work_struct *work) | |||
| 133 | 135 | ||
