diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
| -rw-r--r-- | drivers/usb/host/xhci.c | 92 |
1 files changed, 49 insertions, 43 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index a148a1280126..02c9bfe21ae2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -41,6 +41,19 @@ static unsigned long long quirks; module_param(quirks, ullong, S_IRUGO); MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); +void xhci_portsc_writel(struct xhci_port *port, u32 val) +{ + trace_xhci_portsc_writel(port, val); + writel(val, &port->port_reg->portsc); +} +EXPORT_SYMBOL_GPL(xhci_portsc_writel); + +u32 xhci_portsc_readl(struct xhci_port *port) +{ + return readl(&port->port_reg->portsc); +} +EXPORT_SYMBOL_GPL(xhci_portsc_readl); + static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring) { struct xhci_segment *seg; @@ -237,7 +250,6 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) struct iommu_domain *domain; int err, i; u64 val; - u32 intrs; /* * Some Renesas controllers get into a weird state if they are @@ -278,10 +290,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) if (upper_32_bits(val)) xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); - intrs = min_t(u32, HCS_MAX_INTRS(xhci->hcs_params1), - ARRAY_SIZE(xhci->run_regs->ir_set)); - - for (i = 0; i < intrs; i++) { + for (i = 0; i < xhci->max_interrupters; i++) { struct xhci_intr_reg __iomem *ir; ir = &xhci->run_regs->ir_set[i]; @@ -373,7 +382,7 @@ static void compliance_mode_recovery(struct timer_list *t) return; for (i = 0; i < rhub->num_ports; i++) { - temp = readl(rhub->ports[i]->addr); + temp = xhci_portsc_readl(rhub->ports[i]); if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { /* * Compliance Mode Detected. Letting USB Core @@ -471,15 +480,13 @@ static void xhci_hcd_page_size(struct xhci_hcd *xhci) static void xhci_enable_max_dev_slots(struct xhci_hcd *xhci) { u32 config_reg; - u32 max_slots; - max_slots = HCS_MAX_SLOTS(xhci->hcs_params1); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xHC can handle at most %d device slots", - max_slots); + xhci->max_slots); config_reg = readl(&xhci->op_regs->config_reg); config_reg &= ~HCS_SLOTS_MASK; - config_reg |= max_slots; + config_reg |= xhci->max_slots; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Setting Max device slots reg = 0x%x", config_reg); @@ -896,7 +903,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci, spin_lock_irqsave(&xhci->lock, flags); for (i = 0; i < rhub->num_ports; i++) { - portsc = readl(rhub->ports[i]->addr); + portsc = xhci_portsc_readl(rhub->ports[i]); t1 = xhci_port_state_to_neutral(portsc); t2 = t1; @@ -909,7 +916,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci, t2 |= PORT_CSC; if (t1 != t2) { - writel(t2, rhub->ports[i]->addr); + xhci_portsc_writel(rhub->ports[i], t2); xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n", rhub->hcd->self.busnum, i + 1, portsc, t2); } @@ -936,7 +943,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci) port_index = xhci->usb2_rhub.num_ports; ports = xhci->usb2_rhub.ports; while (port_index--) { - portsc = readl(ports[port_index]->addr); + portsc = xhci_portsc_readl(ports[port_index]); if (portsc & PORT_CHANGE_MASK || (portsc & PORT_PLS_MASK) == XDEV_RESUME) return true; @@ -944,7 +951,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci) port_index = xhci->usb3_rhub.num_ports; ports = xhci->usb3_rhub.ports; while (port_index--) { - portsc = readl(ports[port_index]->addr); + portsc = xhci_portsc_readl(ports[port_index]); if (portsc & (PORT_CHANGE_MASK | PORT_CAS) || (portsc & PORT_PLS_MASK) == XDEV_RESUME) return true; @@ -4223,8 +4230,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) xhci_err(xhci, "Error while assigning device slot ID: %s\n", xhci_trb_comp_code_string(command->status)); xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", - HCS_MAX_SLOTS( - readl(&xhci->cap_regs->hcs_params1))); + xhci->max_slots); xhci_free_command(xhci, command); return 0; } @@ -4367,8 +4373,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); ctrl_ctx->drop_flags = 0; - trace_xhci_address_ctx(xhci, virt_dev->in_ctx, - le32_to_cpu(slot_ctx->dev_info) >> 27); + trace_xhci_address_ctx(xhci, virt_dev->in_ctx); trace_xhci_address_ctrl_ctx(ctrl_ctx); spin_lock_irqsave(&xhci->lock, flags); @@ -4428,7 +4433,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, xhci_err(xhci, "ERROR: unexpected setup %s command completion code 0x%x.\n", act, command->status); - trace_xhci_address_ctx(xhci, virt_dev->out_ctx, 1); + trace_xhci_address_ctx(xhci, virt_dev->out_ctx); ret = -EINVAL; break; } @@ -4446,14 +4451,12 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Output Context DMA address = %#08llx", (unsigned long long)virt_dev->out_ctx->dma); - trace_xhci_address_ctx(xhci, virt_dev->in_ctx, - le32_to_cpu(slot_ctx->dev_info) >> 27); + trace_xhci_address_ctx(xhci, virt_dev->in_ctx); /* * USB core uses address 1 for the roothubs, so we add one to the * address given back to us by the HC. */ - trace_xhci_address_ctx(xhci, virt_dev->out_ctx, - le32_to_cpu(slot_ctx->dev_info) >> 27); + trace_xhci_address_ctx(xhci, virt_dev->out_ctx); /* Zero the input context control for later use */ ctrl_ctx->add_flags = 0; ctrl_ctx->drop_flags = 0; @@ -4637,7 +4640,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_port **ports; - __le32 __iomem *pm_addr, *hlpm_addr; + struct xhci_port_regs __iomem *port_reg; u32 pm_val, hlpm_val, field; unsigned int port_num; unsigned long flags; @@ -4662,9 +4665,8 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, ports = xhci->usb2_rhub.ports; port_num = udev->portnum - 1; - pm_addr = ports[port_num]->addr + PORTPMSC; - pm_val = readl(pm_addr); - hlpm_addr = ports[port_num]->addr + PORTHLPMC; + port_reg = ports[port_num]->port_reg; + pm_val = readl(&port_reg->portpmsc); xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", str_enable_disable(enable), port_num + 1); @@ -4693,30 +4695,30 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, spin_lock_irqsave(&xhci->lock, flags); hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev); - writel(hlpm_val, hlpm_addr); + writel(hlpm_val, &port_reg->porthlmpc); /* flush write */ - readl(hlpm_addr); + readl(&port_reg->porthlmpc); } else { hird = xhci_calculate_hird_besl(xhci, udev); } pm_val &= ~PORT_HIRD_MASK; pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id); - writel(pm_val, pm_addr); - pm_val = readl(pm_addr); + writel(pm_val, &port_reg->portpmsc); + pm_val = readl(&port_reg->portpmsc); pm_val |= PORT_HLE; - writel(pm_val, pm_addr); + writel(pm_val, &port_reg->portpmsc); /* flush write */ - readl(pm_addr); + readl(&port_reg->portpmsc); } else { pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK); - writel(pm_val, pm_addr); + writel(pm_val, &port_reg->portpmsc); /* flush write */ - readl(pm_addr); + readl(&port_reg->portpmsc); if (udev->usb2_hw_lpm_besl_capable) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_change_max_exit_latency(xhci, udev, 0); - readl_poll_timeout(ports[port_num]->addr, pm_val, + readl_poll_timeout(&ports[port_num]->port_reg->portsc, pm_val, (pm_val & PORT_PLS_MASK) == XDEV_U0, 100, 10000); return 0; @@ -5409,6 +5411,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) */ struct device *dev = hcd->self.sysdev; int retval; + u32 hcs_params1; /* Accept arbitrarily long scatter-gather lists */ hcd->self.sg_tablesize = ~0; @@ -5434,7 +5437,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) xhci->run_regs = hcd->regs + (readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK); /* Cache read-only capability registers */ - xhci->hcs_params1 = readl(&xhci->cap_regs->hcs_params1); + hcs_params1 = readl(&xhci->cap_regs->hcs_params1); xhci->hcs_params2 = readl(&xhci->cap_regs->hcs_params2); xhci->hcs_params3 = readl(&xhci->cap_regs->hcs_params3); xhci->hci_version = HC_VERSION(readl(&xhci->cap_regs->hc_capbase)); @@ -5442,10 +5445,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) if (xhci->hci_version > 0x100) xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2); + xhci->max_slots = HCS_MAX_SLOTS(hcs_params1); + xhci->max_ports = min(HCS_MAX_PORTS(hcs_params1), MAX_HC_PORTS); /* xhci-plat or xhci-pci might have set max_interrupters already */ - if ((!xhci->max_interrupters) || - xhci->max_interrupters > HCS_MAX_INTRS(xhci->hcs_params1)) - xhci->max_interrupters = HCS_MAX_INTRS(xhci->hcs_params1); + if (!xhci->max_interrupters) + xhci->max_interrupters = min(HCS_MAX_INTRS(hcs_params1), MAX_HC_INTRS); + else if (xhci->max_interrupters > HCS_MAX_INTRS(hcs_params1)) + xhci->max_interrupters = HCS_MAX_INTRS(hcs_params1); xhci->quirks |= quirks; @@ -5490,7 +5496,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* Set dma_mask and coherent_dma_mask to 64-bits, * if xHC supports 64-bit addressing */ - if (HCC_64BIT_ADDR(xhci->hcc_params) && + if ((xhci->hcc_params & HCC_64BIT_ADDR) && !dma_set_mask(dev, DMA_BIT_MASK(64))) { xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); @@ -5664,8 +5670,8 @@ static int __init xhci_hcd_init(void) BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 8*32/8); BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); - /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ - BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); + /* xhci_run_regs has eight fields and embeds 1024 xhci_intr_regs */ + BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*1024)*32/8); if (usb_disabled()) return -ENODEV; |
