summaryrefslogtreecommitdiffstats
path: root/drivers/dma/dw/regs.h
diff options
context:
space:
mode:
authorMans Rullgard <mans@mansr.com>2016-03-18 15:24:43 +0100
committerVinod Koul <vinod.koul@intel.com>2016-04-13 18:06:10 +0200
commitdf1f3a2305d72cbf470758999785f08bcd642d5d (patch)
treee8af88f6543cad5d375fa7b8eb8058a269dae306 /drivers/dma/dw/regs.h
parentdmaengine: dw: set src and dst master select according to xfer direction (diff)
downloadlinux-df1f3a2305d72cbf470758999785f08bcd642d5d.tar.xz
linux-df1f3a2305d72cbf470758999785f08bcd642d5d.zip
dmaengine: dw: fix byte order of hw descriptor fields
If the DMA controller uses a different byte order than the host CPU, the hardware linked list descriptor fields need to be byte-swapped. This patch makes the driver write these fields using the same byte order it uses for mmio accesses to the DMA engine. I do not know if this is guaranteed to always be correct. Signed-off-by: Mans Rullgard <mans@mansr.com> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/dw/regs.h')
-rw-r--r--drivers/dma/dw/regs.h32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h
index a63d62bbffe2..6571100a07e4 100644
--- a/drivers/dma/dw/regs.h
+++ b/drivers/dma/dw/regs.h
@@ -308,26 +308,44 @@ static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
return container_of(ddev, struct dw_dma, dma);
}
+#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
+typedef __be32 __dw32;
+#else
+typedef __le32 __dw32;
+#endif
+
/* LLI == Linked List Item; a.k.a. DMA block descriptor */
struct dw_lli {
/* values that are not changed by hardware */
- u32 sar;
- u32 dar;
- u32 llp; /* chain to next lli */
- u32 ctllo;
+ __dw32 sar;
+ __dw32 dar;
+ __dw32 llp; /* chain to next lli */
+ __dw32 ctllo;
/* values that may get written back: */
- u32 ctlhi;
+ __dw32 ctlhi;
/* sstat and dstat can snapshot peripheral register state.
* silicon config may discard either or both...
*/
- u32 sstat;
- u32 dstat;
+ __dw32 sstat;
+ __dw32 dstat;
};
struct dw_desc {
/* FIRST values the hardware uses */
struct dw_lli lli;
+#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
+#define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_be32(v))
+#define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_be32(v))
+#define lli_read(d, reg) be32_to_cpu((d)->lli.reg)
+#define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_be32(v))
+#else
+#define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_le32(v))
+#define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_le32(v))
+#define lli_read(d, reg) le32_to_cpu((d)->lli.reg)
+#define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_le32(v))
+#endif
+
/* THEN values for driver housekeeping */
struct list_head desc_node;
struct list_head tx_list;