diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/sysfs.c | 54 | ||||
-rw-r--r-- | drivers/usb/host/xhci-dbg.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ext-caps.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 33 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 251 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 32 |
8 files changed, 309 insertions, 85 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index aa38db44818a..d9284b998bd7 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -497,8 +497,62 @@ set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, | |||
497 | static DEVICE_ATTR(usb2_hardware_lpm, S_IRUGO | S_IWUSR, show_usb2_hardware_lpm, | 497 | static DEVICE_ATTR(usb2_hardware_lpm, S_IRUGO | S_IWUSR, show_usb2_hardware_lpm, |
498 | set_usb2_hardware_lpm); | 498 | set_usb2_hardware_lpm); |
499 | 499 | ||
500 | static ssize_t | ||
501 | show_usb2_lpm_l1_timeout(struct device *dev, struct device_attribute *attr, | ||
502 | char *buf) | ||
503 | { | ||
504 | struct usb_device *udev = to_usb_device(dev); | ||
505 | return sprintf(buf, "%d\n", udev->l1_params.timeout); | ||
506 | } | ||
507 | |||
508 | static ssize_t | ||
509 | set_usb2_lpm_l1_timeout(struct device *dev, struct device_attribute *attr, | ||
510 | const char *buf, size_t count) | ||
511 | { | ||
512 | struct usb_device *udev = to_usb_device(dev); | ||
513 | u16 timeout; | ||
514 | |||
515 | if (kstrtou16(buf, 0, &timeout)) | ||
516 | return -EINVAL; | ||
517 | |||
518 | udev->l1_params.timeout = timeout; | ||
519 | |||
520 | return count; | ||
521 | } | ||
522 | |||
523 | static DEVICE_ATTR(usb2_lpm_l1_timeout, S_IRUGO | S_IWUSR, | ||
524 | show_usb2_lpm_l1_timeout, set_usb2_lpm_l1_timeout); | ||
525 | |||
526 | static ssize_t | ||
527 | show_usb2_lpm_besl(struct device *dev, struct device_attribute *attr, | ||
528 | char *buf) | ||
529 | { | ||
530 | struct usb_device *udev = to_usb_device(dev); | ||
531 | return sprintf(buf, "%d\n", udev->l1_params.besl); | ||
532 | } | ||
533 | |||
534 | static ssize_t | ||
535 | set_usb2_lpm_besl(struct device *dev, struct device_attribute *attr, | ||
536 | const char *buf, size_t count) | ||
537 | { | ||
538 | struct usb_device *udev = to_usb_device(dev); | ||
539 | u8 besl; | ||
540 | |||
541 | if (kstrtou8(buf, 0, &besl) || besl > 15) | ||
542 | return -EINVAL; | ||
543 | |||
544 | udev->l1_params.besl = besl; | ||
545 | |||
546 | return count; | ||
547 | } | ||
548 | |||
549 | static DEVICE_ATTR(usb2_lpm_besl, S_IRUGO | S_IWUSR, | ||
550 | show_usb2_lpm_besl, set_usb2_lpm_besl); | ||
551 | |||
500 | static struct attribute *usb2_hardware_lpm_attr[] = { | 552 | static struct attribute *usb2_hardware_lpm_attr[] = { |
501 | &dev_attr_usb2_hardware_lpm.attr, | 553 | &dev_attr_usb2_hardware_lpm.attr, |
554 | &dev_attr_usb2_lpm_l1_timeout.attr, | ||
555 | &dev_attr_usb2_lpm_besl.attr, | ||
502 | NULL, | 556 | NULL, |
503 | }; | 557 | }; |
504 | static struct attribute_group usb2_hardware_lpm_attr_group = { | 558 | static struct attribute_group usb2_hardware_lpm_attr_group = { |
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 5f3a7c74aa8d..f2e7689e11a3 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -503,11 +503,14 @@ static void xhci_dbg_ep_ctx(struct xhci_hcd *xhci, | |||
503 | if (last_ep < 31) | 503 | if (last_ep < 31) |
504 | last_ep_ctx = last_ep + 1; | 504 | last_ep_ctx = last_ep + 1; |
505 | for (i = 0; i < last_ep_ctx; ++i) { | 505 | for (i = 0; i < last_ep_ctx; ++i) { |
506 | unsigned int epaddr = xhci_get_endpoint_address(i); | ||
506 | struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i); | 507 | struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i); |
507 | dma_addr_t dma = ctx->dma + | 508 | dma_addr_t dma = ctx->dma + |
508 | ((unsigned long)ep_ctx - (unsigned long)ctx->bytes); | 509 | ((unsigned long)ep_ctx - (unsigned long)ctx->bytes); |
509 | 510 | ||
510 | xhci_dbg(xhci, "Endpoint %02d Context:\n", i); | 511 | xhci_dbg(xhci, "%s Endpoint %02d Context (ep_index %02d):\n", |
512 | usb_endpoint_out(epaddr) ? "OUT" : "IN", | ||
513 | epaddr & USB_ENDPOINT_NUMBER_MASK, i); | ||
511 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", | 514 | xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", |
512 | &ep_ctx->ep_info, | 515 | &ep_ctx->ep_info, |
513 | (unsigned long long)dma, ep_ctx->ep_info); | 516 | (unsigned long long)dma, ep_ctx->ep_info); |
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 377f4242dabb..8d7a1324e2f3 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h | |||
@@ -71,6 +71,7 @@ | |||
71 | 71 | ||
72 | /* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */ | 72 | /* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */ |
73 | #define XHCI_HLC (1 << 19) | 73 | #define XHCI_HLC (1 << 19) |
74 | #define XHCI_BLC (1 << 19) | ||
74 | 75 | ||
75 | /* command register values to disable interrupts and halt the HC */ | 76 | /* command register values to disable interrupts and halt the HC */ |
76 | /* start/stop HC execution - do not write unless HC is halted*/ | 77 | /* start/stop HC execution - do not write unless HC is halted*/ |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 187a3ec1069a..1d3545943c50 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -867,18 +867,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
867 | case USB_PORT_FEAT_U1_TIMEOUT: | 867 | case USB_PORT_FEAT_U1_TIMEOUT: |
868 | if (hcd->speed != HCD_USB3) | 868 | if (hcd->speed != HCD_USB3) |
869 | goto error; | 869 | goto error; |
870 | temp = xhci_readl(xhci, port_array[wIndex] + 1); | 870 | temp = xhci_readl(xhci, port_array[wIndex] + PORTPMSC); |
871 | temp &= ~PORT_U1_TIMEOUT_MASK; | 871 | temp &= ~PORT_U1_TIMEOUT_MASK; |
872 | temp |= PORT_U1_TIMEOUT(timeout); | 872 | temp |= PORT_U1_TIMEOUT(timeout); |
873 | xhci_writel(xhci, temp, port_array[wIndex] + 1); | 873 | xhci_writel(xhci, temp, port_array[wIndex] + PORTPMSC); |
874 | break; | 874 | break; |
875 | case USB_PORT_FEAT_U2_TIMEOUT: | 875 | case USB_PORT_FEAT_U2_TIMEOUT: |
876 | if (hcd->speed != HCD_USB3) | 876 | if (hcd->speed != HCD_USB3) |
877 | goto error; | 877 | goto error; |
878 | temp = xhci_readl(xhci, port_array[wIndex] + 1); | 878 | temp = xhci_readl(xhci, port_array[wIndex] + PORTPMSC); |
879 | temp &= ~PORT_U2_TIMEOUT_MASK; | 879 | temp &= ~PORT_U2_TIMEOUT_MASK; |
880 | temp |= PORT_U2_TIMEOUT(timeout); | 880 | temp |= PORT_U2_TIMEOUT(timeout); |
881 | xhci_writel(xhci, temp, port_array[wIndex] + 1); | 881 | xhci_writel(xhci, temp, port_array[wIndex] + PORTPMSC); |
882 | break; | 882 | break; |
883 | default: | 883 | default: |
884 | goto error; | 884 | goto error; |
@@ -1098,10 +1098,8 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
1098 | __le32 __iomem *addr; | 1098 | __le32 __iomem *addr; |
1099 | u32 tmp; | 1099 | u32 tmp; |
1100 | 1100 | ||
1101 | /* Add one to the port status register address to get | 1101 | /* Get the port power control register address. */ |
1102 | * the port power control register address. | 1102 | addr = port_array[port_index] + PORTPMSC; |
1103 | */ | ||
1104 | addr = port_array[port_index] + 1; | ||
1105 | tmp = xhci_readl(xhci, addr); | 1103 | tmp = xhci_readl(xhci, addr); |
1106 | tmp |= PORT_RWE; | 1104 | tmp |= PORT_RWE; |
1107 | xhci_writel(xhci, tmp, addr); | 1105 | xhci_writel(xhci, tmp, addr); |
@@ -1193,7 +1191,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
1193 | /* Add one to the port status register address to get | 1191 | /* Add one to the port status register address to get |
1194 | * the port power control register address. | 1192 | * the port power control register address. |
1195 | */ | 1193 | */ |
1196 | addr = port_array[port_index] + 1; | 1194 | addr = port_array[port_index] + PORTPMSC; |
1197 | tmp = xhci_readl(xhci, addr); | 1195 | tmp = xhci_readl(xhci, addr); |
1198 | tmp &= ~PORT_RWE; | 1196 | tmp &= ~PORT_RWE; |
1199 | xhci_writel(xhci, tmp, addr); | 1197 | xhci_writel(xhci, tmp, addr); |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 2cfc465925bd..832f05ede427 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1852,6 +1852,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1852 | kfree(xhci->usb3_ports); | 1852 | kfree(xhci->usb3_ports); |
1853 | kfree(xhci->port_array); | 1853 | kfree(xhci->port_array); |
1854 | kfree(xhci->rh_bw); | 1854 | kfree(xhci->rh_bw); |
1855 | kfree(xhci->ext_caps); | ||
1855 | 1856 | ||
1856 | xhci->page_size = 0; | 1857 | xhci->page_size = 0; |
1857 | xhci->page_shift = 0; | 1858 | xhci->page_shift = 0; |
@@ -2039,7 +2040,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | |||
2039 | } | 2040 | } |
2040 | 2041 | ||
2041 | static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, | 2042 | static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, |
2042 | __le32 __iomem *addr, u8 major_revision) | 2043 | __le32 __iomem *addr, u8 major_revision, int max_caps) |
2043 | { | 2044 | { |
2044 | u32 temp, port_offset, port_count; | 2045 | u32 temp, port_offset, port_count; |
2045 | int i; | 2046 | int i; |
@@ -2064,6 +2065,10 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, | |||
2064 | /* WTF? "Valid values are ‘1’ to MaxPorts" */ | 2065 | /* WTF? "Valid values are ‘1’ to MaxPorts" */ |
2065 | return; | 2066 | return; |
2066 | 2067 | ||
2068 | /* cache usb2 port capabilities */ | ||
2069 | if (major_revision < 0x03 && xhci->num_ext_caps < max_caps) | ||
2070 | xhci->ext_caps[xhci->num_ext_caps++] = temp; | ||
2071 | |||
2067 | /* Check the host's USB2 LPM capability */ | 2072 | /* Check the host's USB2 LPM capability */ |
2068 | if ((xhci->hci_version == 0x96) && (major_revision != 0x03) && | 2073 | if ((xhci->hci_version == 0x96) && (major_revision != 0x03) && |
2069 | (temp & XHCI_L1C)) { | 2074 | (temp & XHCI_L1C)) { |
@@ -2121,10 +2126,11 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, | |||
2121 | */ | 2126 | */ |
2122 | static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | 2127 | static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) |
2123 | { | 2128 | { |
2124 | __le32 __iomem *addr; | 2129 | __le32 __iomem *addr, *tmp_addr; |
2125 | u32 offset; | 2130 | u32 offset, tmp_offset; |
2126 | unsigned int num_ports; | 2131 | unsigned int num_ports; |
2127 | int i, j, port_index; | 2132 | int i, j, port_index; |
2133 | int cap_count = 0; | ||
2128 | 2134 | ||
2129 | addr = &xhci->cap_regs->hcc_params; | 2135 | addr = &xhci->cap_regs->hcc_params; |
2130 | offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); | 2136 | offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); |
@@ -2157,13 +2163,32 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
2157 | * See section 5.3.6 for offset calculation. | 2163 | * See section 5.3.6 for offset calculation. |
2158 | */ | 2164 | */ |
2159 | addr = &xhci->cap_regs->hc_capbase + offset; | 2165 | addr = &xhci->cap_regs->hc_capbase + offset; |
2166 | |||
2167 | tmp_addr = addr; | ||
2168 | tmp_offset = offset; | ||
2169 | |||
2170 | /* count extended protocol capability entries for later caching */ | ||
2171 | do { | ||
2172 | u32 cap_id; | ||
2173 | cap_id = xhci_readl(xhci, tmp_addr); | ||
2174 | if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) | ||
2175 | cap_count++; | ||
2176 | tmp_offset = XHCI_EXT_CAPS_NEXT(cap_id); | ||
2177 | tmp_addr += tmp_offset; | ||
2178 | } while (tmp_offset); | ||
2179 | |||
2180 | xhci->ext_caps = kzalloc(sizeof(*xhci->ext_caps) * cap_count, flags); | ||
2181 | if (!xhci->ext_caps) | ||
2182 | return -ENOMEM; | ||
2183 | |||
2160 | while (1) { | 2184 | while (1) { |
2161 | u32 cap_id; | 2185 | u32 cap_id; |
2162 | 2186 | ||
2163 | cap_id = xhci_readl(xhci, addr); | 2187 | cap_id = xhci_readl(xhci, addr); |
2164 | if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) | 2188 | if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) |
2165 | xhci_add_in_port(xhci, num_ports, addr, | 2189 | xhci_add_in_port(xhci, num_ports, addr, |
2166 | (u8) XHCI_EXT_PORT_MAJOR(cap_id)); | 2190 | (u8) XHCI_EXT_PORT_MAJOR(cap_id), |
2191 | cap_count); | ||
2167 | offset = XHCI_EXT_CAPS_NEXT(cap_id); | 2192 | offset = XHCI_EXT_CAPS_NEXT(cap_id); |
2168 | if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports) | 2193 | if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports) |
2169 | == num_ports) | 2194 | == num_ports) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 1969c001b3f9..e02b90746e84 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2799,7 +2799,7 @@ hw_died: | |||
2799 | return IRQ_HANDLED; | 2799 | return IRQ_HANDLED; |
2800 | } | 2800 | } |
2801 | 2801 | ||
2802 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) | 2802 | irqreturn_t xhci_msi_irq(int irq, void *hcd) |
2803 | { | 2803 | { |
2804 | return xhci_irq(hcd); | 2804 | return xhci_irq(hcd); |
2805 | } | 2805 | } |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b4aa79d154b2..8be34f838bd4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -218,7 +218,7 @@ static int xhci_setup_msi(struct xhci_hcd *xhci) | |||
218 | return ret; | 218 | return ret; |
219 | } | 219 | } |
220 | 220 | ||
221 | ret = request_irq(pdev->irq, (irq_handler_t)xhci_msi_irq, | 221 | ret = request_irq(pdev->irq, xhci_msi_irq, |
222 | 0, "xhci_hcd", xhci_to_hcd(xhci)); | 222 | 0, "xhci_hcd", xhci_to_hcd(xhci)); |
223 | if (ret) { | 223 | if (ret) { |
224 | xhci_dbg(xhci, "disable MSI interrupt\n"); | 224 | xhci_dbg(xhci, "disable MSI interrupt\n"); |
@@ -290,7 +290,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) | |||
290 | 290 | ||
291 | for (i = 0; i < xhci->msix_count; i++) { | 291 | for (i = 0; i < xhci->msix_count; i++) { |
292 | ret = request_irq(xhci->msix_entries[i].vector, | 292 | ret = request_irq(xhci->msix_entries[i].vector, |
293 | (irq_handler_t)xhci_msi_irq, | 293 | xhci_msi_irq, |
294 | 0, "xhci_hcd", xhci_to_hcd(xhci)); | 294 | 0, "xhci_hcd", xhci_to_hcd(xhci)); |
295 | if (ret) | 295 | if (ret) |
296 | goto disable_msix; | 296 | goto disable_msix; |
@@ -1111,6 +1111,16 @@ unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) | |||
1111 | return index; | 1111 | return index; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | /* The reverse operation to xhci_get_endpoint_index. Calculate the USB endpoint | ||
1115 | * address from the XHCI endpoint index. | ||
1116 | */ | ||
1117 | unsigned int xhci_get_endpoint_address(unsigned int ep_index) | ||
1118 | { | ||
1119 | unsigned int number = DIV_ROUND_UP(ep_index, 2); | ||
1120 | unsigned int direction = ep_index % 2 ? USB_DIR_OUT : USB_DIR_IN; | ||
1121 | return direction | number; | ||
1122 | } | ||
1123 | |||
1114 | /* Find the flag for this endpoint (for use in the control context). Use the | 1124 | /* Find the flag for this endpoint (for use in the control context). Use the |
1115 | * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is | 1125 | * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is |
1116 | * bit 1, etc. | 1126 | * bit 1, etc. |
@@ -3805,6 +3815,56 @@ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1) | |||
3805 | return raw_port; | 3815 | return raw_port; |
3806 | } | 3816 | } |
3807 | 3817 | ||
3818 | /* | ||
3819 | * Issue an Evaluate Context command to change the Maximum Exit Latency in the | ||
3820 | * slot context. If that succeeds, store the new MEL in the xhci_virt_device. | ||
3821 | */ | ||
3822 | static int xhci_change_max_exit_latency(struct xhci_hcd *xhci, | ||
3823 | struct usb_device *udev, u16 max_exit_latency) | ||
3824 | { | ||
3825 | struct xhci_virt_device *virt_dev; | ||
3826 | struct xhci_command *command; | ||
3827 | struct xhci_input_control_ctx *ctrl_ctx; | ||
3828 | struct xhci_slot_ctx *slot_ctx; | ||
3829 | unsigned long flags; | ||
3830 | int ret; | ||
3831 | |||
3832 | spin_lock_irqsave(&xhci->lock, flags); | ||
3833 | if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { | ||
3834 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
3835 | return 0; | ||
3836 | } | ||
3837 | |||
3838 | /* Attempt to issue an Evaluate Context command to change the MEL. */ | ||
3839 | virt_dev = xhci->devs[udev->slot_id]; | ||
3840 | command = xhci->lpm_command; | ||
3841 | xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx); | ||
3842 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
3843 | |||
3844 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | ||
3845 | ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); | ||
3846 | slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); | ||
3847 | slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); | ||
3848 | slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); | ||
3849 | |||
3850 | xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n"); | ||
3851 | xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id); | ||
3852 | xhci_dbg_ctx(xhci, command->in_ctx, 0); | ||
3853 | |||
3854 | /* Issue and wait for the evaluate context command. */ | ||
3855 | ret = xhci_configure_endpoint(xhci, udev, command, | ||
3856 | true, true); | ||
3857 | xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id); | ||
3858 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0); | ||
3859 | |||
3860 | if (!ret) { | ||
3861 | spin_lock_irqsave(&xhci->lock, flags); | ||
3862 | virt_dev->current_mel = max_exit_latency; | ||
3863 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
3864 | } | ||
3865 | return ret; | ||
3866 | } | ||
3867 | |||
3808 | #ifdef CONFIG_PM_RUNTIME | 3868 | #ifdef CONFIG_PM_RUNTIME |
3809 | 3869 | ||
3810 | /* BESL to HIRD Encoding array for USB2 LPM */ | 3870 | /* BESL to HIRD Encoding array for USB2 LPM */ |
@@ -3846,6 +3906,28 @@ static int xhci_calculate_hird_besl(struct xhci_hcd *xhci, | |||
3846 | return besl; | 3906 | return besl; |
3847 | } | 3907 | } |
3848 | 3908 | ||
3909 | /* Calculate BESLD, L1 timeout and HIRDM for USB2 PORTHLPMC */ | ||
3910 | static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev) | ||
3911 | { | ||
3912 | u32 field; | ||
3913 | int l1; | ||
3914 | int besld = 0; | ||
3915 | int hirdm = 0; | ||
3916 | |||
3917 | field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); | ||
3918 | |||
3919 | /* xHCI l1 is set in steps of 256us, xHCI 1.0 section 5.4.11.2 */ | ||
3920 | l1 = udev->l1_params.timeout / 256; | ||
3921 | |||
3922 | /* device has preferred BESLD */ | ||
3923 | if (field & USB_BESL_DEEP_VALID) { | ||
3924 | besld = USB_GET_BESL_DEEP(field); | ||
3925 | hirdm = 1; | ||
3926 | } | ||
3927 | |||
3928 | return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm); | ||
3929 | } | ||
3930 | |||
3849 | static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, | 3931 | static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, |
3850 | struct usb_device *udev) | 3932 | struct usb_device *udev) |
3851 | { | 3933 | { |
@@ -3901,7 +3983,7 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, | |||
3901 | * Check device's USB 2.0 extension descriptor to determine whether | 3983 | * Check device's USB 2.0 extension descriptor to determine whether |
3902 | * HIRD or BESL shoule be used. See USB2.0 LPM errata. | 3984 | * HIRD or BESL shoule be used. See USB2.0 LPM errata. |
3903 | */ | 3985 | */ |
3904 | pm_addr = port_array[port_num] + 1; | 3986 | pm_addr = port_array[port_num] + PORTPMSC; |
3905 | hird = xhci_calculate_hird_besl(xhci, udev); | 3987 | hird = xhci_calculate_hird_besl(xhci, udev); |
3906 | temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); | 3988 | temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); |
3907 | xhci_writel(xhci, temp, pm_addr); | 3989 | xhci_writel(xhci, temp, pm_addr); |
@@ -3978,11 +4060,12 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, | |||
3978 | { | 4060 | { |
3979 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 4061 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
3980 | __le32 __iomem **port_array; | 4062 | __le32 __iomem **port_array; |
3981 | __le32 __iomem *pm_addr; | 4063 | __le32 __iomem *pm_addr, *hlpm_addr; |
3982 | u32 temp; | 4064 | u32 pm_val, hlpm_val, field; |
3983 | unsigned int port_num; | 4065 | unsigned int port_num; |
3984 | unsigned long flags; | 4066 | unsigned long flags; |
3985 | int hird; | 4067 | int hird, exit_latency; |
4068 | int ret; | ||
3986 | 4069 | ||
3987 | if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || | 4070 | if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || |
3988 | !udev->lpm_capable) | 4071 | !udev->lpm_capable) |
@@ -3999,40 +4082,120 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, | |||
3999 | 4082 | ||
4000 | port_array = xhci->usb2_ports; | 4083 | port_array = xhci->usb2_ports; |
4001 | port_num = udev->portnum - 1; | 4084 | port_num = udev->portnum - 1; |
4002 | pm_addr = port_array[port_num] + 1; | 4085 | pm_addr = port_array[port_num] + PORTPMSC; |
4003 | temp = xhci_readl(xhci, pm_addr); | 4086 | pm_val = xhci_readl(xhci, pm_addr); |
4087 | hlpm_addr = port_array[port_num] + PORTHLPMC; | ||
4088 | field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); | ||
4004 | 4089 | ||
4005 | xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", | 4090 | xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", |
4006 | enable ? "enable" : "disable", port_num); | 4091 | enable ? "enable" : "disable", port_num); |
4007 | 4092 | ||
4008 | hird = xhci_calculate_hird_besl(xhci, udev); | ||
4009 | |||
4010 | if (enable) { | 4093 | if (enable) { |
4011 | temp &= ~PORT_HIRD_MASK; | 4094 | /* Host supports BESL timeout instead of HIRD */ |
4012 | temp |= PORT_HIRD(hird) | PORT_RWE; | 4095 | if (udev->usb2_hw_lpm_besl_capable) { |
4013 | xhci_writel(xhci, temp, pm_addr); | 4096 | /* if device doesn't have a preferred BESL value use a |
4014 | temp = xhci_readl(xhci, pm_addr); | 4097 | * default one which works with mixed HIRD and BESL |
4015 | temp |= PORT_HLE; | 4098 | * systems. See XHCI_DEFAULT_BESL definition in xhci.h |
4016 | xhci_writel(xhci, temp, pm_addr); | 4099 | */ |
4100 | if ((field & USB_BESL_SUPPORT) && | ||
4101 | (field & USB_BESL_BASELINE_VALID)) | ||
4102 | hird = USB_GET_BESL_BASELINE(field); | ||
4103 | else | ||
4104 | hird = udev->l1_params.besl; | ||
4105 | |||
4106 | exit_latency = xhci_besl_encoding[hird]; | ||
4107 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4108 | |||
4109 | /* USB 3.0 code dedicate one xhci->lpm_command->in_ctx | ||
4110 | * input context for link powermanagement evaluate | ||
4111 | * context commands. It is protected by hcd->bandwidth | ||
4112 | * mutex and is shared by all devices. We need to set | ||
4113 | * the max ext latency in USB 2 BESL LPM as well, so | ||
4114 | * use the same mutex and xhci_change_max_exit_latency() | ||
4115 | */ | ||
4116 | mutex_lock(hcd->bandwidth_mutex); | ||
4117 | ret = xhci_change_max_exit_latency(xhci, udev, | ||
4118 | exit_latency); | ||
4119 | mutex_unlock(hcd->bandwidth_mutex); | ||
4120 | |||
4121 | if (ret < 0) | ||
4122 | return ret; | ||
4123 | spin_lock_irqsave(&xhci->lock, flags); | ||
4124 | |||
4125 | hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev); | ||
4126 | xhci_writel(xhci, hlpm_val, hlpm_addr); | ||
4127 | /* flush write */ | ||
4128 | xhci_readl(xhci, hlpm_addr); | ||
4129 | } else { | ||
4130 | hird = xhci_calculate_hird_besl(xhci, udev); | ||
4131 | } | ||
4132 | |||
4133 | pm_val &= ~PORT_HIRD_MASK; | ||
4134 | pm_val |= PORT_HIRD(hird) | PORT_RWE; | ||
4135 | xhci_writel(xhci, pm_val, pm_addr); | ||
4136 | pm_val = xhci_readl(xhci, pm_addr); | ||
4137 | pm_val |= PORT_HLE; | ||
4138 | xhci_writel(xhci, pm_val, pm_addr); | ||
4139 | /* flush write */ | ||
4140 | xhci_readl(xhci, pm_addr); | ||
4017 | } else { | 4141 | } else { |
4018 | temp &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); | 4142 | pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); |
4019 | xhci_writel(xhci, temp, pm_addr); | 4143 | xhci_writel(xhci, pm_val, pm_addr); |
4144 | /* flush write */ | ||
4145 | xhci_readl(xhci, pm_addr); | ||
4146 | if (udev->usb2_hw_lpm_besl_capable) { | ||
4147 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4148 | mutex_lock(hcd->bandwidth_mutex); | ||
4149 | xhci_change_max_exit_latency(xhci, udev, 0); | ||
4150 | mutex_unlock(hcd->bandwidth_mutex); | ||
4151 | return 0; | ||
4152 | } | ||
4020 | } | 4153 | } |
4021 | 4154 | ||
4022 | spin_unlock_irqrestore(&xhci->lock, flags); | 4155 | spin_unlock_irqrestore(&xhci->lock, flags); |
4023 | return 0; | 4156 | return 0; |
4024 | } | 4157 | } |
4025 | 4158 | ||
4159 | /* check if a usb2 port supports a given extened capability protocol | ||
4160 | * only USB2 ports extended protocol capability values are cached. | ||
4161 | * Return 1 if capability is supported | ||
4162 | */ | ||
4163 | static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port, | ||
4164 | unsigned capability) | ||
4165 | { | ||
4166 | u32 port_offset, port_count; | ||
4167 | int i; | ||
4168 | |||
4169 | for (i = 0; i < xhci->num_ext_caps; i++) { | ||
4170 | if (xhci->ext_caps[i] & capability) { | ||
4171 | /* port offsets starts at 1 */ | ||
4172 | port_offset = XHCI_EXT_PORT_OFF(xhci->ext_caps[i]) - 1; | ||
4173 | port_count = XHCI_EXT_PORT_COUNT(xhci->ext_caps[i]); | ||
4174 | if (port >= port_offset && | ||
4175 | port < port_offset + port_count) | ||
4176 | return 1; | ||
4177 | } | ||
4178 | } | ||
4179 | return 0; | ||
4180 | } | ||
4181 | |||
4026 | int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) | 4182 | int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) |
4027 | { | 4183 | { |
4028 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 4184 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
4029 | int ret; | 4185 | int ret; |
4186 | int portnum = udev->portnum - 1; | ||
4030 | 4187 | ||
4031 | ret = xhci_usb2_software_lpm_test(hcd, udev); | 4188 | ret = xhci_usb2_software_lpm_test(hcd, udev); |
4032 | if (!ret) { | 4189 | if (!ret) { |
4033 | xhci_dbg(xhci, "software LPM test succeed\n"); | 4190 | xhci_dbg(xhci, "software LPM test succeed\n"); |
4034 | if (xhci->hw_lpm_support == 1) { | 4191 | if (xhci->hw_lpm_support == 1 && |
4192 | xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { | ||
4035 | udev->usb2_hw_lpm_capable = 1; | 4193 | udev->usb2_hw_lpm_capable = 1; |
4194 | udev->l1_params.timeout = XHCI_L1_TIMEOUT; | ||
4195 | udev->l1_params.besl = XHCI_DEFAULT_BESL; | ||
4196 | if (xhci_check_usb2_port_capability(xhci, portnum, | ||
4197 | XHCI_BLC)) | ||
4198 | udev->usb2_hw_lpm_besl_capable = 1; | ||
4036 | ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); | 4199 | ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); |
4037 | if (!ret) | 4200 | if (!ret) |
4038 | udev->usb2_hw_lpm_enabled = 1; | 4201 | udev->usb2_hw_lpm_enabled = 1; |
@@ -4363,56 +4526,6 @@ static u16 xhci_calculate_lpm_timeout(struct usb_hcd *hcd, | |||
4363 | return timeout; | 4526 | return timeout; |
4364 | } | 4527 | } |
4365 | 4528 | ||
4366 | /* | ||
4367 | * Issue an Evaluate Context command to change the Maximum Exit Latency in the | ||
4368 | * slot context. If that succeeds, store the new MEL in the xhci_virt_device. | ||
4369 | */ | ||
4370 | static int xhci_change_max_exit_latency(struct xhci_hcd *xhci, | ||
4371 | struct usb_device *udev, u16 max_exit_latency) | ||
4372 | { | ||
4373 | struct xhci_virt_device *virt_dev; | ||
4374 | struct xhci_command *command; | ||
4375 | struct xhci_input_control_ctx *ctrl_ctx; | ||
4376 | struct xhci_slot_ctx *slot_ctx; | ||
4377 | unsigned long flags; | ||
4378 | int ret; | ||
4379 | |||
4380 | spin_lock_irqsave(&xhci->lock, flags); | ||
4381 | if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { | ||
4382 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4383 | return 0; | ||
4384 | } | ||
4385 | |||
4386 | /* Attempt to issue an Evaluate Context command to change the MEL. */ | ||
4387 | virt_dev = xhci->devs[udev->slot_id]; | ||
4388 | command = xhci->lpm_command; | ||
4389 | xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx); | ||
4390 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4391 | |||
4392 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | ||
4393 | ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); | ||
4394 | slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); | ||
4395 | slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); | ||
4396 | slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); | ||
4397 | |||
4398 | xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n"); | ||
4399 | xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id); | ||
4400 | xhci_dbg_ctx(xhci, command->in_ctx, 0); | ||
4401 | |||
4402 | /* Issue and wait for the evaluate context command. */ | ||
4403 | ret = xhci_configure_endpoint(xhci, udev, command, | ||
4404 | true, true); | ||
4405 | xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id); | ||
4406 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0); | ||
4407 | |||
4408 | if (!ret) { | ||
4409 | spin_lock_irqsave(&xhci->lock, flags); | ||
4410 | virt_dev->current_mel = max_exit_latency; | ||
4411 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
4412 | } | ||
4413 | return ret; | ||
4414 | } | ||
4415 | |||
4416 | static int calculate_max_exit_latency(struct usb_device *udev, | 4529 | static int calculate_max_exit_latency(struct usb_device *udev, |
4417 | enum usb3_link_state state_changed, | 4530 | enum usb3_link_state state_changed, |
4418 | u16 hub_encoded_timeout) | 4531 | u16 hub_encoded_timeout) |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 29c978e37135..c306849eb299 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -132,6 +132,11 @@ struct xhci_cap_regs { | |||
132 | /* Number of registers per port */ | 132 | /* Number of registers per port */ |
133 | #define NUM_PORT_REGS 4 | 133 | #define NUM_PORT_REGS 4 |
134 | 134 | ||
135 | #define PORTSC 0 | ||
136 | #define PORTPMSC 1 | ||
137 | #define PORTLI 2 | ||
138 | #define PORTHLPMC 3 | ||
139 | |||
135 | /** | 140 | /** |
136 | * struct xhci_op_regs - xHCI Host Controller Operational Registers. | 141 | * struct xhci_op_regs - xHCI Host Controller Operational Registers. |
137 | * @command: USBCMD - xHC command register | 142 | * @command: USBCMD - xHC command register |
@@ -381,6 +386,27 @@ struct xhci_op_regs { | |||
381 | #define PORT_L1DS(p) (((p) & 0xff) << 8) | 386 | #define PORT_L1DS(p) (((p) & 0xff) << 8) |
382 | #define PORT_HLE (1 << 16) | 387 | #define PORT_HLE (1 << 16) |
383 | 388 | ||
389 | |||
390 | /* USB2 Protocol PORTHLPMC */ | ||
391 | #define PORT_HIRDM(p)((p) & 3) | ||
392 | #define PORT_L1_TIMEOUT(p)(((p) & 0xff) << 2) | ||
393 | #define PORT_BESLD(p)(((p) & 0xf) << 10) | ||
394 | |||
395 | /* use 512 microseconds as USB2 LPM L1 default timeout. */ | ||
396 | #define XHCI_L1_TIMEOUT 512 | ||
397 | |||
398 | /* Set default HIRD/BESL value to 4 (350/400us) for USB2 L1 LPM resume latency. | ||
399 | * Safe to use with mixed HIRD and BESL systems (host and device) and is used | ||
400 | * by other operating systems. | ||
401 | * | ||
402 | * XHCI 1.0 errata 8/14/12 Table 13 notes: | ||
403 | * "Software should choose xHC BESL/BESLD field values that do not violate a | ||
404 | * device's resume latency requirements, | ||
405 | * e.g. not program values > '4' if BLC = '1' and a HIRD device is attached, | ||
406 | * or not program values < '4' if BLC = '0' and a BESL device is attached. | ||
407 | */ | ||
408 | #define XHCI_DEFAULT_BESL 4 | ||
409 | |||
384 | /** | 410 | /** |
385 | * struct xhci_intr_reg - Interrupt Register Set | 411 | * struct xhci_intr_reg - Interrupt Register Set |
386 | * @irq_pending: IMAN - Interrupt Management Register. Used to enable | 412 | * @irq_pending: IMAN - Interrupt Management Register. Used to enable |
@@ -1532,6 +1558,9 @@ struct xhci_hcd { | |||
1532 | unsigned sw_lpm_support:1; | 1558 | unsigned sw_lpm_support:1; |
1533 | /* support xHCI 1.0 spec USB2 hardware LPM */ | 1559 | /* support xHCI 1.0 spec USB2 hardware LPM */ |
1534 | unsigned hw_lpm_support:1; | 1560 | unsigned hw_lpm_support:1; |
1561 | /* cached usb2 extened protocol capabilites */ | ||
1562 | u32 *ext_caps; | ||
1563 | unsigned int num_ext_caps; | ||
1535 | /* Compliance Mode Recovery Data */ | 1564 | /* Compliance Mode Recovery Data */ |
1536 | struct timer_list comp_mode_recovery_timer; | 1565 | struct timer_list comp_mode_recovery_timer; |
1537 | u32 port_status_u0; | 1566 | u32 port_status_u0; |
@@ -1641,6 +1670,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
1641 | void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, | 1670 | void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, |
1642 | struct usb_device *udev); | 1671 | struct usb_device *udev); |
1643 | unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); | 1672 | unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); |
1673 | unsigned int xhci_get_endpoint_address(unsigned int ep_index); | ||
1644 | unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc); | 1674 | unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc); |
1645 | unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index); | 1675 | unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index); |
1646 | unsigned int xhci_last_valid_endpoint(u32 added_ctxs); | 1676 | unsigned int xhci_last_valid_endpoint(u32 added_ctxs); |
@@ -1745,7 +1775,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated); | |||
1745 | 1775 | ||
1746 | int xhci_get_frame(struct usb_hcd *hcd); | 1776 | int xhci_get_frame(struct usb_hcd *hcd); |
1747 | irqreturn_t xhci_irq(struct usb_hcd *hcd); | 1777 | irqreturn_t xhci_irq(struct usb_hcd *hcd); |
1748 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd); | 1778 | irqreturn_t xhci_msi_irq(int irq, void *hcd); |
1749 | int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev); | 1779 | int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev); |
1750 | void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev); | 1780 | void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev); |
1751 | int xhci_alloc_tt_info(struct xhci_hcd *xhci, | 1781 | int xhci_alloc_tt_info(struct xhci_hcd *xhci, |