From patchwork Wed Aug 7 15:34:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Mack X-Patchwork-Id: 2840374 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 36565BF535 for ; Wed, 7 Aug 2013 15:39:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CF32D2028F for ; Wed, 7 Aug 2013 15:39:47 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2A81120250 for ; Wed, 7 Aug 2013 15:39:46 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V75oe-0007dq-Hy; Wed, 07 Aug 2013 15:38:25 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V75ng-0003yl-Ok; Wed, 07 Aug 2013 15:37:24 +0000 Received: from svenfoo.org ([82.94.215.22] helo=mail.zonque.de) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V75la-0003im-Ca; Wed, 07 Aug 2013 15:35:27 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.zonque.de (Postfix) with ESMTP id EF206C05A6; Wed, 7 Aug 2013 17:34:51 +0200 (CEST) Received: from mail.zonque.de ([127.0.0.1]) by localhost (rambrand.bugwerft.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nI93BGdy9ift; Wed, 7 Aug 2013 17:34:51 +0200 (CEST) Received: from tamtam.fritz.box (p5DDC7ADB.dip0.t-ipconnect.de [93.220.122.219]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.zonque.de (Postfix) with ESMTPSA id 13CEFC05A5; Wed, 7 Aug 2013 17:34:50 +0200 (CEST) From: Daniel Mack To: haojian.zhuang@linaro.org, eric.y.miao@gmail.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH 11/20] net: smc91x.c: switch to generic buf-to-buf DMA offload Date: Wed, 7 Aug 2013 17:34:00 +0200 Message-Id: <1375889649-14638-12-git-send-email-zonque@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1375889649-14638-1-git-send-email-zonque@gmail.com> References: <1375889649-14638-1-git-send-email-zonque@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130807_113515_152548_1E4423EA X-CRM114-Status: GOOD ( 17.26 ) X-Spam-Score: 1.5 (+) Cc: mark.rutland@arm.com, s.neumann@raumfeld.com, linux-mtd@lists.infradead.org, Daniel Mack , cxie4@marvell.com, lars@metafoo.de, nico@linaro.org, vinod.koul@intel.com, marek.vasut@gmail.com, ezequiel.garcia@free-electrons.com, rmk+kernel@arm.linux.org.uk, devicetree@vger.kernel.org, samuel@sortiz.org, arnd@arndb.de, broonie@kernel.org, mika.westerberg@linux.intel.com, thomas.petazzoni@free-electrons.com, gregkh@linuxfoundation.org, g.liakhovetski@gmx.de, sachin.kamat@linaro.org, kernel@pengutronix.de, djbw@fb.com, davem@davemloft.net X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,KHOP_BIG_TO_CC,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Drop all PXA-DMA specific implementation details and rely on dma_async_memcpy_buf_to_buf(). This patch is only compile-tested. Signed-off-by: Daniel Mack --- drivers/net/ethernet/smsc/smc91x.c | 40 +++++++-------------- drivers/net/ethernet/smsc/smc91x.h | 71 ++++++++++++++------------------------ 2 files changed, 38 insertions(+), 73 deletions(-) diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index cde13be..2d1e073 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -2015,17 +2015,17 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr, if (retval) goto err_out; -#ifdef CONFIG_ARCH_PXA -# ifdef SMC_USE_PXA_DMA - lp->cfg.flags |= SMC91X_USE_DMA; -# endif if (lp->cfg.flags & SMC91X_USE_DMA) { - int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, - smc_pxa_dma_irq, NULL); - if (dma >= 0) - dev->dma = dma; + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_MEMCPY, mask); + lp->dma_channel = dma_request_channel(mask, NULL, NULL); + + if (!lp->dma_channel) + printk("%s(): request of DMA channel failed\n", + __func__); } -#endif retval = register_netdev(dev); if (retval == 0) { @@ -2034,9 +2034,6 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr, dev->name, version_string, revision_register & 0x0f, lp->base, dev->irq); - if (dev->dma != (unsigned char)-1) - printk(" DMA %d", dev->dma); - printk("%s%s\n", lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "", THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); @@ -2060,10 +2057,6 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr, } err_out: -#ifdef CONFIG_ARCH_PXA - if (retval && dev->dma != (unsigned char)-1) - pxa_free_dma(dev->dma); -#endif return retval; } @@ -2282,14 +2275,6 @@ static int smc_drv_probe(struct platform_device *pdev) goto out_release_attrib; } -#ifdef CONFIG_ARCH_PXA - { - struct smc_local *lp = netdev_priv(ndev); - lp->device = &pdev->dev; - lp->physaddr = res->start; - } -#endif - ret = smc_probe(ndev, addr, irq_flags); if (ret != 0) goto out_iounmap; @@ -2320,12 +2305,11 @@ static int smc_drv_remove(struct platform_device *pdev) unregister_netdev(ndev); + if (lp->dma_channel) + dma_release_channel(lp->dma_channel); + free_irq(ndev->irq, ndev); -#ifdef CONFIG_ARCH_PXA - if (ndev->dma != (unsigned char)-1) - pxa_free_dma(ndev->dma); -#endif iounmap(lp->base); smc_release_datacs(pdev,ndev); diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index 370e13d..cf51366 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -34,6 +34,7 @@ #ifndef _SMC91X_H_ #define _SMC91X_H_ +#include #include /* @@ -338,11 +339,8 @@ struct smc_local { spinlock_t lock; -#ifdef CONFIG_ARCH_PXA - /* DMA needs the physical address of the chip */ - u_long physaddr; - struct device *device; -#endif + struct dma_chan *dma_channel; + void __iomem *base; void __iomem *datacs; @@ -358,13 +356,29 @@ struct smc_local { #ifdef CONFIG_ARCH_PXA /* - * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is + * Let's use the generic DMA buffer-to-buffer offload mechanism. This is * always happening in irq context so no need to worry about races. TX is * different and probably not worth it for that reason, and not as critical * as RX which can overrun memory and lose packets. */ -#include -#include + +static void smc_dma_copy(struct smc_local *lp, void *dest, void *src, + unsigned int len) +{ + dma_cookie_t cookie; + cookie = dma_async_memcpy_buf_to_buf(lp->dma_channel, dest, src, len); + + while (1) { + struct dma_tx_state state; + enum dma_status status; + + status = dmaengine_tx_status(lp->dma_channel, cookie, &state); + if (status != DMA_IN_PROGRESS) + break; + + cpu_relax(); + } +} #ifdef SMC_insl #undef SMC_insl @@ -374,11 +388,8 @@ 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; - /* fallback if no DMA available */ - if (dma == (unsigned char)-1) { + if (lp->dma_channel == NULL) { readsl(ioaddr + reg, buf, len); return; } @@ -390,18 +401,7 @@ smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, len--; } - 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_dma_copy(lp, buf, (__u32 *) ioaddr + reg, len * 4); } #endif @@ -413,11 +413,8 @@ 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; - /* fallback if no DMA available */ - if (dma == (unsigned char)-1) { + if (lp->dma_channel == NULL) { readsw(ioaddr + reg, buf, len); return; } @@ -429,26 +426,10 @@ smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma, len--; } - 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_dma_copy(lp, buf, (__u32 *) ioaddr + reg, len * 2); } #endif -static void -smc_pxa_dma_irq(int dma, void *dummy) -{ - DCSR(dma) = 0; -} #endif /* CONFIG_ARCH_PXA */