diff options
Diffstat (limited to 'drivers/usb/host')
| -rw-r--r-- | drivers/usb/host/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-pmcmsp.c | 40 | ||||
| -rw-r--r-- | drivers/usb/host/pci-quirks.c | 19 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-hub.c | 7 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 9 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 10 |
6 files changed, 35 insertions, 52 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 61b7817bd66..03314f861be 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -176,7 +176,7 @@ config USB_EHCI_HCD_AT91 config USB_EHCI_MSM tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" - depends on ARCH_MSM + depends on ARCH_MSM || ARCH_QCOM select USB_EHCI_ROOT_HUB_TT ---help--- Enables support for the USB Host controller present on the diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index af3974a5e7c..7d75465d97c 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -68,9 +68,6 @@ static void usb_hcd_tdi_set_mode(struct ehci_hcd *ehci) /* set TWI GPIO USB_HOST_DEV pin high */ gpio_direction_output(MSP_PIN_USB0_HOST_DEV, 1); -#ifdef CONFIG_MSP_HAS_DUAL_USB - gpio_direction_output(MSP_PIN_USB1_HOST_DEV, 1); -#endif } /* called during probe() after chip reset completes */ @@ -248,33 +245,6 @@ void usb_hcd_msp_remove(struct usb_hcd *hcd, struct platform_device *dev) usb_put_hcd(hcd); } -#ifdef CONFIG_MSP_HAS_DUAL_USB -/* - * Wrapper around the main ehci_irq. Since both USB host controllers are - * sharing the same IRQ, need to first determine whether we're the intended - * recipient of this interrupt. - */ -static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd) -{ - u32 int_src; - struct device *dev = hcd->self.controller; - struct platform_device *pdev; - struct mspusb_device *mdev; - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - /* need to reverse-map a couple of containers to get our device */ - pdev = to_platform_device(dev); - mdev = to_mspusb_device(pdev); - - /* Check to see if this interrupt is for this host controller */ - int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat); - if (int_src & (1 << pdev->id)) - return ehci_irq(hcd); - - /* Not for this device */ - return IRQ_NONE; -} -#endif /* DUAL_USB */ - static const struct hc_driver ehci_msp_hc_driver = { .description = hcd_name, .product_desc = "PMC MSP EHCI", @@ -283,11 +253,7 @@ static const struct hc_driver ehci_msp_hc_driver = { /* * generic hardware linkage */ -#ifdef CONFIG_MSP_HAS_DUAL_USB - .irq = ehci_msp_irq, -#else .irq = ehci_irq, -#endif .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, /* @@ -334,9 +300,6 @@ static int ehci_hcd_msp_drv_probe(struct platform_device *pdev) return -ENODEV; gpio_request(MSP_PIN_USB0_HOST_DEV, "USB0_HOST_DEV_GPIO"); -#ifdef CONFIG_MSP_HAS_DUAL_USB - gpio_request(MSP_PIN_USB1_HOST_DEV, "USB1_HOST_DEV_GPIO"); -#endif ret = usb_hcd_msp_probe(&ehci_msp_hc_driver, pdev); @@ -351,9 +314,6 @@ static int ehci_hcd_msp_drv_remove(struct platform_device *pdev) /* free TWI GPIO USB_HOST_DEV pin */ gpio_free(MSP_PIN_USB0_HOST_DEV); -#ifdef CONFIG_MSP_HAS_DUAL_USB - gpio_free(MSP_PIN_USB1_HOST_DEV); -#endif return 0; } diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 4a6d3dd6857..2f3acebb577 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -656,6 +656,14 @@ static const struct dmi_system_id ehci_dmi_nohandoff_table[] = { DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), }, }, + { + /* HASEE E200 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HASEE"), + DMI_MATCH(DMI_BOARD_NAME, "E210"), + DMI_MATCH(DMI_BIOS_VERSION, "6.00"), + }, + }, { } }; @@ -665,9 +673,14 @@ static void ehci_bios_handoff(struct pci_dev *pdev, { int try_handoff = 1, tried_handoff = 0; - /* The Pegatron Lucid tablet sporadically waits for 98 seconds trying - * the handoff on its unused controller. Skip it. */ - if (pdev->vendor == 0x8086 && pdev->device == 0x283a) { + /* + * The Pegatron Lucid tablet sporadically waits for 98 seconds trying + * the handoff on its unused controller. Skip it. + * + * The HASEE E200 hangs when the semaphore is set (bugzilla #77021). + */ + if (pdev->vendor == 0x8086 && (pdev->device == 0x283a || + pdev->device == 0x27cc)) { if (dmi_check_system(ehci_dmi_nohandoff_table)) try_handoff = 0; } diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 6231ce6aa0c..aa79e874904 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -22,6 +22,7 @@ #include <linux/slab.h> +#include <linux/device.h> #include <asm/unaligned.h> #include "xhci.h" @@ -287,7 +288,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) { struct xhci_command *command; command = xhci_alloc_command(xhci, false, false, - GFP_NOIO); + GFP_NOWAIT); if (!command) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_free_command(xhci, cmd); @@ -1139,7 +1140,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd) * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME * is enabled, so also enable remote wake here. */ - if (hcd->self.root_hub->do_remote_wakeup) { + if (hcd->self.root_hub->do_remote_wakeup + && device_may_wakeup(hcd->self.controller)) { + if (t1 & PORT_CONNECT) { t2 |= PORT_WKOC_E | PORT_WKDISC_E; t2 &= ~PORT_WKCONN_E; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d67ff71209f..749fc68eb5c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1433,8 +1433,11 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code); break; case TRB_RESET_DEV: - WARN_ON(slot_id != TRB_TO_SLOT_ID( - le32_to_cpu(cmd_trb->generic.field[3]))); + /* SLOT_ID field in reset device cmd completion event TRB is 0. + * Use the SLOT_ID from the command TRB instead (xhci 4.6.11) + */ + slot_id = TRB_TO_SLOT_ID( + le32_to_cpu(cmd_trb->generic.field[3])); xhci_handle_cmd_reset_dev(xhci, slot_id, event); break; case TRB_NEC_GET_FW: @@ -3534,7 +3537,7 @@ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci, return 0; max_burst = urb->ep->ss_ep_comp.bMaxBurst; - return roundup(total_packet_count, max_burst + 1) - 1; + return DIV_ROUND_UP(total_packet_count, max_burst + 1) - 1; } /* diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2b8d9a24af0..7436d5f5e67 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -936,7 +936,7 @@ int xhci_suspend(struct xhci_hcd *xhci) */ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) { - u32 command, temp = 0; + u32 command, temp = 0, status; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; int retval = 0; @@ -1054,8 +1054,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) done: if (retval == 0) { - usb_hcd_resume_root_hub(hcd); - usb_hcd_resume_root_hub(xhci->shared_hcd); + /* Resume root hubs only when have pending events. */ + status = readl(&xhci->op_regs->status); + if (status & STS_EINT) { + usb_hcd_resume_root_hub(hcd); + usb_hcd_resume_root_hub(xhci->shared_hcd); + } } /* |
