]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/irda/pxaficp_ir.c
Merge remote-tracking branch 'input-current/for-linus'
[karo-tx-linux.git] / drivers / net / irda / pxaficp_ir.c
index 100454662e4b36b4d7cad113bdd81cc538cb7304..6e8f616be48eff3557369a922334cd8e7f7617c8 100644 (file)
@@ -19,6 +19,9 @@
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma/pxa-dma.h>
 #include <linux/gpio.h>
 #include <linux/slab.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>
+#undef __REG
+#define __REG(x) ((x) & 0xffff)
 #include <mach/regs-uart.h>
 
-#define FICP           __REG(0x40800000)  /* Start of FICP area */
-#define ICCR0          __REG(0x40800000)  /* ICP Control Register 0 */
-#define ICCR1          __REG(0x40800004)  /* ICP Control Register 1 */
-#define ICCR2          __REG(0x40800008)  /* ICP Control Register 2 */
-#define ICDR           __REG(0x4080000c)  /* ICP Data Register */
-#define ICSR0          __REG(0x40800014)  /* ICP Status Register 0 */
-#define ICSR1          __REG(0x40800018)  /* ICP Status Register 1 */
+#define ICCR0          0x0000          /* ICP Control Register 0 */
+#define ICCR1          0x0004          /* ICP Control Register 1 */
+#define ICCR2          0x0008          /* ICP Control Register 2 */
+#define ICDR           0x000c          /* ICP Data Register */
+#define ICSR0          0x0014          /* ICP Status Register 0 */
+#define ICSR1          0x0018          /* ICP Status Register 1 */
 
 #define ICCR0_AME      (1 << 7)        /* Address match enable */
 #define ICCR0_TIE      (1 << 6)        /* Transmit FIFO interrupt enable */
@@ -56,9 +58,7 @@
 #define ICCR2_TRIG_16   (1 << 0)       /*      >= 16 bytes */
 #define ICCR2_TRIG_32   (2 << 0)       /*      >= 32 bytes */
 
-#ifdef CONFIG_PXA27x
 #define ICSR0_EOC      (1 << 6)        /* DMA End of Descriptor Chain */
-#endif
 #define ICSR0_FRE      (1 << 5)        /* Framing error */
 #define ICSR0_RFS      (1 << 4)        /* Receive FIFO service request */
 #define ICSR0_TFS      (1 << 3)        /* Transnit FIFO service request */
                 IrSR_RCVEIR_UART_MODE | \
                 IrSR_XMITIR_IR_MODE)
 
