Function xhci_read_64() is used to read 64bit xHC registers residing in MMIO. On 32bit systems, registers should be read/written with 32bit accesses by reading/writing the low 32bits first and then the high 32bits second. This patch adds asm-generic/io-64-nonatomic-lo-hi.h header file in xhci.h so that if the system is not 64bit, readq() will read registers in low-high order. Also, it replaces all calls to xhci_read_64() with calls to readq() and removes xhci_read_64(). This is done to reduce code duplication since 64bit register read operation is already implemented. Signed-off-by: Xenia Ragiadakou <burzalodowa@xxxxxxxxx> --- drivers/usb/host/xhci-dbg.c | 6 +++--- drivers/usb/host/xhci-mem.c | 6 +++--- drivers/usb/host/xhci-ring.c | 6 +++--- drivers/usb/host/xhci.c | 12 ++++++------ drivers/usb/host/xhci.h | 9 +-------- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index eb009a4..b016d38 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -203,12 +203,12 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num) addr, (unsigned int)temp); addr = &ir_set->erst_base; - temp_64 = xhci_read_64(xhci, addr); + temp_64 = readq(addr); xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n", addr, temp_64); addr = &ir_set->erst_dequeue; - temp_64 = xhci_read_64(xhci, addr); + temp_64 = readq(addr); xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n", addr, temp_64); } @@ -412,7 +412,7 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci) { u64 val; - val = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); + val = readq(&xhci->op_regs->cmd_ring); xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = @%08x\n", lower_32_bits(val)); xhci_dbg(xhci, "// xHC command ring deq ptr high bits = @%08x\n", diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index f9873fa..dae8a39 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1968,7 +1968,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 = readq(&xhci->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. @@ -2319,7 +2319,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) (unsigned long long)xhci->cmd_ring->first_seg->dma); /* Set the address in the Command Ring Control register */ - val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); + val_64 = readq(&xhci->op_regs->cmd_ring); val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) | xhci->cmd_ring->cycle_state; @@ -2403,7 +2403,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Set ERST base address for ir_set 0 = 0x%llx", (unsigned long long)xhci->erst.erst_dma_addr); - val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base); + val_64 = readq(&xhci->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); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9b50a54..5192170 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -303,7 +303,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) return 0; } - temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); + temp_64 = readq(&xhci->op_regs->cmd_ring); if (!(temp_64 & CMD_RING_RUNNING)) { xhci_dbg(xhci, "Command ring had been stopped\n"); return 0; @@ -2843,7 +2843,7 @@ 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 = readq(&xhci->ir_set->erst_dequeue); xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); spin_unlock(&xhci->lock); @@ -2857,7 +2857,7 @@ hw_died: */ while (xhci_handle_event(xhci) > 0) {} - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 = readq(&xhci->ir_set->erst_dequeue); /* If necessary, update the HW's version of the event ring deq ptr. */ if (event_ring_deq != xhci->event_ring->dequeue) { deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 63ccb21..c56cf1f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -604,7 +604,7 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg(xhci, "Event ring:\n"); xhci_debug_ring(xhci, xhci->event_ring); xhci_dbg_ring_ptrs(xhci, xhci->event_ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 = readq(&xhci->ir_set->erst_dequeue); temp_64 &= ~ERST_PTR_MASK; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "ERST deq = 64'h%0lx", (long unsigned int) temp_64); @@ -742,11 +742,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) { xhci->s3.command = readl(&xhci->op_regs->command); xhci->s3.dev_nt = readl(&xhci->op_regs->dev_notification); - xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); + xhci->s3.dcbaa_ptr = readq(&xhci->op_regs->dcbaa_ptr); xhci->s3.config_reg = readl(&xhci->op_regs->config_reg); xhci->s3.erst_size = readl(&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.erst_base = readq(&xhci->ir_set->erst_base); + xhci->s3.erst_dequeue = readq(&xhci->ir_set->erst_dequeue); xhci->s3.irq_pending = readl(&xhci->ir_set->irq_pending); xhci->s3.irq_control = readl(&xhci->ir_set->irq_control); } @@ -769,7 +769,7 @@ static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) u64 val_64; /* step 2: initialize command ring buffer */ - val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); + val_64 = readq(&xhci->op_regs->cmd_ring); val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, xhci->cmd_ring->dequeue) & @@ -3823,7 +3823,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) if (ret) { return ret; } - temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); + temp_64 = readq(&xhci->op_regs->dcbaa_ptr); xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Op regs DCBAA ptr = %#016llx", temp_64); xhci_dbg_trace(xhci, trace_xhci_dbg_address, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2a2ab62..0ad527e 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -27,6 +27,7 @@ #include <linux/timer.h> #include <linux/kernel.h> #include <linux/usb/hcd.h> +#include <asm-generic/io-64-nonatomic-lo-hi.h> /* Code sharing between pci-quirks and xhci hcd */ #include "xhci-ext-caps.h" @@ -1593,14 +1594,6 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) * xHCI implementations that do not support 64-bit address pointers will ignore * the high dword, and write order is irrelevant. */ -static inline u64 xhci_read_64(const struct xhci_hcd *xhci, - __le64 __iomem *regs) -{ - __u32 __iomem *ptr = (__u32 __iomem *) regs; - u64 val_lo = readl(ptr); - u64 val_hi = readl(ptr + 1); - return val_lo + (val_hi << 32); -} static inline void xhci_write_64(struct xhci_hcd *xhci, const u64 val, __le64 __iomem *regs) { -- 1.8.3.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