The ir_set registers are per-event ring, so it makes sense to move the pointer in here for when we have multiple event rings. Signed-off-by: Matthew Wilcox <matthew.r.wilcox@xxxxxxxxx> --- drivers/usb/host/xhci-mem.c | 22 +++++++++++----------- drivers/usb/host/xhci-ring.c | 12 ++++++------ drivers/usb/host/xhci.c | 42 +++++++++++++++++++++--------------------- drivers/usb/host/xhci.h | 3 +-- 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index a1ca531..2ad7443 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1485,10 +1485,10 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) int i; /* Free the Event Ring Segment Table and the actual Event Ring */ - if (xhci->ir_set) { - xhci_writel(xhci, 0, &xhci->ir_set->erst_size); - xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); - xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); + if (xhci->erst.ir_set) { + xhci_writel(xhci, 0, &xhci->erst.ir_set->erst_size); + xhci_write_64(xhci, 0, &xhci->erst.ir_set->erst_base); + xhci_write_64(xhci, 0, &xhci->erst.ir_set->erst_dequeue); } size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); if (xhci->erst.entries) @@ -1717,7 +1717,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) xhci_warn(xhci, "WARN something wrong with SW event ring " "dequeue ptr.\n"); /* Update HC event ring dequeue pointer */ - temp = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp = xhci_read_64(xhci, &xhci->erst.ir_set->erst_dequeue); temp &= ERST_PTR_MASK; /* Don't clear the EHB bit (which is RW1C) because * there might be more events to service. @@ -1726,7 +1726,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) xhci_dbg(xhci, "// Write event ring dequeue pointer, " "preserving EHB bit\n"); xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp, - &xhci->ir_set->erst_dequeue); + &xhci->erst.ir_set->erst_dequeue); } static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, @@ -2017,7 +2017,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) xhci_dbg_regs(xhci); xhci_print_run_regs(xhci); /* Set ir_set to interrupt register set 0 */ - xhci->ir_set = &xhci->run_regs->ir_set[0]; + xhci->erst.ir_set = &xhci->run_regs->ir_set[0]; /* * Event ring setup: Allocate a normal ring, but also setup @@ -2055,21 +2055,21 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) } /* set ERST count with the number of entries in the segment table */ - val = xhci_readl(xhci, &xhci->ir_set->erst_size); + val = xhci_readl(xhci, &xhci->erst.ir_set->erst_size); val &= ERST_SIZE_MASK; val |= ERST_NUM_SEGS; xhci_dbg(xhci, "// Write ERST size = %i to ir_set 0 (some bits preserved)\n", val); - xhci_writel(xhci, val, &xhci->ir_set->erst_size); + xhci_writel(xhci, val, &xhci->erst.ir_set->erst_size); xhci_dbg(xhci, "// Set ERST entries to point to event ring.\n"); /* set the segment table base address */ xhci_dbg(xhci, "// Set ERST base address for ir_set 0 = 0x%llx\n", (unsigned long long)xhci->erst.erst_dma_addr); - val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base); + val_64 = xhci_read_64(xhci, &xhci->erst.ir_set->erst_base); val_64 &= ERST_PTR_MASK; val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); - xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base); + xhci_write_64(xhci, val_64, &xhci->erst.ir_set->erst_base); /* Set the event ring dequeue address */ xhci_set_hc_event_deq(xhci); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 05dfdfa..92e9b5c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2289,9 +2289,9 @@ hw_died: if (hcd->irq != -1) { u32 irq_pending; /* Acknowledge the PCI interrupt */ - irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); + irq_pending = xhci_readl(xhci, &xhci->erst.ir_set->irq_pending); irq_pending |= 0x3; - xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); + xhci_writel(xhci, irq_pending, &xhci->erst.ir_set->irq_pending); } if (xhci->xhc_state & XHCI_STATE_DYING) { @@ -2300,9 +2300,9 @@ hw_died: /* Clear the event handler busy flag (RW1C); * the event ring should be empty. */ - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 = xhci_read_64(xhci, &xhci->erst.ir_set->erst_dequeue); xhci_write_64(xhci, temp_64 | ERST_EHB, - &xhci->ir_set->erst_dequeue); + &xhci->erst.ir_set->erst_dequeue); spin_unlock(&xhci->lock); return IRQ_HANDLED; @@ -2314,7 +2314,7 @@ hw_died: */ while (xhci_handle_event(xhci) > 0) {} - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 = xhci_read_64(xhci, &xhci->erst.ir_set->erst_dequeue); /* If necessary, update the HW's version of the event ring deq ptr. */ if (event_ring_deq != xhci->erst.ring->dequeue) { deq = xhci_trb_virt_to_dma(xhci->erst.ring->deq_seg, @@ -2329,7 +2329,7 @@ hw_died: /* Clear the event handler busy flag (RW1C); event ring is empty. */ temp_64 |= ERST_EHB; - xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue); + xhci_write_64(xhci, temp_64, &xhci->erst.ir_set->erst_dequeue); spin_unlock(&xhci->lock); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7035797..94c2000 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -351,14 +351,14 @@ static void xhci_event_ring_work(unsigned long arg) return; } - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + temp = xhci_readl(xhci, &xhci->erst.ir_set->irq_pending); xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); xhci->error_bitmask = 0; xhci_dbg(xhci, "Event ring:\n"); xhci_debug_segment(xhci, xhci->erst.ring->deq_seg); xhci_dbg_ring_ptrs(xhci, xhci->erst.ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 = xhci_read_64(xhci, &xhci->erst.ir_set->erst_dequeue); temp_64 &= ~ERST_PTR_MASK; xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); xhci_dbg(xhci, "Command ring:\n"); @@ -468,15 +468,15 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg(xhci, "Event ring:\n"); xhci_debug_ring(xhci, xhci->erst.ring); xhci_dbg_ring_ptrs(xhci, xhci->erst.ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 = xhci_read_64(xhci, &xhci->erst.ir_set->erst_dequeue); temp_64 &= ~ERST_PTR_MASK; xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); xhci_dbg(xhci, "// Set the interrupt modulation register\n"); - temp = xhci_readl(xhci, &xhci->ir_set->irq_control); + temp = xhci_readl(xhci, &xhci->erst.ir_set->irq_control); temp &= ~ER_IRQ_INTERVAL_MASK; temp |= (u32) 160; - xhci_writel(xhci, temp, &xhci->ir_set->irq_control); + xhci_writel(xhci, temp, &xhci->erst.ir_set->irq_control); /* Set the HCD state before we enable the irqs */ temp = xhci_readl(xhci, &xhci->op_regs->command); @@ -485,11 +485,11 @@ int xhci_run(struct usb_hcd *hcd) temp); xhci_writel(xhci, temp, &xhci->op_regs->command); - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + temp = xhci_readl(xhci, &xhci->erst.ir_set->irq_pending); xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", - xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); + xhci->erst.ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); xhci_writel(xhci, ER_IRQ_ENABLE(temp), - &xhci->ir_set->irq_pending); + &xhci->erst.ir_set->irq_pending); xhci_print_ir_set(xhci, 0); if (xhci->quirks & XHCI_NEC_HOST) @@ -556,9 +556,9 @@ void xhci_stop(struct usb_hcd *hcd) xhci_dbg(xhci, "// Disabling event ring interrupts\n"); temp = xhci_readl(xhci, &xhci->op_regs->status); xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + temp = xhci_readl(xhci, &xhci->erst.ir_set->irq_pending); xhci_writel(xhci, ER_IRQ_DISABLE(temp), - &xhci->ir_set->irq_pending); + &xhci->erst.ir_set->irq_pending); xhci_print_ir_set(xhci, 0); xhci_dbg(xhci, "cleaning up memory\n"); @@ -597,11 +597,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); - xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); - xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); - xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); - xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + xhci->s3.irq_pending = xhci_readl(xhci, &xhci->erst.ir_set->irq_pending); + xhci->s3.irq_control = xhci_readl(xhci, &xhci->erst.ir_set->irq_control); + xhci->s3.erst_size = xhci_readl(xhci, &xhci->erst.ir_set->erst_size); + xhci->s3.erst_base = xhci_read_64(xhci, &xhci->erst.ir_set->erst_base); + xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->erst.ir_set->erst_dequeue); } static void xhci_restore_registers(struct xhci_hcd *xhci) @@ -610,10 +610,10 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); - xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); - xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); - xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); - xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); + xhci_writel(xhci, xhci->s3.irq_pending, &xhci->erst.ir_set->irq_pending); + xhci_writel(xhci, xhci->s3.irq_control, &xhci->erst.ir_set->irq_control); + xhci_writel(xhci, xhci->s3.erst_size, &xhci->erst.ir_set->erst_size); + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->erst.ir_set->erst_base); } static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) @@ -793,9 +793,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "// Disabling event ring interrupts\n"); temp = xhci_readl(xhci, &xhci->op_regs->status); xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + temp = xhci_readl(xhci, &xhci->erst.ir_set->irq_pending); xhci_writel(xhci, ER_IRQ_DISABLE(temp), - &xhci->ir_set->irq_pending); + &xhci->erst.ir_set->irq_pending); xhci_print_ir_set(xhci, 0); xhci_dbg(xhci, "cleaning up memory\n"); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 86e16d2..db2491b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1136,6 +1136,7 @@ struct xhci_erst_entry { struct xhci_erst { struct xhci_ring *ring; + struct xhci_intr_reg __iomem *ir_set; struct xhci_erst_entry *entries; unsigned int num_entries; /* ring keeps track of segment dma addresses */ @@ -1213,8 +1214,6 @@ struct xhci_hcd { struct xhci_op_regs __iomem *op_regs; struct xhci_run_regs __iomem *run_regs; struct xhci_doorbell_array __iomem *dba; - /* Our HCD's current interrupter register set */ - struct xhci_intr_reg __iomem *ir_set; /* Cached register copies of read-only HC data */ __u32 hcs_params1; -- 1.7.4.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html