+/* macros for registers read/write */
+#define ficp_writel(irda, val, off)                                    \
+       do {                                                            \
+               dev_vdbg(irda->dev,                                     \
+                        "%s():%d ficp_writel(0x%x, %s)\n",             \
+                        __func__, __LINE__, (val), #off);              \
+               writel_relaxed((val), (irda)->irda_base + (off));       \
+       } while (0)
+
+#define ficp_readl(irda, off)                                          \
+       ({                                                              \
+               unsigned int _v;                                        \
+               _v = readl_relaxed((irda)->irda_base + (off));          \
+               dev_vdbg(irda->dev,                                     \
+                        "%s():%d ficp_readl(%s): 0x%x\n",              \
+                        __func__, __LINE__, #off, _v);                 \
+               _v;                                                     \
+       })
+
+#define stuart_writel(irda, val, off)                                  \
+       do {                                                            \
+               dev_vdbg(irda->dev,                                     \
+                        "%s():%d stuart_writel(0x%x, %s)\n",           \
+                        __func__, __LINE__, (val), #off);              \
+               writel_relaxed((val), (irda)->stuart_base + (off));     \
+       } while (0)
+
+#define stuart_readl(irda, off)                                                \
+       ({                                                              \
+               unsigned int _v;                                        \
+               _v = readl_relaxed((irda)->stuart_base + (off));        \
+               dev_vdbg(irda->dev,                                     \
+                        "%s():%d stuart_readl(%s): 0x%x\n",            \
+                        __func__, __LINE__, #off, _v);                 \
+               _v;                                                     \
+       })
+
 struct pxa_irda {
        int                     speed;
        int                     newspeed;
-       unsigned long           last_oscr;
+       unsigned long long      last_clk;
 
+       void __iomem            *stuart_base;
+       void __iomem            *irda_base;
        unsigned char           *dma_rx_buff;
        unsigned char           *dma_tx_buff;
        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            rx_cookie;
+       dma_cookie_t            tx_cookie;
+       int                     drcmr_rx;
+       int                     drcmr_tx;
 
        int                     uart_irq;
        int                     icp_irq;
@@ -128,6 +171,8 @@ struct pxa_irda {
        struct clk              *cur_clk;
 };
 
+static int pxa_irda_set_speed(struct pxa_irda *si, int speed);
+
 static inline void pxa_irda_disable_clk(struct pxa_irda *si)
 {
        if (si->cur_clk)
@@ -151,22 +196,41 @@ static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
 #define IS_FIR(si)             ((si)->speed >= 4000000)
 #define IRDA_FRAME_SIZE_LIMIT  2047
 
+static void pxa_irda_fir_dma_rx_irq(void *data);
+static void pxa_irda_fir_dma_tx_irq(void *data);
+
 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;
+
+       tx = dmaengine_prep_slave_single(si->rxdma, si->dma_rx_buff_phy,
+                                        IRDA_FRAME_SIZE_LIMIT, DMA_FROM_DEVICE,
+                                        DMA_PREP_INTERRUPT);
+       if (!tx) {
+               dev_err(si->dev, "prep_slave_sg() failed\n");
+               return;
+       }
+       tx->callback = pxa_irda_fir_dma_rx_irq;
+       tx->callback_param = si;
+       si->rx_cookie = dmaengine_submit(tx);
+       dma_async_issue_pending(si->rxdma);
 }
 
 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;
+
+       tx = dmaengine_prep_slave_single(si->txdma, si->dma_tx_buff_phy,
+                                        si->dma_tx_buff_len, DMA_TO_DEVICE,
+                                        DMA_PREP_INTERRUPT);
+       if (!tx) {
+               dev_err(si->dev, "prep_slave_sg() failed\n");
+               return;
+       }
+       tx->callback = pxa_irda_fir_dma_tx_irq;
+       tx->callback_param = si;
+       si->tx_cookie = dmaengine_submit(tx);
+       dma_async_issue_pending(si->rxdma);
 }
 
 /*
@@ -205,9 +269,9 @@ 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;
+                       ficp_writel(si, 0, ICCR0);
                        pxa_irda_disable_clk(si);
 
                        /* set board transceiver to SIR mode */
@@ -218,17 +282,19 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
                }
 
                /* disable STUART first */
-               STIER = 0;
+               stuart_writel(si, 0, STIER);
 
                /* access DLL & DLH */
-               STLCR |= LCR_DLAB;
-               STDLL = divisor & 0xff;
-               STDLH = divisor >> 8;
-               STLCR &= ~LCR_DLAB;
+               stuart_writel(si, stuart_readl(si, STLCR) | LCR_DLAB, STLCR);
+               stuart_writel(si, divisor & 0xff, STDLL);
+               stuart_writel(si, divisor >> 8, STDLH);
+               stuart_writel(si, stuart_readl(si, STLCR) & ~LCR_DLAB, STLCR);
 
                si->speed = speed;
-               STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
-               STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
+               stuart_writel(si, IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6,
+                             STISR);
+               stuart_writel(si, IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE,
+                             STIER);
 
                local_irq_restore(flags);
                break;
@@ -237,12 +303,12 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
                local_irq_save(flags);
 
                /* disable STUART */
-               STIER = 0;
-               STISR = 0;
+               stuart_writel(si, 0, STIER);
+               stuart_writel(si, 0, STISR);
                pxa_irda_disable_clk(si);
 
                /* disable FICP first */
-               ICCR0 = 0;
+               ficp_writel(si, 0, ICCR0);
 
                /* set board transceiver to FIR mode */
                pxa_irda_set_mode(si, IR_FIRMODE);
@@ -252,7 +318,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 
                si->speed = speed;
                pxa_irda_fir_dma_rx_start(si);
-               ICCR0 = ICCR0_ITR | ICCR0_RXE;
+               ficp_writel(si, ICCR0_ITR | ICCR0_RXE, ICCR0);
 
                local_irq_restore(flags);
                break;
@@ -271,13 +337,13 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
        struct pxa_irda *si = netdev_priv(dev);
        int iir, lsr, data;
 
-       iir = STIIR;
+       iir = stuart_readl(si, STIIR);
 
        switch  (iir & 0x0F) {
        case 0x06: /* Receiver Line Status */
-               lsr = STLSR;
+               lsr = stuart_readl(si, STLSR);
                while (lsr & LSR_FIFOE) {
-                       data = STRBR;
+                       data = stuart_readl(si, STRBR);
                        if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) {
                                printk(KERN_DEBUG "pxa_ir: sir receiving error\n");
                                dev->stats.rx_errors++;
@@ -290,9 +356,9 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
                                async_unwrap_char(dev, &dev->stats,
                                                  &si->rx_buff, data);
                        }
-                       lsr = STLSR;
+                       lsr = stuart_readl(si, STLSR);
                }
-               si->last_oscr = readl_relaxed(OSCR);
+               si->last_clk = sched_clock();
                break;
 
        case 0x04: /* Received Data Available */
@@ -301,14 +367,16 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
        case 0x0C: /* Character Timeout Indication */
                do  {
                    dev->stats.rx_bytes++;
-                   async_unwrap_char(dev, &dev->stats, &si->rx_buff, STRBR);
-               } while (STLSR & LSR_DR);
-               si->last_oscr = readl_relaxed(OSCR);
+                   async_unwrap_char(dev, &dev->stats, &si->rx_buff,
+                                     stuart_readl(si, STRBR));
+               } while (stuart_readl(si, STLSR) & LSR_DR);
+               si->last_clk = sched_clock();
                break;
 
        case 0x02: /* Transmit FIFO Data Request */
-               while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) {
-                       STTHR = *si->tx_buff.data++;
+               while ((si->tx_buff.len) &&
+                      (stuart_readl(si, STLSR) & LSR_TDRQ)) {
+                       stuart_writel(si, *si->tx_buff.data++, STTHR);
                        si->tx_buff.len -= 1;
                }
 
@@ -317,9 +385,9 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
                        dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head;
 
                         /* We need to ensure that the transmitter has finished. */
-                       while ((STLSR & LSR_TEMT) == 0)
+                       while ((stuart_readl(si, STLSR) & LSR_TEMT) == 0)
                                cpu_relax();
-                       si->last_oscr = readl_relaxed(OSCR);
+                       si->last_clk = sched_clock();
 
                        /*
                        * Ok, we've finished transmitting.  Now enable
@@ -331,9 +399,11 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
                                si->newspeed = 0;
                        } else {
                                /* enable IR Receiver, disable IR Transmitter */
-                               STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
+                               stuart_writel(si, IrSR_IR_RECEIVE_ON |
+                                             IrSR_XMODE_PULSE_1_6, STISR);
                                /* enable STUART and receive interrupts */
-                               STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;
+                               stuart_writel(si, IER_UUE | IER_RLSE |
+                                             IER_RAVIE | IER_RTIOE, STIER);
                        }
                        /* I'm hungry! */
                        netif_wake_queue(dev);
@@ -345,35 +415,32 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 }
 
 /* FIR Receive DMA interrupt handler */
