aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2019-05-02 12:50:55 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2019-05-09 12:16:41 -0400
commite659587c64b3d48a9293e34eb854967654ed98f7 (patch)
tree7c086962e9c0038c8cc7dce93ab0021896fdd17d
parent39694ed0dbe17de1eff7850e7481bef98047130c (diff)
ARM: riscpc: dma: improve address/length writing
Rearrange writing the DMA addresses to generate more efficient code. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--arch/arm/mach-rpc/dma.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index e2b9c95d853b..6140472d148e 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -100,7 +100,7 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
100 struct iomd_dma *idma = dev_id; 100 struct iomd_dma *idma = dev_id;
101 unsigned long base = idma->base; 101 unsigned long base = idma->base;
102 unsigned int state = idma->state; 102 unsigned int state = idma->state;
103 unsigned int status; 103 unsigned int status, cur, end;
104 104
105 do { 105 do {
106 status = iomd_readb(base + ST); 106 status = iomd_readb(base + ST);
@@ -110,21 +110,17 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
110 if ((state ^ status) & DMA_ST_AB) 110 if ((state ^ status) & DMA_ST_AB)
111 iomd_get_next_sg(idma); 111 iomd_get_next_sg(idma);
112 112
113 switch (status & (DMA_ST_OFL | DMA_ST_AB)) { 113 // This efficiently implements state = OFL != AB ? AB : 0
114 case DMA_ST_OFL: /* OIA */ 114 state = ((status >> 2) ^ status) & DMA_ST_AB;
115 case DMA_ST_AB: /* .IB */ 115 if (state) {
116 iomd_writel(idma->cur_addr, base + CURA); 116 cur = CURA;
117 iomd_writel(idma->cur_len, base + ENDA); 117 end = ENDA;
118 state = DMA_ST_AB; 118 } else {
119 break; 119 cur = CURB;
120 120 end = ENDB;
121 case DMA_ST_OFL | DMA_ST_AB: /* OIB */
122 case 0: /* .IA */
123 iomd_writel(idma->cur_addr, base + CURB);
124 iomd_writel(idma->cur_len, base + ENDB);
125 state = 0;
126 break;
127 } 121 }
122 iomd_writel(idma->cur_addr, base + cur);
123 iomd_writel(idma->cur_len, base + end);
128 124
129 if (status & DMA_ST_OFL && 125 if (status & DMA_ST_OFL &&
130 idma->cur_len == (DMA_END_S|DMA_END_L)) 126 idma->cur_len == (DMA_END_S|DMA_END_L))