Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: irda: pxaficp_ir: dmaengine conversion

Convert pxaficp_ir to dmaengine. As pxa architecture is shifting from
raw DMA registers access to pxa_dma dmaengine driver, convert this
driver to dmaengine.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Tested-by: Petr Cvek <petr.cvek@tul.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Robert Jarzmik and committed by
David S. Miller
1273bc57 89fa5724

+106 -51
+106 -51
drivers/net/irda/pxaficp_ir.c
··· 19 19 #include <linux/etherdevice.h> 20 20 #include <linux/platform_device.h> 21 21 #include <linux/clk.h> 22 + #include <linux/dmaengine.h> 23 + #include <linux/dma-mapping.h> 24 + #include <linux/dma/pxa-dma.h> 22 25 #include <linux/gpio.h> 23 26 #include <linux/slab.h> 24 27 ··· 30 27 #include <net/irda/wrapper.h> 31 28 #include <net/irda/irda_device.h> 32 29 33 - #include <mach/dma.h> 34 30 #include <linux/platform_data/irda-pxaficp.h> 35 31 #undef __REG 36 32 #define __REG(x) ((x) & 0xffff) ··· 148 146 dma_addr_t dma_rx_buff_phy; 149 147 dma_addr_t dma_tx_buff_phy; 150 148 unsigned int dma_tx_buff_len; 151 - int txdma; 152 - int rxdma; 149 + struct dma_chan *txdma; 150 + struct dma_chan *rxdma; 151 + dma_cookie_t rx_cookie; 152 + dma_cookie_t tx_cookie; 153 + int drcmr_rx; 154 + int drcmr_tx; 153 155 154 156 int uart_irq; 155 157 int icp_irq; ··· 170 164 struct clk *sir_clk; 171 165 struct clk *cur_clk; 172 166 }; 167 + 168 + static int pxa_irda_set_speed(struct pxa_irda *si, int speed); 173 169 174 170 static inline void pxa_irda_disable_clk(struct pxa_irda *si) 175 171 { ··· 196 188 #define IS_FIR(si) ((si)->speed >= 4000000) 197 189 #define IRDA_FRAME_SIZE_LIMIT 2047 198 190 191 + static void pxa_irda_fir_dma_rx_irq(void *data); 192 + static void pxa_irda_fir_dma_tx_irq(void *data); 193 + 199 194 inline static void pxa_irda_fir_dma_rx_start(struct pxa_irda *si) 200 195 { 201 - DCSR(si->rxdma) = DCSR_NODESC; 202 - DSADR(si->rxdma) = (unsigned long)si->irda_base + ICDR; 203 - DTADR(si->rxdma) = si->dma_rx_buff_phy; 204 - DCMD(si->rxdma) = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 | DCMD_BURST32 | IRDA_FRAME_SIZE_LIMIT; 205 - DCSR(si->rxdma) |= DCSR_RUN; 196 + struct dma_async_tx_descriptor *tx; 197 + 198 + tx = dmaengine_prep_slave_single(si->rxdma, si->dma_rx_buff_phy, 199 + IRDA_FRAME_SIZE_LIMIT, DMA_FROM_DEVICE, 200 + DMA_PREP_INTERRUPT); 201 + if (!tx) { 202 + dev_err(si->dev, "prep_slave_sg() failed\n"); 203 + return; 204 + } 205 + tx->callback = pxa_irda_fir_dma_rx_irq; 206 + tx->callback_param = si; 207 + si->rx_cookie = dmaengine_submit(tx); 208 + dma_async_issue_pending(si->rxdma); 206 209 } 207 210 208 211 inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si) 209 212 { 210 - DCSR(si->txdma) = DCSR_NODESC; 211 - DSADR(si->txdma) = si->dma_tx_buff_phy; 212 - DTADR(si->txdma) = (unsigned long)si->irda_base + ICDR; 213 - DCMD(si->txdma) = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_ENDIRQEN | DCMD_WIDTH1 | DCMD_BURST32 | si->dma_tx_buff_len; 214 - DCSR(si->txdma) |= DCSR_RUN; 213 + struct dma_async_tx_descriptor *tx; 214 + 215 + tx = dmaengine_prep_slave_single(si->txdma, si->dma_tx_buff_phy, 216 + si->dma_tx_buff_len, DMA_TO_DEVICE, 217 + DMA_PREP_INTERRUPT); 218 + if (!tx) { 219 + dev_err(si->dev, "prep_slave_sg() failed\n"); 220 + return; 221 + } 222 + tx->callback = pxa_irda_fir_dma_tx_irq; 223 + tx->callback_param = si; 224 + si->tx_cookie = dmaengine_submit(tx); 225 + dma_async_issue_pending(si->rxdma); 215 226 } 216 227 217 228 /* ··· 269 242 270 243 if (IS_FIR(si)) { 271 244 /* stop RX DMA */ 272 - DCSR(si->rxdma) &= ~DCSR_RUN; 245 + dmaengine_terminate_all(si->rxdma); 273 246 /* disable FICP */ 274 247 ficp_writel(si, 0, ICCR0); 275 248 pxa_irda_disable_clk(si); ··· 415 388 } 416 389 417 390 /* FIR Receive DMA interrupt handler */ 418 - static void pxa_irda_fir_dma_rx_irq(int channel, void *data) 419 - { 420 - int dcsr = DCSR(channel); 421 - 422 - DCSR(channel) = dcsr & ~DCSR_RUN; 423 - 424 - printk(KERN_DEBUG "pxa_ir: fir rx dma bus error %#x\n", dcsr); 425 - } 426 - 427 - /* FIR Transmit DMA interrupt handler */ 428 - static void pxa_irda_fir_dma_tx_irq(int channel, void *data) 391 + static void pxa_irda_fir_dma_rx_irq(void *data) 429 392 { 430 393 struct net_device *dev = data; 431 394 struct pxa_irda *si = netdev_priv(dev); 432 - int dcsr; 433 395 434 - dcsr = DCSR(channel); 435 - DCSR(channel) = dcsr & ~DCSR_RUN; 396 + dmaengine_terminate_all(si->rxdma); 397 + netdev_dbg(dev, "pxa_ir: fir rx dma bus error\n"); 398 + } 436 399 437 - if (dcsr & DCSR_ENDINTR) { 400 + /* FIR Transmit DMA interrupt handler */ 401 + static void pxa_irda_fir_dma_tx_irq(void *data) 402 + { 403 + struct net_device *dev = data; 404 + struct pxa_irda *si = netdev_priv(dev); 405 + 406 + dmaengine_terminate_all(si->txdma); 407 + if (dmaengine_tx_status(si->txdma, si->tx_cookie, NULL) == DMA_ERROR) { 408 + dev->stats.tx_errors++; 409 + } else { 438 410 dev->stats.tx_packets++; 439 411 dev->stats.tx_bytes += si->dma_tx_buff_len; 440 - } else { 441 - dev->stats.tx_errors++; 442 412 } 443 413 444 414 while (ficp_readl(si, ICSR1) & ICSR1_TBY) ··· 470 446 static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0) 471 447 { 472 448 unsigned int len, stat, data; 449 + struct dma_tx_state state; 473 450 474 451 /* Get the current data position. */ 475 - len = DTADR(si->rxdma) - si->dma_rx_buff_phy; 452 + 453 + dmaengine_tx_status(si->rxdma, si->rx_cookie, &state); 454 + len = IRDA_FRAME_SIZE_LIMIT - state.residue; 476 455 477 456 do { 478 457 /* Read Status, and then Data. */ ··· 542 515 int icsr0, i = 64; 543 516 544 517 /* stop RX DMA */ 545 - DCSR(si->rxdma) &= ~DCSR_RUN; 518 + dmaengine_terminate_all(si->rxdma); 546 519 si->last_clk = sched_clock(); 547 520 icsr0 = ficp_readl(si, ICSR0); 548 521 ··· 624 597 cpu_relax(); 625 598 626 599 /* stop RX DMA, disable FICP */ 627 - DCSR(si->rxdma) &= ~DCSR_RUN; 600 + dmaengine_terminate_all(si->rxdma); 628 601 ficp_writel(si, 0, ICCR0); 629 602 630 603 pxa_irda_fir_dma_tx_start(si); ··· 697 670 /* configure FICP ICCR2 */ 698 671 ficp_writel(si, ICCR2_TXP | ICCR2_TRIG_32, ICCR2); 699 672 700 - /* configure DMAC */ 701 - DRCMR(17) = si->rxdma | DRCMR_MAPVLD; 702 - DRCMR(18) = si->txdma | DRCMR_MAPVLD; 703 - 704 673 /* force SIR reinitialization */ 705 674 si->speed = 4000000; 706 675 pxa_irda_set_speed(si, 9600); ··· 716 693 stuart_writel(si, 0, STISR); 717 694 718 695 /* disable DMA */ 719 - DCSR(si->txdma) &= ~DCSR_RUN; 720 - DCSR(si->rxdma) &= ~DCSR_RUN; 696 + dmaengine_terminate_all(si->rxdma); 697 + dmaengine_terminate_all(si->txdma); 721 698 /* disable FICP */ 722 699 ficp_writel(si, 0, ICCR0); 723 700 724 701 /* disable the STUART or FICP clocks */ 725 702 pxa_irda_disable_clk(si); 726 - 727 - DRCMR(17) = 0; 728 - DRCMR(18) = 0; 729 703 730 704 local_irq_restore(flags); 731 705 ··· 735 715 static int pxa_irda_start(struct net_device *dev) 736 716 { 737 717 struct pxa_irda *si = netdev_priv(dev); 718 + dma_cap_mask_t mask; 719 + struct dma_slave_config config; 720 + struct pxad_param param; 738 721 int err; 739 722 740 723 si->speed = 9600; ··· 757 734 disable_irq(si->icp_irq); 758 735 759 736 err = -EBUSY; 760 - si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev); 761 - if (si->rxdma < 0) 737 + dma_cap_zero(mask); 738 + dma_cap_set(DMA_SLAVE, mask); 739 + param.prio = PXAD_PRIO_LOWEST; 740 + 741 + memset(&config, 0, sizeof(config)); 742 + config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 743 + config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; 744 + config.src_addr = (dma_addr_t)si->irda_base + ICDR; 745 + config.dst_addr = (dma_addr_t)si->irda_base + ICDR; 746 + config.src_maxburst = 32; 747 + config.dst_maxburst = 32; 748 + 749 + param.drcmr = si->drcmr_rx; 750 + si->rxdma = dma_request_slave_channel_compat(mask, pxad_filter_fn, 751 + &param, &dev->dev, "rx"); 752 + if (!si->rxdma) 762 753 goto err_rx_dma; 763 754 764 - si->txdma = pxa_request_dma("FICP_TX",DMA_PRIO_LOW, pxa_irda_fir_dma_tx_irq, dev); 765 - if (si->txdma < 0) 755 + param.drcmr = si->drcmr_tx; 756 + si->txdma = dma_request_slave_channel_compat(mask, pxad_filter_fn, 757 + &param, &dev->dev, "tx"); 758 + if (!si->txdma) 766 759 goto err_tx_dma; 760 + 761 + err = dmaengine_slave_config(si->rxdma, &config); 762 + if (err) 763 + goto err_dma_rx_buff; 764 + err = dmaengine_slave_config(si->txdma, &config); 765 + if (err) 766 + goto err_dma_rx_buff; 767 767 768 768 err = -ENOMEM; 769 769 si->dma_rx_buff = dma_alloc_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, ··· 827 781 err_dma_tx_buff: 828 782 dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_rx_buff, si->dma_rx_buff_phy); 829 783 err_dma_rx_buff: 830 - pxa_free_dma(si->txdma); 784 + dma_release_channel(si->txdma); 831 785 err_tx_dma: 832 - pxa_free_dma(si->rxdma); 786 + dma_release_channel(si->rxdma); 833 787 err_rx_dma: 834 788 free_irq(si->icp_irq, dev); 835 789 err_irq2: ··· 856 810 free_irq(si->uart_irq, dev); 857 811 free_irq(si->icp_irq, dev); 858 812 859 - pxa_free_dma(si->rxdma); 860 - pxa_free_dma(si->txdma); 813 + dmaengine_terminate_all(si->rxdma); 814 + dmaengine_terminate_all(si->txdma); 815 + dma_release_channel(si->rxdma); 816 + dma_release_channel(si->txdma); 861 817 862 818 if (si->dma_rx_buff) 863 819 dma_free_coherent(si->dev, IRDA_FRAME_SIZE_LIMIT, si->dma_tx_buff, si->dma_tx_buff_phy); ··· 967 919 err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk); 968 920 goto err_mem_4; 969 921 } 922 + 923 + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 924 + if (res) 925 + si->drcmr_rx = res->start; 926 + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 927 + if (res) 928 + si->drcmr_tx = res->start; 970 929 971 930 /* 972 931 * Initialise the SIR buffers