All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Mack <zonque@gmail.com>
To: haojian.zhuang@linaro.org, eric.y.miao@gmail.com,
	linux-arm-kernel@lists.infradead.org
Cc: mark.rutland@arm.com, s.neumann@raumfeld.com,
	linux-mtd@lists.infradead.org, Daniel Mack <zonque@gmail.com>,
	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
Subject: [PATCH 10/20] net: irda: pxaficp_ir: switch to dmaengine
Date: Wed,  7 Aug 2013 17:33:59 +0200	[thread overview]
Message-ID: <1375889649-14638-11-git-send-email-zonque@gmail.com> (raw)
In-Reply-To: <1375889649-14638-1-git-send-email-zonque@gmail.com>

This was only compile-tested.

Signed-off-by: Daniel Mack <zonque@gmail.com>
---
 drivers/net/irda/pxaficp_ir.c | 242 ++++++++++++++++++++++++++----------------
 1 file changed, 151 insertions(+), 91 deletions(-)

diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 964b116..d77a342 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -21,13 +21,15 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma/mmp-pdma.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
 
-#include <mach/dma.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <mach/regs-ost.h>
 #include <mach/regs-uart.h>
@@ -99,6 +101,9 @@
                 IrSR_RCVEIR_UART_MODE | \
                 IrSR_XMITIR_IR_MODE)
 