-static void pxa_irda_fir_dma_rx_irq(int channel, void *data)
+static void pxa_irda_fir_dma_rx_irq(void *data)
 {
-       int dcsr = DCSR(channel);
-
-       DCSR(channel) = dcsr & ~DCSR_RUN;
+       struct net_device *dev = data;
+       struct pxa_irda *si = netdev_priv(dev);
 
-       printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr);
+       dmaengine_terminate_all(si->rxdma);
+       netdev_dbg(dev, "pxa_ir: fir rx dma bus error\n");
 }
 
 /* FIR Transmit DMA interrupt handler */
-static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
+static void pxa_irda_fir_dma_tx_irq(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)  {
+       dmaengine_terminate_all(si->txdma);
+       if (dmaengine_tx_status(si->txdma, si->tx_cookie, NULL) == DMA_ERROR) {
+               dev->stats.tx_errors++;
+       } else {
                dev->stats.tx_packets++;
                dev->stats.tx_bytes += si->dma_tx_buff_len;
-       } else {
-               dev->stats.tx_errors++;
        }
 
-       while (ICSR1 & ICSR1_TBY)
+       while (ficp_readl(si, ICSR1) & ICSR1_TBY)
                cpu_relax();
-       si->last_oscr = readl_relaxed(OSCR);
+       si->last_clk = sched_clock();
 
        /*
         * HACK: It looks like the TBY bit is dropped too soon.
@@ -387,11 +454,11 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
        } else {
                int i = 64;
 
-               ICCR0 = 0;
+               ficp_writel(si, 0, ICCR0);
                pxa_irda_fir_dma_rx_start(si);
-               while ((ICSR1 & ICSR1_RNE) && i--)
-                       (void)ICDR;
-               ICCR0 = ICCR0_ITR | ICCR0_RXE;
+               while ((ficp_readl(si, ICSR1) & ICSR1_RNE) && i--)
+                       ficp_readl(si, ICDR);
+               ficp_writel(si, ICCR0_ITR | ICCR0_RXE, ICCR0);
 
                if (i < 0)
                        printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
@@ -403,15 +470,18 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
 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 state;
 
        /* Get the current data position. */
-       len = DTADR(si->rxdma) - si->dma_rx_buff_phy;
+
+       dmaengine_tx_status(si->rxdma, si->rx_cookie, &state);
+       len = IRDA_FRAME_SIZE_LIMIT - state.residue;
 
        do {
                /* Read Status, and then Data.   */
-               stat = ICSR1;
+               stat = ficp_readl(si, ICSR1);
                rmb();
-               data = ICDR;
+               data = ficp_readl(si, ICDR);
 
                if (stat & (ICSR1_CRE | ICSR1_ROR)) {
                        dev->stats.rx_errors++;
@@ -429,7 +499,7 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in
                /* If we hit the end of frame, there's no point in continuing. */
                if (stat & ICSR1_EOF)
                        break;
-       } while (ICSR0 & ICSR0_EIF);
+       } while (ficp_readl(si, ICSR0) & ICSR0_EIF);
 
        if (stat & ICSR1_EOF) {
                /* end of frame. */
@@ -472,9 +542,9 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
        int icsr0, i = 64;
 
        /* stop RX DMA */
-       DCSR(si->rxdma) &= ~DCSR_RUN;
-       si->last_oscr = readl_relaxed(OSCR);
-       icsr0 = ICSR0;
+       dmaengine_terminate_all(si->rxdma);
+       si->last_clk = sched_clock();
+       icsr0 = ficp_readl(si, ICSR0);
 
        if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
                if (icsr0 & ICSR0_FRE) {
@@ -484,7 +554,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
                        printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
                        dev->stats.rx_errors++;
                }
-               ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB);
+               ficp_writel(si, icsr0 & (ICSR0_FRE | ICSR0_RAB), ICSR0);
        }
 
        if (icsr0 & ICSR0_EIF) {
@@ -492,11 +562,11 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
                pxa_irda_fir_irq_eif(si, dev, icsr0);
        }
 
