From e09b41010ba33a20a87472ee821fa407a5b8da36 Mon Sep 17 00:00:00 2001 From: José Pekkarinen Date: Mon, 11 Apr 2016 10:41:07 +0300 Subject: These changes are the raw update to linux-4.4.6-rt14. Kernel sources are taken from kernel.org, and rt patch from the rt wiki download page. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During the rebasing, the following patch collided: Force tick interrupt and get rid of softirq magic(I70131fb85). Collisions have been removed because its logic was found on the source already. Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769 Signed-off-by: José Pekkarinen --- kernel/drivers/net/ethernet/smsc/smc91x.h | 99 ++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 34 deletions(-) (limited to 'kernel/drivers/net/ethernet/smsc/smc91x.h') diff --git a/kernel/drivers/net/ethernet/smsc/smc91x.h b/kernel/drivers/net/ethernet/smsc/smc91x.h index 3a18501d1..a3c129e1e 100644 --- a/kernel/drivers/net/ethernet/smsc/smc91x.h +++ b/kernel/drivers/net/ethernet/smsc/smc91x.h @@ -33,6 +33,7 @@ #ifndef _SMC91X_H_ #define _SMC91X_H_ +#include #include /* @@ -244,6 +245,7 @@ struct smc_local { u_long physaddr; struct device *device; #endif + struct dma_chan *dma_chan; void __iomem *base; void __iomem *datacs; @@ -265,21 +267,47 @@ struct smc_local { * as RX which can overrun memory and lose packets. */ #include -#include +#include #ifdef SMC_insl #undef SMC_insl #define SMC_insl(a, r, p, l) \ smc_pxa_dma_insl(a, lp, r, dev->dma, p, l) +static inline void +smc_pxa_dma_inpump(struct smc_local *lp, u_char *buf, int len) +{ + dma_addr_t dmabuf; + struct dma_async_tx_descriptor *tx; + dma_cookie_t cookie; + enum dma_status status; + struct dma_tx_state state; + + dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); + tx = dmaengine_prep_slave_single(lp->dma_chan, dmabuf, len, + DMA_DEV_TO_MEM, 0); + if (tx) { + cookie = dmaengine_submit(tx); + dma_async_issue_pending(lp->dma_chan); + do { + status = dmaengine_tx_status(lp->dma_chan, cookie, + &state); + cpu_relax(); + } while (status != DMA_COMPLETE && status != DMA_ERROR && + state.residue); + dmaengine_terminate_all(lp->dma_chan); + } + dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); +} + static inline void smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, u_char *buf, int len) { - u_long physaddr = lp->physaddr; - dma_addr_t dmabuf; + struct dma_slave_config config; + int ret; /* fallback if no DMA available */ - if (dma == (unsigned char)-1) { + if (!lp->dma_chan) { readsl(ioaddr + reg, buf, len); return; } @@ -291,18 +319,22 @@ smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, len--; } + memset(&config, 0, sizeof(config)); + config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + config.src_addr = lp->physaddr + reg; + config.dst_addr = lp->physaddr + reg; + config.src_maxburst = 32; + config.dst_maxburst = 32; + ret = dmaengine_slave_config(lp->dma_chan, &config); + if (ret) { + dev_err(lp->device, "dma channel configuration failed: %d\n", + ret); + return; + } + len *= 4; - dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); - DCSR(dma) = DCSR_NODESC; - DTADR(dma) = dmabuf; - DSADR(dma) = physaddr + reg; - DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | - DCMD_WIDTH4 | (DCMD_LENGTH & len)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; - while (!(DCSR(dma) & DCSR_STOPSTATE)) - cpu_relax(); - DCSR(dma) = 0; - dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); + smc_pxa_dma_inpump(lp, buf, len); } #endif @@ -314,11 +346,11 @@ static inline void smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, u_char *buf, int len) { - u_long physaddr = lp->physaddr; - dma_addr_t dmabuf; + struct dma_slave_config config; + int ret; /* fallback if no DMA available */ - if (dma == (unsigned char)-1) { + if (!lp->dma_chan) { readsw(ioaddr + reg, buf, len); return; } @@ -330,26 +362,25 @@ smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, len--; } + memset(&config, 0, sizeof(config)); + config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + config.src_addr = lp->physaddr + reg; + config.dst_addr = lp->physaddr + reg; + config.src_maxburst = 32; + config.dst_maxburst = 32; + ret = dmaengine_slave_config(lp->dma_chan, &config); + if (ret) { + dev_err(lp->device, "dma channel configuration failed: %d\n", + ret); + return; + } + len *= 2; - dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE); - DCSR(dma) = DCSR_NODESC; - DTADR(dma) = dmabuf; - DSADR(dma) = physaddr + reg; - DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | - DCMD_WIDTH2 | (DCMD_LENGTH & len)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; - while (!(DCSR(dma) & DCSR_STOPSTATE)) - cpu_relax(); - DCSR(dma) = 0; - dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE); + smc_pxa_dma_inpump(lp, buf, len); } #endif -static void -smc_pxa_dma_irq(int dma, void *dummy) -{ - DCSR(dma) = 0; -} #endif /* CONFIG_ARCH_PXA */ -- cgit 1.2.3-korg