+/* FIXME */
+extern void pxa2xx_transceiver_mode(struct device *dev, int mode);
+
 struct pxa_irda {
 	int			speed;
 	int			newspeed;
@@ -109,8 +114,10 @@ struct pxa_irda {
 	dma_addr_t		dma_rx_buff_phy;
 	dma_addr_t		dma_tx_buff_phy;
 	unsigned int		dma_tx_buff_len;
-	int			txdma;
-	int			rxdma;
+	struct dma_chan		*txdma;
+	struct dma_chan		*rxdma;
+	dma_cookie_t		dma_rx_cookie;
+	dma_cookie_t		dma_tx_cookie;
 
 	int			uart_irq;
 	int			icp_irq;
@@ -122,6 +129,7 @@ struct pxa_irda {
 	iobuff_t		rx_buff;
 
 	struct device		*dev;
+	struct net_device	*net_dev;
 	struct pxaficp_platform_data *pdata;
 	struct clk		*fir_clk;
 	struct clk		*sir_clk;
@@ -147,26 +155,121 @@ static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
 	clk_prepare_enable(si->sir_clk);
 }
 
-
 #define IS_FIR(si)		((si)->speed >= 4000000)
 #define IRDA_FRAME_SIZE_LIMIT	2047
 
 inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
 {
-	DCSR(si->rxdma)  = DCSR_NODESC;
-	DSADR(si->rxdma) = __PREG(ICDR);
-	DTADR(si->rxdma) = si->dma_rx_buff_phy;
-	DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC |  DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
-	DCSR(si->rxdma) |= DCSR_RUN;
+	struct dma_async_tx_descriptor *tx;
+	struct dma_slave_config config;
+	struct dma_device *dma_dev;
+	int ret;
+
+	dma_dev = si->rxdma->device;
+
+	memset(&config, 0, sizeof(config));
+	config.src_maxburst = 32;
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	config.direction = DMA_DEV_TO_MEM;
+
+	ret = dmaengine_slave_config(si->rxdma, &config);
+	if (ret < 0) {
+		dev_err(si->dev, "dmaengine_slave_config() failed: %d\n", ret);
+		return;
+	}
+
+	tx = dma_dev->device_prep_dma_memcpy(si->rxdma, __PREG(ICDR),
+					     si->dma_rx_buff_phy,
+					     IRDA_FRAME_SIZE_LIMIT, 0);
+	if (!tx) {
+		dev_err(si->dev, "device_prep_dma_memcpy() failed: %d\n", ret);
+		return;
+	}
+
+	si->dma_rx_cookie = dmaengine_submit(tx);
+	dma_async_issue_pending(si->rxdma);
+}
+
+static int pxa_irda_set_speed(struct pxa_irda *si, int speed);
+
+/* FIR Transmit DMA interrupt handler */
+static void pxa_irda_fir_dma_tx_irq(void *param)
+{
+	struct net_device *dev = param;
+	struct pxa_irda *si = netdev_priv(dev);
+	struct dma_tx_state tx_state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(si->txdma, si->dma_tx_cookie, &tx_state);
+	if (status == DMA_ERROR) {
+		dev->stats.tx_errors++;
+	} else {
+		dev->stats.tx_packets++;
+		dev->stats.tx_bytes += si->dma_tx_buff_len;
+	}
+
+	while (ICSR1 & ICSR1_TBY)
+		cpu_relax();
+	si->last_oscr = readl_relaxed(OSCR);
+
+	/*
+	 * HACK: It looks like the TBY bit is dropped too soon.
+	 * Without this delay things break.
+	 */
+	udelay(120);
+
+	if (si->newspeed) {
+		pxa_irda_set_speed(si, si->newspeed);
+		si->newspeed = 0;
+	} else {
+		int i = 64;
+
+		ICCR0 = 0;
+		pxa_irda_fir_dma_rx_start(si);
+		while ((ICSR1 & ICSR1_RNE) && i--)
+			(void)ICDR;
+		ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+		if (i < 0)
+			printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
+	}
+	netif_wake_queue(dev);
 }
 
+
 inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
 {
-	DCSR(si->txdma)  = DCSR_NODESC;
-	DSADR(si->txdma) = si->dma_tx_buff_phy;
-	DTADR(si->txdma) = __PREG(ICDR);
-	DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG |  DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
-	DCSR(si->txdma) |= DCSR_RUN;
+	struct dma_async_tx_descriptor *tx;
+	struct dma_slave_config config;
+	struct dma_device *dma_dev;
+	int ret;
+
+	dma_dev = si->txdma->device;
+
+	memset(&config, 0, sizeof(config));
+	config.dst_maxburst = 32;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	config.direction = DMA_MEM_TO_DEV;
+
+	ret = dmaengine_slave_config(si->txdma, &config);
+	if (ret < 0) {
+		dev_err(si->dev, "dmaengine_slave_config() failed: %d\n", ret);
+		return;
+	}
+
+	tx = dma_dev->device_prep_dma_memcpy(si->txdma, __PREG(ICDR),
+					     si->dma_tx_buff_phy,
+					     si->dma_tx_buff_len, 0);
+	if (!tx) {
+		dev_err(si->dev, "device_prep_dma_memcpy() failed: %d\n", ret);
+		return;
+	}
+
+	tx->callback = pxa_irda_fir_dma_tx_irq;
+	tx->callback_param = si->net_dev;
+
+	si->dma_tx_cookie = dmaengine_submit(tx);
+	dma_async_issue_pending(si->txdma);
 }
 
 /*
@@ -205,7 +308,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 
 		if (IS_FIR(si)) {
 			/* stop RX DMA */
-			DCSR(si->rxdma) &= ~DCSR_RUN;
+			dmaengine_terminate_all(si->rxdma);
 			/* disable FICP */
 			ICCR0 = 0;
 			pxa_irda_disable_clk(si);
@@ -344,68 +447,18 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-/* FIR Receive DMA interrupt handler */
-static void pxa_irda_fir_dma_rx_irq(int channel, void *data)
-{
-	int dcsr = DCSR(channel);
-
-	DCSR(channel) = dcsr & ~DCSR_RUN;
-
-	printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
-}
-
-/* FIR Transmit DMA interrupt handler */
-static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
-{
-	struct net_device *dev = data;
-	struct pxa_irda *si = netdev_priv(dev);
-	int dcsr;
-
-	dcsr = DCSR(channel);
-	DCSR(channel) = dcsr & ~DCSR_RUN;
-
-	if (dcsr & DCSR_ENDINTR)  {
-		dev->stats.tx_packets++;
-		dev->stats.tx_bytes += si->dma_tx_buff_len;
-	} else {
-		dev->stats.tx_errors++;
-	}
-
-	while (ICSR1 & ICSR1_TBY)
-		cpu_relax();
-	si->last_oscr = readl_relaxed(OSCR);
-
-	/*
-	 * HACK: It looks like the TBY bit is dropped too soon.
-	 * Without this delay things break.
-	 */
-	udelay(120);
-
-	if (si->newspeed) {
-		pxa_irda_set_speed(si, si->newspeed);
-		si->newspeed = 0;
-	} else {
-		int i = 64;
-
-		ICCR0 = 0;
-		pxa_irda_fir_dma_rx_start(si);
-		while ((ICSR1 & ICSR1_RNE) && i--)
-			(void)ICDR;
-		ICCR0 = ICCR0_ITR | ICCR0_RXE;
-
-		if (i < 0)
-			printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
-	}
-	netif_wake_queue(dev);
-}
-
 /* EIF(Error in FIFO/End in Frame) handler for FIR */
 static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0)
 {
 	unsigned int len, stat, data;
+	struct dma_tx_state tx_state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(si->rxdma, si->dma_rx_cookie,
+				     &tx_state);
 
 	/* Get the current data position. */
-	len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
+	len = IRDA_FRAME_SIZE_LIMIT - tx_state.residue;
 
 	do {
 		/* Read Status, and then Data. 	 */
@@ -472,7 +525,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
 	int icsr0, i = 64;
 
 	/* stop RX DMA */
-	DCSR(si->rxdma) &= ~DCSR_RUN;
+	dmaengine_terminate_all(si->rxdma);
 	si->last_oscr = readl_relaxed(OSCR);
 	icsr0 = ICSR0;
 
@@ -553,7 +606,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 				cpu_relax();
 
 		/* stop RX DMA,  disable FICP */
-		DCSR(si->rxdma) &= ~DCSR_RUN;
+		dmaengine_terminate_all(si->rxdma);
 		ICCR0 = 0;
 
 		pxa_irda_fir_dma_tx_start(si);
@@ -626,10 +679,6 @@ static void pxa_irda_startup(struct pxa_irda *si)
 	/* configure FICP ICCR2 */
 	ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
 
-	/* configure DMAC */
-	DRCMR(17) = si->rxdma | DRCMR_MAPVLD;
-	DRCMR(18) = si->txdma | DRCMR_MAPVLD;
-
 	/* force SIR reinitialization */
 	si->speed = 4000000;
 	pxa_irda_set_speed(si, 9600);
@@ -649,17 +698,15 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 	STISR = 0;
 
 	/* disable DMA */
-	DCSR(si->txdma) &= ~DCSR_RUN;
-	DCSR(si->rxdma) &= ~DCSR_RUN;
+	dmaengine_terminate_all(si->rxdma);
+	dmaengine_terminate_all(si->txdma);
+
 	/* disable FICP */
 	ICCR0 = 0;
 
 	/* disable the STUART or FICP clocks */
 	pxa_irda_disable_clk(si);
 
-	DRCMR(17) = 0;
-	DRCMR(18) = 0;
-
 	local_irq_restore(flags);
 
 	/* power off board transceiver */
@@ -671,7 +718,8 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 static int pxa_irda_start(struct net_device *dev)
 {
 	struct pxa_irda *si = netdev_priv(dev);
-	int err;
+	dma_cap_mask_t mask;
+	int drcmr, err;
 
 	si->speed = 9600;
 
@@ -689,13 +737,21 @@ static int pxa_irda_start(struct net_device *dev)
 	disable_irq(si->uart_irq);
 	disable_irq(si->icp_irq);
 
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
 	err = -EBUSY;
-	si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
-	if (si->rxdma < 0)
+
+	drcmr = 17;
+	si->rxdma = dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+						     &drcmr, si->dev, "rx");
+	if (si->rxdma == NULL)
 		goto err_rx_dma;
 
-	si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
-	if (si->txdma < 0)
+	drcmr = 18;
+	si->rxdma = dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+						     &drcmr, si->dev, "rx");
+	if (si->txdma == NULL)
 		goto err_tx_dma;
 
 	err = -ENOMEM;
@@ -737,9 +793,9 @@ err_irlap:
 err_dma_tx_buff:
 	dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
 err_dma_rx_buff:
-	pxa_free_dma(si->txdma);
+	dma_release_channel(si->txdma);
 err_tx_dma:
-	pxa_free_dma(si->rxdma);
+	dma_release_channel(si->rxdma);
 err_rx_dma:
 	free_irq(si->icp_irq, dev);
 err_irq2:
@@ -766,8 +822,11 @@ static int pxa_irda_stop(struct net_device *dev)
 	free_irq(si->uart_irq, dev);
 	free_irq(si->icp_irq, dev);
 
-	pxa_free_dma(si->rxdma);
-	pxa_free_dma(si->txdma);
+	dmaengine_terminate_all(si->rxdma);
+	dmaengine_terminate_all(si->txdma);
+
+	dma_release_channel(si->rxdma);
+	dma_release_channel(si->txdma);
 
 	if (si->dma_rx_buff)
 		dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
@@ -855,6 +914,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
 	si = netdev_priv(dev);
 	si->dev = &pdev->dev;
 	si->pdata = pdev->dev.platform_data;
+	si->net_dev = dev;
 
 	si->uart_irq = platform_get_irq(pdev, 0);
 	si->icp_irq = platform_get_irq(pdev, 1);
-- 
1.8.3.1

WARNING: multiple messages have this Message-ID (diff)
From: zonque@gmail.com (Daniel Mack)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 10/20] net: irda: pxaficp_ir: switch to dmaengine
Date: Wed,  7 Aug 2013 17:33:59 +0200	[thread overview]
Message-ID: <1375889649-14638-11-git-send-email-zonque@gmail.com> (raw)
In-Reply-To: <1375889649-14638-1-git-send-email-zonque@gmail.com>

This was only compile-tested.

Signed-off-by: Daniel Mack <zonque@gmail.com>
---
 drivers/net/irda/pxaficp_ir.c | 242 ++++++++++++++++++++++++++----------------
 1 file changed, 151 insertions(+), 91 deletions(-)

diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 964b116..d77a342 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -21,13 +21,15 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma/mmp-pdma.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
 
-#include <mach/dma.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <mach/regs-ost.h>
 #include <mach/regs-uart.h>
@@ -99,6 +101,9 @@
                 IrSR_RCVEIR_UART_MODE | \
                 IrSR_XMITIR_IR_MODE)
 