-       ICCR0 = 0;
+       ficp_writel(si, 0, ICCR0);
        pxa_irda_fir_dma_rx_start(si);
-       while ((ICSR1 & ICSR1_RNE) && i--)
-               (void)ICDR;
-       ICCR0 = ICCR0_ITR | ICCR0_RXE;
+       while ((ficp_readl(si, ICSR1) & ICSR1_RNE) && i--)
+               ficp_readl(si, ICDR);
+       ficp_writel(si, ICCR0_ITR | ICCR0_RXE, ICCR0);
 
        if (i < 0)
                printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
@@ -537,11 +607,12 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
                si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize);
 
                /* Disable STUART interrupts and switch to transmit mode. */
-               STIER = 0;
-               STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6;
+               stuart_writel(si, 0, STIER);
+               stuart_writel(si, IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6,
+                             STISR);
 
                /* enable STUART and transmit interrupts */
-               STIER = IER_UUE | IER_TIE;
+               stuart_writel(si, IER_UUE | IER_TIE, STIER);
        } else {
                unsigned long mtt = irda_get_mtt(skb);
 
@@ -549,15 +620,15 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
                skb_copy_from_linear_data(skb, si->dma_tx_buff, skb->len);
 
                if (mtt)
-                       while ((unsigned)(readl_relaxed(OSCR) - si->last_oscr)/4 < mtt)
+                       while ((sched_clock() - si->last_clk) * 1000 < mtt)
                                cpu_relax();
 
                /* stop RX DMA,  disable FICP */
-               DCSR(si->rxdma) &= ~DCSR_RUN;
-               ICCR0 = 0;
+               dmaengine_terminate_all(si->rxdma);
+               ficp_writel(si, 0, ICCR0);
 
                pxa_irda_fir_dma_tx_start(si);
-               ICCR0 = ICCR0_ITR | ICCR0_TXE;
+               ficp_writel(si, ICCR0_ITR | ICCR0_TXE, ICCR0);
        }
 
        dev_kfree_skb(skb);
