diff options
author | Xenia Ragiadakou <burzalodowa@gmail.com> | 2013-11-14 22:34:09 -0500 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2013-12-02 15:59:50 -0500 |
commit | 7dd09a1af2c7150269350aaa567a11b06e831003 (patch) | |
tree | d471de024c220174132915ba2f38a7d63dcd2462 /drivers/usb/host | |
parent | e8b373326d8efcaf9ec1da8b618556c89bd5ffc4 (diff) |
xhci: replace xhci_write_64() with writeq()
Function xhci_write_64() is used to write 64bit xHC registers residing in MMIO.
On 32bit systems, xHC registers need to be written with 32bit accesses by
writing first the lower 32bits and then the higher 32bits. The header file
asm-generic/io-64-nonatomic-lo-hi.h ensures that on 32bit systems writeq() will
will write 64bit registers in 32bit chunks with low-high order.
Replace all calls to xhci_write_64() with calls to writeq().
This is done to reduce code duplication since 64bit low-high write logic
is already implemented and to take advantage of inherent "atomic" 64bit
write operations on 64bit systems.
Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 29 |
4 files changed, 20 insertions, 33 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 4b87026f8a5a..873c272b3ef5 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1967,7 +1967,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | |||
1967 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 1967 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
1968 | "// Write event ring dequeue pointer, " | 1968 | "// Write event ring dequeue pointer, " |
1969 | "preserving EHB bit"); | 1969 | "preserving EHB bit"); |
1970 | xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp, | 1970 | writeq(((u64) deq & (u64) ~ERST_PTR_MASK) | temp, |
1971 | &xhci->ir_set->erst_dequeue); | 1971 | &xhci->ir_set->erst_dequeue); |
1972 | } | 1972 | } |
1973 | 1973 | ||
@@ -2269,7 +2269,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2269 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 2269 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
2270 | "// Device context base array address = 0x%llx (DMA), %p (virt)", | 2270 | "// Device context base array address = 0x%llx (DMA), %p (virt)", |
2271 | (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); | 2271 | (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); |
2272 | xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr); | 2272 | writeq(dma, &xhci->op_regs->dcbaa_ptr); |
2273 | 2273 | ||
2274 | /* | 2274 | /* |
2275 | * Initialize the ring segment pool. The ring must be a contiguous | 2275 | * Initialize the ring segment pool. The ring must be a contiguous |
@@ -2318,7 +2318,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2318 | xhci->cmd_ring->cycle_state; | 2318 | xhci->cmd_ring->cycle_state; |
2319 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 2319 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
2320 | "// Setting command ring address to 0x%x", val); | 2320 | "// Setting command ring address to 0x%x", val); |
2321 | xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); | 2321 | writeq(val_64, &xhci->op_regs->cmd_ring); |
2322 | xhci_dbg_cmd_ptrs(xhci); | 2322 | xhci_dbg_cmd_ptrs(xhci); |
2323 | 2323 | ||
2324 | xhci->lpm_command = xhci_alloc_command(xhci, true, true, flags); | 2324 | xhci->lpm_command = xhci_alloc_command(xhci, true, true, flags); |
@@ -2399,7 +2399,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2399 | val_64 = readq(&xhci->ir_set->erst_base); | 2399 | val_64 = readq(&xhci->ir_set->erst_base); |
2400 | val_64 &= ERST_PTR_MASK; | 2400 | val_64 &= ERST_PTR_MASK; |
2401 | val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); | 2401 | val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); |
2402 | xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base); | 2402 | writeq(val_64, &xhci->ir_set->erst_base); |
2403 | 2403 | ||
2404 | /* Set the event ring dequeue address */ | 2404 | /* Set the event ring dequeue address */ |
2405 | xhci_set_hc_event_deq(xhci); | 2405 | xhci_set_hc_event_deq(xhci); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 339733b8524a..fe9208a5d103 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -319,8 +319,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) | |||
319 | return 0; | 319 | return 0; |
320 | } | 320 | } |
321 | xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; | 321 | xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; |
322 | xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, | 322 | writeq(temp_64 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); |
323 | &xhci->op_regs->cmd_ring); | ||
324 | 323 | ||
325 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should | 324 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should |
326 | * time the completion od all xHCI commands, including | 325 | * time the completion od all xHCI commands, including |
@@ -2872,8 +2871,7 @@ hw_died: | |||
2872 | * the event ring should be empty. | 2871 | * the event ring should be empty. |
2873 | */ | 2872 | */ |
2874 | temp_64 = readq(&xhci->ir_set->erst_dequeue); | 2873 | temp_64 = readq(&xhci->ir_set->erst_dequeue); |
2875 | xhci_write_64(xhci, temp_64 | ERST_EHB, | 2874 | writeq(temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); |
2876 | &xhci->ir_set->erst_dequeue); | ||
2877 | spin_unlock(&xhci->lock); | 2875 | spin_unlock(&xhci->lock); |
2878 | 2876 | ||
2879 | return IRQ_HANDLED; | 2877 | return IRQ_HANDLED; |
@@ -2900,7 +2898,7 @@ hw_died: | |||
2900 | 2898 | ||
2901 | /* Clear the event handler busy flag (RW1C); event ring is empty. */ | 2899 | /* Clear the event handler busy flag (RW1C); event ring is empty. */ |
2902 | temp_64 |= ERST_EHB; | 2900 | temp_64 |= ERST_EHB; |
2903 | xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue); | 2901 | writeq(temp_64, &xhci->ir_set->erst_dequeue); |
2904 | 2902 | ||
2905 | spin_unlock(&xhci->lock); | 2903 | spin_unlock(&xhci->lock); |
2906 | 2904 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 858e992729c9..7fe6f664054f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -762,11 +762,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) | |||
762 | { | 762 | { |
763 | writel(xhci->s3.command, &xhci->op_regs->command); | 763 | writel(xhci->s3.command, &xhci->op_regs->command); |
764 | writel(xhci->s3.dev_nt, &xhci->op_regs->dev_notification); | 764 | writel(xhci->s3.dev_nt, &xhci->op_regs->dev_notification); |
765 | xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); | 765 | writeq(xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); |
766 | writel(xhci->s3.config_reg, &xhci->op_regs->config_reg); | 766 | writel(xhci->s3.config_reg, &xhci->op_regs->config_reg); |
767 | writel(xhci->s3.erst_size, &xhci->ir_set->erst_size); | 767 | writel(xhci->s3.erst_size, &xhci->ir_set->erst_size); |
768 | xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); | 768 | writeq(xhci->s3.erst_base, &xhci->ir_set->erst_base); |
769 | xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); | 769 | writeq(xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); |
770 | writel(xhci->s3.irq_pending, &xhci->ir_set->irq_pending); | 770 | writel(xhci->s3.irq_pending, &xhci->ir_set->irq_pending); |
771 | writel(xhci->s3.irq_control, &xhci->ir_set->irq_control); | 771 | writel(xhci->s3.irq_control, &xhci->ir_set->irq_control); |
772 | } | 772 | } |
@@ -785,7 +785,7 @@ static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) | |||
785 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 785 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
786 | "// Setting command ring address to 0x%llx", | 786 | "// Setting command ring address to 0x%llx", |
787 | (long unsigned long) val_64); | 787 | (long unsigned long) val_64); |
788 | xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); | 788 | writeq(val_64, &xhci->op_regs->cmd_ring); |
789 | } | 789 | } |
790 | 790 | ||
791 | /* | 791 | /* |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 5579b44379a4..7807f621a713 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -28,6 +28,15 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/usb/hcd.h> | 29 | #include <linux/usb/hcd.h> |
30 | 30 | ||
31 | /* | ||
32 | * Registers should always be accessed with double word or quad word accesses. | ||
33 | * | ||
34 | * Some xHCI implementations may support 64-bit address pointers. Registers | ||
35 | * with 64-bit address pointers should be written to with dword accesses by | ||
36 | * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. | ||
37 | * xHCI implementations that do not support 64-bit address pointers will ignore | ||
38 | * the high dword, and write order is irrelevant. | ||
39 | */ | ||
31 | #include <asm-generic/io-64-nonatomic-lo-hi.h> | 40 | #include <asm-generic/io-64-nonatomic-lo-hi.h> |
32 | 41 | ||
33 | /* Code sharing between pci-quirks and xhci hcd */ | 42 | /* Code sharing between pci-quirks and xhci hcd */ |
@@ -1597,26 +1606,6 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | |||
1597 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ | 1606 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ |
1598 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1607 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1599 | 1608 | ||
1600 | /* | ||
1601 | * Registers should always be accessed with double word or quad word accesses. | ||
1602 | * | ||
1603 | * Some xHCI implementations may support 64-bit address pointers. Registers | ||
1604 | * with 64-bit address pointers should be written to with dword accesses by | ||
1605 | * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. | ||
1606 | * xHCI implementations that do not support 64-bit address pointers will ignore | ||
1607 | * the high dword, and write order is irrelevant. | ||
1608 | */ | ||
1609 | static inline void xhci_write_64(struct xhci_hcd *xhci, | ||
1610 | const u64 val, __le64 __iomem *regs) | ||
1611 | { | ||
1612 | __u32 __iomem *ptr = (__u32 __iomem *) regs; | ||
1613 | u32 val_lo = lower_32_bits(val); | ||
1614 | u32 val_hi = upper_32_bits(val); | ||
1615 | |||
1616 | writel(val_lo, ptr); | ||
1617 | writel(val_hi, ptr + 1); | ||
1618 | } | ||
1619 | |||
1620 | static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) | 1609 | static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) |
1621 | { | 1610 | { |
1622 | return xhci->quirks & XHCI_LINK_TRB_QUIRK; | 1611 | return xhci->quirks & XHCI_LINK_TRB_QUIRK; |