+/* FIXME */
+extern void pxa2xx_transceiver_mode(struct device *dev, int mode);
+
 struct pxa_irda {
 	int			speed;
 	int			newspeed;
@@ -109,8 +114,10 @@ struct pxa_irda {
 	dma_addr_t		dma_rx_buff_phy;
 	dma_addr_t		dma_tx_buff_phy;
 	unsigned int		dma_tx_buff_len;
-	int			txdma;
-	int			rxdma;
+	struct dma_chan		*txdma;
+	struct dma_chan		*rxdma;
+	dma_cookie_t		dma_rx_cookie;
+	dma_cookie_t		dma_tx_cookie;
 
 	int			uart_irq;
 	int			icp_irq;
@@ -122,6 +129,7 @@ struct pxa_irda {
 	iobuff_t		rx_buff;
 
 	struct device		*dev;
+	struct net_device	*net_dev;
 	struct pxaficp_platform_data *pdata;
 	struct clk		*fir_clk;
 	struct clk		*sir_clk;
@@ -147,26 +155,121 @@ static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
 	clk_prepare_enable(si->sir_clk);
 }
 
-
 #define IS_FIR(si)		((si)->speed >= 4000000)
 #define IRDA_FRAME_SIZE_LIMIT	2047
 
 inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si)
 {
-	DCSR(si->rxdma)  = DCSR_NODESC;
-	DSADR(si->rxdma) = __PREG(ICDR);
-	DTADR(si->rxdma) = si->dma_rx_buff_phy;
-	DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC |  DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT;
-	DCSR(si->rxdma) |= DCSR_RUN;
+	struct dma_async_tx_descriptor *tx;
+	struct dma_slave_config config;
+	struct dma_device *dma_dev;
+	int ret;
+
+	dma_dev = si->rxdma->device;
+
+	memset(&config, 0, sizeof(config));
+	config.src_maxburst = 32;
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	config.direction = DMA_DEV_TO_MEM;
+
+	ret = dmaengine_slave_config(si->rxdma, &config);
+	if (ret < 0) {
+		dev_err(si->dev, "dmaengine_slave_config() failed: %d\n", ret);
+		return;
+	}
+
+	tx = dma_dev->device_prep_dma_memcpy(si->rxdma, __PREG(ICDR),
+					     si->dma_rx_buff_phy,
+					     IRDA_FRAME_SIZE_LIMIT, 0);
+	if (!tx) {
+		dev_err(si->dev, "device_prep_dma_memcpy() failed: %d\n", ret);
+		return;
+	}
+
+	si->dma_rx_cookie = dmaengine_submit(tx);
+	dma_async_issue_pending(si->rxdma);
+}
+
+static int pxa_irda_set_speed(struct pxa_irda *si, int speed);
+
+/* FIR Transmit DMA interrupt handler */
+static void pxa_irda_fir_dma_tx_irq(void *param)
+{
+	struct net_device *dev = param;
+	struct pxa_irda *si = netdev_priv(dev);
+	struct dma_tx_state tx_state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(si->txdma, si->dma_tx_cookie, &tx_state);
+	if (status == DMA_ERROR) {
+		dev->stats.tx_errors++;
+	} else {
+		dev->stats.tx_packets++;
+		dev->stats.tx_bytes += si->dma_tx_buff_len;
+	}
+
+	while (ICSR1 & ICSR1_TBY)
+		cpu_relax();
+	si->last_oscr = readl_relaxed(OSCR);
+
+	/*
+	 * HACK: It looks like the TBY bit is dropped too soon.
+	 * Without this delay things break.
+	 */
+	udelay(120);
+
+	if (si->newspeed) {
+		pxa_irda_set_speed(si, si->newspeed);
+		si->newspeed = 0;
+	} else {
+		int i = 64;
+
+		ICCR0 = 0;
+		pxa_irda_fir_dma_rx_start(si);
+		while ((ICSR1 & ICSR1_RNE) && i--)
+			(void)ICDR;
+		ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+		if (i < 0)
+			printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
+	}
+	netif_wake_queue(dev);
 }
 
+
 inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
 {
-	DCSR(si->txdma)  = DCSR_NODESC;
-	DSADR(si->txdma) = si->dma_tx_buff_phy;
-	DTADR(si->txdma) = __PREG(ICDR);
-	DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG |  DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len;
-	DCSR(si->txdma) |= DCSR_RUN;
+	struct dma_async_tx_descriptor *tx;
+	struct dma_slave_config config;
+	struct dma_device *dma_dev;
+	int ret;
+
+	dma_dev = si->txdma->device;
+
+	memset(&config, 0, sizeof(config));
+	config.dst_maxburst = 32;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	config.direction = DMA_MEM_TO_DEV;
+
+	ret = dmaengine_slave_config(si->txdma, &config);
+	if (ret < 0) {
+		dev_err(si->dev, "dmaengine_slave_config() failed: %d\n", ret);
+		return;
+	}
+
+	tx = dma_dev->device_prep_dma_memcpy(si->txdma, __PREG(ICDR),
+					     si->dma_tx_buff_phy,
+					     si->dma_tx_buff_len, 0);
+	if (!tx) {
+		dev_err(si->dev, "device_prep_dma_memcpy() failed: %d\n", ret);
+		return;
+	}
+
+	tx->callback = pxa_irda_fir_dma_tx_irq;
+	tx->callback_param = si->net_dev;
+
+	si->dma_tx_cookie = dmaengine_submit(tx);
+	dma_async_issue_pending(si->txdma);
 }
 
 /*
@@ -205,7 +308,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 
 		if (IS_FIR(si)) {
 			/* stop RX DMA */
-			DCSR(si->rxdma) &= ~DCSR_RUN;
+			dmaengine_terminate_all(si->rxdma);
 			/* disable FICP */
 			ICCR0 = 0;
 			pxa_irda_disable_clk(si);
@@ -344,68 +447,18 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-/* FIR Receive DMA interrupt handler */
-static void pxa_irda_fir_dma_rx_irq(int channel, void *data)
-{
-	int dcsr = DCSR(channel);
-
-	DCSR(channel) = dcsr & ~DCSR_RUN;
-
-	printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
-}
-
-/* FIR Transmit DMA interrupt handler */
-static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
-{
-	struct net_device *dev = data;
-	struct pxa_irda *si = netdev_priv(dev);
-	int dcsr;
-
-	dcsr = DCSR(channel);
-	DCSR(channel) = dcsr & ~DCSR_RUN;
-
-	if (dcsr & DCSR_ENDINTR)  {
-		dev->stats.tx_packets++;
-		dev->stats.tx_bytes += si->dma_tx_buff_len;
-	} else {
-		dev->stats.tx_errors++;
-	}
-
-	while (ICSR1 & ICSR1_TBY)
-		cpu_relax();
-	si->last_oscr = readl_relaxed(OSCR);
-
-	/*
-	 * HACK: It looks like the TBY bit is dropped too soon.
-	 * Without this delay things break.
-	 */
-	udelay(120);
-
-	if (si->newspeed) {
-		pxa_irda_set_speed(si, si->newspeed);
-		si->newspeed = 0;
-	} else {
-		int i = 64;
-
-		ICCR0 = 0;
-		pxa_irda_fir_dma_rx_start(si);
-		while ((ICSR1 & ICSR1_RNE) && i--)
-			(void)ICDR;
-		ICCR0 = ICCR0_ITR | ICCR0_RXE;
-
-		if (i < 0)
-			printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
-	}
-	netif_wake_queue(dev);
-}
-
 /* EIF(Error in FIFO/End in Frame) handler for FIR */
 static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0)
 {
 	unsigned int len, stat, data;
+	struct dma_tx_state tx_state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(si->rxdma, si->dma_rx_cookie,
+				     &tx_state);
 
 	/* Get the current data position. */
-	len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
+	len = IRDA_FRAME_SIZE_LIMIT - tx_state.residue;
 
 	do {
 		/* Read Status, and then Data. 	 */
@@ -472,7 +525,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
 	int icsr0, i = 64;
 
 	/* stop RX DMA */
-	DCSR(si->rxdma) &= ~DCSR_RUN;
+	dmaengine_terminate_all(si->rxdma);
 	si->last_oscr = readl_relaxed(OSCR);
 	icsr0 = ICSR0;
 
@@ -553,7 +606,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 				cpu_relax();
 
 		/* stop RX DMA,  disable FICP */
-		DCSR(si->rxdma) &= ~DCSR_RUN;
+		dmaengine_terminate_all(si->rxdma);
 		ICCR0 = 0;
 
 		pxa_irda_fir_dma_tx_start(si);
@@ -626,10 +679,6 @@ static void pxa_irda_startup(struct pxa_irda *si)
 	/* configure FICP ICCR2 */
 	ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
 
-	/* configure DMAC */
-	DRCMR(17) = si->rxdma | DRCMR_MAPVLD;
-	DRCMR(18) = si->txdma | DRCMR_MAPVLD;
-
 	/* force SIR reinitialization */
 	si->speed = 4000000;
 	pxa_irda_set_speed(si, 9600);
@@ -649,17 +698,15 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 	STISR = 0;
 
 	/* disable DMA */
-	DCSR(si->txdma) &= ~DCSR_RUN;
-	DCSR(si->rxdma) &= ~DCSR_RUN;
+	dmaengine_terminate_all(si->rxdma);
+	dmaengine_terminate_all(si->txdma);
+
 	/* disable FICP */
 	ICCR0 = 0;
 
 	/* disable the STUART or FICP clocks */
 	pxa_irda_disable_clk(si);
 
-	DRCMR(17) = 0;
-	DRCMR(18) = 0;
-
 	local_irq_restore(flags);
 
 	/* power off board transceiver */
@@ -671,7 +718,8 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 static int pxa_irda_start(struct net_device *dev)
 {
 	struct pxa_irda *si = netdev_priv(dev);
-	int err;
+	dma_cap_mask_t mask;
+	int drcmr, err;
 
 	si->speed = 9600;
 
@@ -689,13 +737,21 @@ static int pxa_irda_start(struct net_device *dev)
 	disable_irq(si->uart_irq);
 	disable_irq(si->icp_irq);
 
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
 	err = -EBUSY;
-	si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
-	if (si->rxdma < 0)
+
+	drcmr = 17;
+	si->rxdma = dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+						     &drcmr, si->dev, "rx");
+	if (si->rxdma == NULL)
 		goto err_rx_dma;
 
-	si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev);
-	if (si->txdma < 0)
+	drcmr = 18;
+	si->rxdma = dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn,
+						     &drcmr, si->dev, "rx");
+	if (si->txdma == NULL)
 		goto err_tx_dma;
 
 	err = -ENOMEM;