@@ -613,22 +684,18 @@ static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
 static void pxa_irda_startup(struct pxa_irda *si)
 {
        /* Disable STUART interrupts */
-       STIER = 0;
+       stuart_writel(si, 0, STIER);
        /* enable STUART interrupt to the processor */
-       STMCR = MCR_OUT2;
+       stuart_writel(si, MCR_OUT2, STMCR);
        /* configure SIR frame format: StartBit - Data 7 ... Data 0 - Stop Bit */
-       STLCR = LCR_WLS0 | LCR_WLS1;
+       stuart_writel(si, LCR_WLS0 | LCR_WLS1, STLCR);
        /* enable FIFO, we use FIFO to improve performance */
-       STFCR = FCR_TRFIFOE | FCR_ITL_32;
+       stuart_writel(si, FCR_TRFIFOE | FCR_ITL_32, STFCR);
 
        /* disable FICP */
-       ICCR0 = 0;
+       ficp_writel(si, 0, ICCR0);
        /* configure FICP ICCR2 */
-       ICCR2 = ICCR2_TXP | ICCR2_TRIG_32;
-
-       /* configure DMAC */
-       DRCMR(17) = si->rxdma | DRCMR_MAPVLD;
-       DRCMR(18) = si->txdma | DRCMR_MAPVLD;
+       ficp_writel(si, ICCR2_TXP | ICCR2_TRIG_32, ICCR2);
 
        /* force SIR reinitialization */
        si->speed = 4000000;
@@ -644,22 +711,19 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
        local_irq_save(flags);
 
        /* disable STUART and interrupt */
-       STIER = 0;
+       stuart_writel(si, 0, STIER);
        /* disable STUART SIR mode */
-       STISR = 0;
+       stuart_writel(si, 0, STISR);
 
        /* 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;
+       ficp_writel(si, 0, ICCR0);
 
        /* 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,6 +735,9 @@ 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);
+       dma_cap_mask_t mask;
+       struct dma_slave_config config;
+       struct pxad_param param;
        int err;
 
        si->speed = 9600;
@@ -690,14 +757,37 @@ static int pxa_irda_start(struct net_device *dev)
        disable_irq(si->icp_irq);
 
        err = -EBUSY;
-       si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev);
-       if (si->rxdma < 0)
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+       param.prio = PXAD_PRIO_LOWEST;
+
+       memset(&config, 0, sizeof(config));
+       config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       config.src_addr = (dma_addr_t)si->irda_base + ICDR;
+       config.dst_addr = (dma_addr_t)si->irda_base + ICDR;
+       config.src_maxburst = 32;
+       config.dst_maxburst = 32;
+
+       param.drcmr = si->drcmr_rx;
+       si->rxdma = dma_request_slave_channel_compat(mask, pxad_filter_fn,
+                                                    &param, &dev->dev, "rx");
+       if (!si->rxdma)
                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)
+       param.drcmr = si->drcmr_tx;
+       si->txdma = dma_request_slave_channel_compat(mask, pxad_filter_fn,
+                                                    &param, &dev->dev, "tx");
+       if (!si->txdma)
                goto err_tx_dma;
 
+       err = dmaengine_slave_config(si->rxdma, &config);
+       if (err)
+               goto err_dma_rx_buff;
+       err = dmaengine_slave_config(si->txdma, &config);
+       if (err)
+               goto err_dma_rx_buff;
+
        err = -ENOMEM;
        si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT,
                                             &si->dma_rx_buff_phy, GFP_KERNEL);
@@ -737,9 +827,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 +856,10 @@ 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);
@@ -830,25 +922,33 @@ static const struct net_device_ops pxa_irda_netdev_ops = {
 static int pxa_irda_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
+       struct resource *res;
        struct pxa_irda *si;
+       void __iomem *ficp, *stuart;
        unsigned int baudrate_mask;
        int err;
 
        if (!pdev->dev.platform_data)
                return -ENODEV;
 
-       err = request_mem_region(__PREG(STUART), 0x24, "IrDA") ? 0 : -EBUSY;
-       if (err)
-               goto err_mem_1;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       ficp = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(ficp)) {
+               dev_err(&pdev->dev, "resource ficp not defined\n");
+               return PTR_ERR(ficp);
+       }
 
-       err = request_mem_region(__PREG(FICP), 0x1c, "IrDA") ? 0 : -EBUSY;
-       if (err)
-               goto err_mem_2;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       stuart = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(stuart)) {
+               dev_err(&pdev->dev, "resource stuart not defined\n");
+               return PTR_ERR(stuart);
+       }
 
        dev = alloc_irdadev(sizeof(struct pxa_irda));
        if (!dev) {
                err = -ENOMEM;
-               goto err_mem_3;
+               goto err_mem_1;
        }
 
        SET_NETDEV_DEV(dev, &pdev->dev);
@@ -856,16 +956,25 @@ static int pxa_irda_probe(struct platform_device *pdev)
        si->dev = &pdev->dev;
        si->pdata = pdev->dev.platform_data;
 
+       si->irda_base = ficp;
+       si->stuart_base = stuart;
        si->uart_irq = platform_get_irq(pdev, 0);
        si->icp_irq = platform_get_irq(pdev, 1);
 
-       si->sir_clk = clk_get(&pdev->dev, "UARTCLK");
-       si->fir_clk = clk_get(&pdev->dev, "FICPCLK");
+       si->sir_clk = devm_clk_get(&pdev->dev, "UARTCLK");
+       si->fir_clk = devm_clk_get(&pdev->dev, "FICPCLK");
        if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) {
                err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk);
                goto err_mem_4;
        }
 
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (res)
+               si->drcmr_rx = res->start;
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (res)
+               si->drcmr_tx = res->start;
+
        /*
         * Initialise the SIR buffers
         */
@@ -925,15 +1034,7 @@ err_startup:
 err_mem_5:
                kfree(si->rx_buff.head);
 err_mem_4:
-               if (si->sir_clk && !IS_ERR(si->sir_clk))
-                       clk_put(si->sir_clk);
-               if (si->fir_clk && !IS_ERR(si->fir_clk))
-                       clk_put(si->fir_clk);
                free_netdev(dev);
-err_mem_3:
-               release_mem_region(__PREG(FICP), 0x1c);
-err_mem_2:
-               release_mem_region(__PREG(STUART), 0x24);
        }
 err_mem_1:
        return err;
@@ -952,14 +1053,9 @@ static int pxa_irda_remove(struct platform_device *_dev)
                        si->pdata->shutdown(si->dev);
                kfree(si->tx_buff.head);
                kfree(si->rx_buff.head);
-               clk_put(si->fir_clk);
-               clk_put(si->sir_clk);
                free_netdev(dev);
        }
 
-       release_mem_region(__PREG(STUART), 0x24);
-       release_mem_region(__PREG(FICP), 0x1c);
-
        return 0;
 }