@@ -737,9 +793,9 @@ err_irlap:
 err_dma_tx_buff:
 	dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy);
 err_dma_rx_buff:
-	pxa_free_dma(si->txdma);
+	dma_release_channel(si->txdma);
 err_tx_dma:
-	pxa_free_dma(si->rxdma);
+	dma_release_channel(si->rxdma);
 err_rx_dma:
 	free_irq(si->icp_irq, dev);
 err_irq2:
@@ -766,8 +822,11 @@ static int pxa_irda_stop(struct net_device *dev)
 	free_irq(si->uart_irq, dev);
 	free_irq(si->icp_irq, dev);
 
-	pxa_free_dma(si->rxdma);
-	pxa_free_dma(si->txdma);
+	dmaengine_terminate_all(si->rxdma);
+	dmaengine_terminate_all(si->txdma);
+
+	dma_release_channel(si->rxdma);
+	dma_release_channel(si->txdma);
 
 	if (si->dma_rx_buff)
 		dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy);
@@ -855,6 +914,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
 	si = netdev_priv(dev);
 	si->dev = &pdev->dev;
 	si->pdata = pdev->dev.platform_data;
+	si->net_dev = dev;
 
 	si->uart_irq = platform_get_irq(pdev, 0);
 	si->icp_irq = platform_get_irq(pdev, 1);
-- 
1.8.3.1

  parent reply	other threads:[~2013-08-07 15:33 UTC|newest]

Thread overview: 126+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-07 15:33 [PATCH 00/20] ARM: pxa: move core and drivers to dmaengine Daniel Mack
2013-08-07 15:33 ` Daniel Mack
2013-08-07 15:33 ` [PATCH 01/20] mtd: pxa3xx-nand: replace pxa_request_dma with dmaengine Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-07 17:46   ` Ezequiel Garcia
2013-08-07 17:46     ` Ezequiel Garcia
2013-08-08  6:42     ` Daniel Mack
2013-08-08  6:42       ` Daniel Mack
2013-08-08 10:12       ` Ezequiel Garcia
2013-08-08 10:12         ` Ezequiel Garcia
2013-08-08 10:14         ` Daniel Mack
2013-08-08 10:14           ` Daniel Mack
2013-08-07 15:33 ` [PATCH 02/20] mtd: pxa3xx-nand: use mmp_pdma_filter_fn and dma_request_slave_channel_compat Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-07 15:33 ` [PATCH 03/20] ARM: pxa: ssp: add shortcut for &pdev->dev Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-08  7:32   ` Brian Norris
2013-08-08  7:32     ` Brian Norris
2013-08-08  7:52     ` Artem Bityutskiy
2013-08-08  7:52       ` Artem Bityutskiy
2013-08-08  8:20       ` Daniel Mack
2013-08-08  8:20         ` Daniel Mack
2013-08-07 15:33 ` [PATCH 04/20] ARM: pxa: ssp: add DT bindings Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-07 15:54   ` Arnd Bergmann
2013-08-07 15:54     ` Arnd Bergmann
2013-08-07 15:33 ` [PATCH 05/20] ARM: pxa: ssp: use devm_ functions Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-07 15:33 ` [PATCH 06/20] tty: serial: pxa: remove old cruft Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-12  8:19   ` Daniel Mack
2013-08-12 18:08     ` Greg KH
2013-08-07 15:33 ` [PATCH 07/20] spi: spi-pxa2xx: remove legacy PXA DMA bits Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-07 15:55   ` Mark Brown
2013-08-07 15:55     ` Mark Brown
2013-08-07 15:59     ` Daniel Mack
2013-08-07 15:59       ` Daniel Mack
2013-08-07 16:41       ` Mark Brown
2013-08-07 16:41         ` Mark Brown
2013-08-07 15:33 ` [PATCH 08/20] mmc: host: pxamci: switch over to dmaengine use Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2014-10-15 18:32   ` Vasily Khoruzhick
2014-10-15 18:32     ` Vasily Khoruzhick
2014-10-15 18:32     ` Vasily Khoruzhick
2014-10-16 17:57     ` Vasily Khoruzhick
2014-10-16 17:57       ` Vasily Khoruzhick
2014-10-16 17:57       ` Vasily Khoruzhick
2013-08-07 15:33 ` [PATCH 09/20] ata: pdata_pxa: migrate over to dmaengine usage Daniel Mack
2013-08-07 15:33   ` Daniel Mack
2013-08-07 15:59   ` Arnd Bergmann
2013-08-07 15:59     ` Arnd Bergmann
2013-08-07 15:33 ` Daniel Mack [this message]
2013-08-07 15:33   ` [PATCH 10/20] net: irda: pxaficp_ir: switch to dmaengine Daniel Mack
2013-08-07 15:34 ` [PATCH 11/20] net: smc91x.c: switch to generic buf-to-buf DMA offload Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 15:34 ` [PATCH 12/20] net: smc911x.c: switch to dmaengine API Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 15:34 ` [PATCH 13/20] ASoC: pxa: pxa-ssp: add DT bindings Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 16:40   ` Mark Brown
2013-08-07 16:40     ` Mark Brown
2013-08-08  9:39     ` Daniel Mack
2013-08-08  9:39       ` Daniel Mack
2013-08-08 13:20       ` Mark Brown
2013-08-08 13:20         ` Mark Brown
2013-08-09 13:03         ` Daniel Mack
2013-08-09 13:03           ` Daniel Mack
2013-08-07 15:34 ` [PATCH 14/20] ASoC: pxa: use snd_dmaengine_dai_dma_data Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 15:57   ` Mark Brown
2013-08-07 15:57     ` Mark Brown
2013-08-07 15:34 ` [PATCH 15/20] ASoC: pxa: pxa-ssp: set dma filter data from startup hook Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 15:58   ` Mark Brown
2013-08-07 15:58     ` Mark Brown
2013-08-07 15:34 ` [PATCH 16/20] ASoC: pxa: add DT bindings for pxa2xx-pcm Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 16:06   ` Mark Brown
2013-08-07 16:06     ` Mark Brown
2013-08-07 15:34 ` [PATCH 17/20] ASoC: pxa: pxa-pcm-lib: switch over to snd-soc-dmaengine-pcm Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 16:07   ` Mark Brown
2013-08-07 16:07     ` Mark Brown
2013-08-07 16:10     ` Daniel Mack
2013-08-07 16:10       ` Daniel Mack
2013-08-07 16:32       ` Mark Brown
2013-08-07 16:32         ` Mark Brown
2013-08-08  8:18         ` Daniel Mack
2013-08-08  8:18           ` Daniel Mack
2013-08-08  8:44           ` Lars-Peter Clausen
2013-08-08  8:44             ` Lars-Peter Clausen
2013-08-08  9:03             ` Daniel Mack
2013-08-08  9:03               ` Daniel Mack
2013-08-08  9:36               ` Mark Brown
2013-08-08  9:36                 ` Mark Brown
2013-08-08  9:43                 ` Daniel Mack
2013-08-08  9:43                   ` Daniel Mack
2013-08-08 10:35                   ` Mark Brown
2013-08-08 10:35                     ` Mark Brown
2013-08-08 10:39                     ` Daniel Mack
2013-08-08 10:39                       ` Daniel Mack
2013-08-08 11:03                       ` Mark Brown
2013-08-08 11:03                         ` Mark Brown
2013-08-08 10:25                 ` Russell King - ARM Linux
2013-08-08 10:25                   ` Russell King - ARM Linux
2013-08-07 15:34 ` [PATCH 18/20] ARM: pxa: register static mmp_pdma device Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 15:34 ` [PATCH 19/20] ARM: mmp: " Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 15:34 ` [PATCH 20/20] ARM: pxa: remove old DMA implementation Daniel Mack
2013-08-07 15:34   ` Daniel Mack
2013-08-07 16:08 ` [PATCH 00/20] ARM: pxa: move core and drivers to dmaengine Arnd Bergmann
2013-08-07 16:08   ` Arnd Bergmann
2013-08-09 22:50 ` Robert Jarzmik
2013-08-09 22:50   ` Robert Jarzmik
2013-08-10 10:56   ` Daniel Mack
2013-08-10 10:56     ` Daniel Mack
2013-08-11 20:05     ` Robert Jarzmik
2013-08-11 20:05       ` Robert Jarzmik
2013-08-14 10:00     ` Vinod Koul
2013-08-14 10:00       ` Vinod Koul
2013-08-15 15:22       ` Robert Jarzmik
2013-08-15 15:22         ` Robert Jarzmik
2013-08-15 15:30         ` Daniel Mack
2013-08-15 15:30           ` Daniel Mack

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1375889649-14638-11-git-send-email-zonque@gmail.com \
    --to=zonque@gmail.com \
    --cc=arnd@arndb.de \
    --cc=broonie@kernel.org \
    --cc=cxie4@marvell.com \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=djbw@fb.com \
    --cc=eric.y.miao@gmail.com \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=g.liakhovetski@gmx.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=haojian.zhuang@linaro.org \
    --cc=kernel@pengutronix.de \
    --cc=lars@metafoo.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=marek.vasut@gmail.com \
    --cc=mark.rutland@arm.com \
    --cc=mika.westerberg@linux.intel.com \
    --cc=nico@linaro.org \
    --cc=rmk+kernel@arm.linux.org.uk \
    --cc=s.neumann@raumfeld.com \
    --cc=sachin.kamat@linaro.org \
    --cc=samuel@sortiz.org \
    --cc=thomas.petazzoni@free-electrons.com \
    --cc=vinod.koul@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.