diff options
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi_nvidia.txt | 5 | ||||
-rw-r--r-- | Documentation/spi/ep93xx_spi | 10 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/core.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/dma-m2p.c | 411 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/dma.c | 108 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/dma.h | 190 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h | 2 | ||||
-rw-r--r-- | drivers/dma/Kconfig | 7 | ||||
-rw-r--r-- | drivers/dma/Makefile | 1 | ||||
-rw-r--r-- | drivers/dma/ep93xx_dma.c | 1355 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 23 | ||||
-rw-r--r-- | drivers/spi/Makefile | 112 | ||||
-rw-r--r-- | drivers/spi/atmel_spi.h | 167 | ||||
-rw-r--r-- | drivers/spi/spi-altera.c (renamed from drivers/spi/spi_altera.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-ath79.c (renamed from drivers/spi/ath79_spi.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-atmel.c (renamed from drivers/spi/atmel_spi.c) | 155 | ||||
-rw-r--r-- | drivers/spi/spi-au1550.c (renamed from drivers/spi/au1550_spi.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-bfin-sport.c (renamed from drivers/spi/spi_bfin_sport.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-bfin5xx.c (renamed from drivers/spi/spi_bfin5xx.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-bitbang-txrx.h (renamed from drivers/spi/spi_bitbang_txrx.h) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-bitbang.c (renamed from drivers/spi/spi_bitbang.c) | 8 | ||||
-rw-r--r-- | drivers/spi/spi-butterfly.c (renamed from drivers/spi/spi_butterfly.c) | 4 | ||||
-rw-r--r-- | drivers/spi/spi-coldfire-qspi.c (renamed from drivers/spi/coldfire_qspi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c (renamed from drivers/spi/davinci_spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-dw-mid.c (renamed from drivers/spi/dw_spi_mid.c) | 4 | ||||
-rw-r--r-- | drivers/spi/spi-dw-mmio.c (renamed from drivers/spi/dw_spi_mmio.c) | 4 | ||||
-rw-r--r-- | drivers/spi/spi-dw-pci.c (renamed from drivers/spi/dw_spi_pci.c) | 4 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c (renamed from drivers/spi/dw_spi.c) | 4 | ||||
-rw-r--r-- | drivers/spi/spi-dw.h (renamed from drivers/spi/dw_spi.h) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-ep93xx.c (renamed from drivers/spi/ep93xx_spi.c) | 303 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-espi.c (renamed from drivers/spi/spi_fsl_espi.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lib.c (renamed from drivers/spi/spi_fsl_lib.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lib.h (renamed from drivers/spi/spi_fsl_lib.h) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-spi.c (renamed from drivers/spi/spi_fsl_spi.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-gpio.c (renamed from drivers/spi/spi_gpio.c) | 6 | ||||
-rw-r--r-- | drivers/spi/spi-imx.c (renamed from drivers/spi/spi_imx.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-lm70llp.c (renamed from drivers/spi/spi_lm70llp.c) | 4 | ||||
-rw-r--r-- | drivers/spi/spi-mpc512x-psc.c (renamed from drivers/spi/mpc512x_psc_spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-mpc52xx-psc.c (renamed from drivers/spi/mpc52xx_psc_spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-mpc52xx.c (renamed from drivers/spi/mpc52xx_spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-nuc900.c (renamed from drivers/spi/spi_nuc900.c) | 5 | ||||
-rw-r--r-- | drivers/spi/spi-oc-tiny.c (renamed from drivers/spi/spi_oc_tiny.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-omap-100k.c (renamed from drivers/spi/omap_spi_100k.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-omap-uwire.c (renamed from drivers/spi/omap_uwire.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c (renamed from drivers/spi/omap2_mcspi.c) | 10 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c (renamed from drivers/spi/orion_spi.c) | 8 | ||||
-rw-r--r-- | drivers/spi/spi-pl022.c (renamed from drivers/spi/amba-pl022.c) | 111 | ||||
-rw-r--r-- | drivers/spi/spi-ppc4xx.c (renamed from drivers/spi/spi_ppc4xx.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx-pci.c (renamed from drivers/spi/pxa2xx_spi_pci.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c (renamed from drivers/spi/pxa2xx_spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-s3c24xx-fiq.S (renamed from drivers/spi/spi_s3c24xx_fiq.S) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-s3c24xx-fiq.h (renamed from drivers/spi/spi_s3c24xx_fiq.h) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-s3c24xx-gpio.c (renamed from drivers/spi/spi_s3c24xx_gpio.c) | 5 | ||||
-rw-r--r-- | drivers/spi/spi-s3c24xx.c (renamed from drivers/spi/spi_s3c24xx.c) | 5 | ||||
-rw-r--r-- | drivers/spi/spi-s3c64xx.c (renamed from drivers/spi/spi_s3c64xx.c) | 3 | ||||
-rw-r--r-- | drivers/spi/spi-sh-msiof.c (renamed from drivers/spi/spi_sh_msiof.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-sh-sci.c (renamed from drivers/spi/spi_sh_sci.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-sh.c (renamed from drivers/spi/spi_sh.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-stmp.c (renamed from drivers/spi/spi_stmp.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-tegra.c (renamed from drivers/spi/spi_tegra.c) | 20 | ||||
-rw-r--r-- | drivers/spi/spi-ti-ssp.c (renamed from drivers/spi/ti-ssp-spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi-tle62x0.c (renamed from drivers/spi/tle62x0.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-topcliff-pch.c (renamed from drivers/spi/spi_topcliff_pch.c) | 1158 | ||||
-rw-r--r-- | drivers/spi/spi-txx9.c (renamed from drivers/spi/spi_txx9.c) | 2 | ||||
-rw-r--r-- | drivers/spi/spi-xilinx.c (renamed from drivers/spi/xilinx_spi.c) | 0 | ||||
-rw-r--r-- | drivers/spi/spi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 2 | ||||
-rw-r--r-- | sound/soc/ep93xx/ep93xx-ac97.c | 4 | ||||
-rw-r--r-- | sound/soc/ep93xx/ep93xx-i2s.c | 4 | ||||
-rw-r--r-- | sound/soc/ep93xx/ep93xx-pcm.c | 137 |
71 files changed, 3096 insertions, 1297 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi_nvidia.txt b/Documentation/devicetree/bindings/spi/spi_nvidia.txt new file mode 100644 index 00000000000..bde450b50fc --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi_nvidia.txt @@ -0,0 +1,5 @@ +NVIDIA Tegra 2 SPI device + +Required properties: +- compatible : should be "nvidia,tegra250-spi". +- gpios : should specify GPIOs used for chipselect. diff --git a/Documentation/spi/ep93xx_spi b/Documentation/spi/ep93xx_spi index 6325f5b4863..d8eb01c15db 100644 --- a/Documentation/spi/ep93xx_spi +++ b/Documentation/spi/ep93xx_spi @@ -88,6 +88,16 @@ static void __init ts72xx_init_machine(void) ARRAY_SIZE(ts72xx_spi_devices)); } +The driver can use DMA for the transfers also. In this case ts72xx_spi_info +becomes: + +static struct ep93xx_spi_info ts72xx_spi_info = { + .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), + .use_dma = true; +}; + +Note that CONFIG_EP93XX_DMA should be enabled as well. + Thanks to ========= Martin Guy, H. Hartley Sweeten and others who helped me during development of diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 33ee2c863d1..21e721ab737 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -1,11 +1,13 @@ # # Makefile for the linux kernel. # -obj-y := core.o clock.o dma-m2p.o gpio.o +obj-y := core.o clock.o gpio.o obj-m := obj-n := obj- := +obj-$(CONFIG_EP93XX_DMA) += dma.o + obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 1d4b65fd673..ce07e0a6f89 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -492,11 +492,15 @@ static struct resource ep93xx_spi_resources[] = { }, }; +static u64 ep93xx_spi_dma_mask = DMA_BIT_MASK(32); + static struct platform_device ep93xx_spi_device = { .name = "ep93xx-spi", .id = 0, .dev = { - .platform_data = &ep93xx_spi_master_data, + .platform_data = &ep93xx_spi_master_data, + .coherent_dma_mask = DMA_BIT_MASK(32), + .dma_mask = &ep93xx_spi_dma_mask, }, .num_resources = ARRAY_SIZE(ep93xx_spi_resources), .resource = ep93xx_spi_resources, diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c deleted file mode 100644 index a696d354b1f..00000000000 --- a/arch/arm/mach-ep93xx/dma-m2p.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * arch/arm/mach-ep93xx/dma-m2p.c - * M2P DMA handling for Cirrus EP93xx chips. - * - * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> - * Copyright (C) 2006 Applied Data Systems - * - * Copyright (C) 2009 Ryan Mallon <ryan@bluewatersys.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -/* - * On the EP93xx chip the following peripherals my be allocated to the 10 - * Memory to Internal Peripheral (M2P) channels (5 transmit + 5 receive). - * - * I2S contains 3 Tx and 3 Rx DMA Channels - * AAC contains 3 Tx and 3 Rx DMA Channels - * UART1 contains 1 Tx and 1 Rx DMA Channels - * UART2 contains 1 Tx and 1 Rx DMA Channels - * UART3 contains 1 Tx and 1 Rx DMA Channels - * IrDA contains 1 Tx and 1 Rx DMA Channels - * - * SSP and IDE use the Memory to Memory (M2M) channels and are not covered - * with this implementation. - */ - -#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/io.h> - -#include <mach/dma.h> -#include <mach/hardware.h> - -#define M2P_CONTROL 0x00 -#define M2P_CONTROL_STALL_IRQ_EN (1 << 0) -#define M2P_CONTROL_NFB_IRQ_EN (1 << 1) -#define M2P_CONTROL_ERROR_IRQ_EN (1 << 3) -#define M2P_CONTROL_ENABLE (1 << 4) -#define M2P_INTERRUPT 0x04 -#define M2P_INTERRUPT_STALL (1 << 0) -#define M2P_INTERRUPT_NFB (1 << 1) -#define M2P_INTERRUPT_ERROR (1 << 3) -#define M2P_PPALLOC 0x08 -#define M2P_STATUS 0x0c -#define M2P_REMAIN 0x14 -#define M2P_MAXCNT0 0x20 -#define M2P_BASE0 0x24 -#define M2P_MAXCNT1 0x30 -#define M2P_BASE1 0x34 - -#define STATE_IDLE 0 /* Channel is inactive. */ -#define STATE_STALL 1 /* Channel is active, no buffers pending. */ -#define STATE_ON 2 /* Channel is active, one buffer pending. */ -#define STATE_NEXT 3 /* Channel is active, two buffers pending. */ - -struct m2p_channel { - char *name; - void __iomem *base; - int irq; - - struct clk *clk; - spinlock_t lock; - - void *client; - unsigned next_slot:1; - struct ep93xx_dma_buffer *buffer_xfer; - struct ep93xx_dma_buffer *buffer_next; - struct list_head buffers_pending; -}; - -static struct m2p_channel m2p_rx[] = { - {"m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1}, - {"m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3}, - {"m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5}, - {"m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7}, - {"m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9}, - {NULL}, -}; - -static struct m2p_channel m2p_tx[] = { - {"m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0}, - {"m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2}, - {"m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4}, - {"m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6}, - {"m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8}, - {NULL}, -}; - -static void feed_buf(struct m2p_channel *ch, struct ep93xx_dma_buffer *buf) -{ - if (ch->next_slot == 0) { - writel(buf->size, ch->base + M2P_MAXCNT0); - writel(buf->bus_addr, ch->base + M2P_BASE0); - } else { - writel(buf->size, ch->base + M2P_MAXCNT1); - writel(buf->bus_addr, ch->base + M2P_BASE1); - } - ch->next_slot ^= 1; -} - -static void choose_buffer_xfer(struct m2p_channel *ch) -{ - struct ep93xx_dma_buffer *buf; - - ch->buffer_xfer = NULL; - if (!list_empty(&ch->buffers_pending)) { - buf = list_entry(ch->buffers_pending.next, - struct ep93xx_dma_buffer, list); - list_del(&buf->list); - feed_buf(ch, buf); - ch->buffer_xfer = buf; - } -} - -static void choose_buffer_next(struct m2p_channel *ch) -{ - struct ep93xx_dma_buffer *buf; - - ch->buffer_next = NULL; - if (!list_empty(&ch->buffers_pending)) { - buf = list_entry(ch->buffers_pending.next, - struct ep93xx_dma_buffer, list); - list_del(&buf->list); - feed_buf(ch, buf); - ch->buffer_next = buf; - } -} - -static inline void m2p_set_control(struct m2p_channel *ch, u32 v) -{ - /* - * The control register must be read immediately after being written so - * that the internal state machine is correctly updated. See the ep93xx - * users' guide for details. - */ - writel(v, ch->base + M2P_CONTROL); - readl(ch->base + M2P_CONTROL); -} - -static inline int m2p_channel_state(struct m2p_channel *ch) -{ - return (readl(ch->base + M2P_STATUS) >> 4) & 0x3; -} - -static irqreturn_t m2p_irq(int irq, void *dev_id) -{ - struct m2p_channel *ch = dev_id; - struct ep93xx_dma_m2p_client *cl; - u32 irq_status, v; - int error = 0; - - cl = ch->client; - - spin_lock(&ch->lock); - irq_status = readl(ch->base + M2P_INTERRUPT); - - if (irq_status & M2P_INTERRUPT_ERROR) { - writel(M2P_INTERRUPT_ERROR, ch->base + M2P_INTERRUPT); - error = 1; - } - - if ((irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) == 0) { - spin_unlock(&ch->lock); - return IRQ_NONE; - } - - switch (m2p_channel_state(ch)) { - case STATE_IDLE: - pr_crit("dma interrupt without a dma buffer\n"); - BUG(); - break; - - case STATE_STALL: - cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error); - if (ch->buffer_next != NULL) { - cl->buffer_finished(cl->cookie, ch->buffer_next, - 0, error); - } - choose_buffer_xfer(ch); - choose_buffer_next(ch); - if (ch->buffer_xfer != NULL) - cl->buffer_started(cl->cookie, ch->buffer_xfer); - break; - - case STATE_ON: - cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error); - ch->buffer_xfer = ch->buffer_next; - choose_buffer_next(ch); - cl->buffer_started(cl->cookie, ch->buffer_xfer); - break; - - case STATE_NEXT: - pr_crit("dma interrupt while next\n"); - BUG(); - break; - } - - v = readl(ch->base + M2P_CONTROL) & ~(M2P_CONTROL_STALL_IRQ_EN | - M2P_CONTROL_NFB_IRQ_EN); - if (ch->buffer_xfer != NULL) - v |= M2P_CONTROL_STALL_IRQ_EN; - if (ch->buffer_next != NULL) - v |= M2P_CONTROL_NFB_IRQ_EN; - m2p_set_control(ch, v); - - spin_unlock(&ch->lock); - return IRQ_HANDLED; -} - -static struct m2p_channel *find_free_channel(struct ep93xx_dma_m2p_client *cl) -{ - struct m2p_channel *ch; - int i; - - if (cl->flags & EP93XX_DMA_M2P_RX) - ch = m2p_rx; - else - ch = m2p_tx; - - for (i = 0; ch[i].base; i++) { - struct ep93xx_dma_m2p_client *client; - - client = ch[i].client; - if (client != NULL) { - int port; - - port = cl->flags & EP93XX_DMA_M2P_PORT_MASK; - if (port == (client->flags & - EP93XX_DMA_M2P_PORT_MASK)) { - pr_warning("DMA channel already used by %s\n", - cl->name ? : "unknown client"); - return ERR_PTR(-EBUSY); - } - } - } - - for (i = 0; ch[i].base; i++) { - if (ch[i].client == NULL) - return ch + i; - } - - pr_warning("No free DMA channel for %s\n", - cl->name ? : "unknown client"); - return ERR_PTR(-ENODEV); -} - -static void channel_enable(struct m2p_channel *ch) -{ - struct ep93xx_dma_m2p_client *cl = ch->client; - u32 v; - - clk_enable(ch->clk); - - v = cl->flags & EP93XX_DMA_M2P_PORT_MASK; - writel(v, ch->base + M2P_PPALLOC); - - v = cl->flags & EP93XX_DMA_M2P_ERROR_MASK; - v |= M2P_CONTROL_ENABLE | M2P_CONTROL_ERROR_IRQ_EN; - m2p_set_control(ch, v); -} - -static void channel_disable(struct m2p_channel *ch) -{ - u32 v; - - v = readl(ch->base + M2P_CONTROL); - v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN); - m2p_set_control(ch, v); - - while (m2p_channel_state(ch) >= STATE_ON) - cpu_relax(); - - m2p_set_control(ch, 0x0); - - while (m2p_channel_state(ch) == STATE_STALL) - cpu_relax(); - - clk_disable(ch->clk); -} - -int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *cl) -{ - struct m2p_channel *ch; - int err; - - ch = find_free_channel(cl); - if (IS_ERR(ch)) - return PTR_ERR(ch); - - err = request_irq(ch->irq, m2p_irq, 0, cl->name ? : "dma-m2p", ch); - if (err) - return err; - - ch->client = cl; - ch->next_slot = 0; - ch->buffer_xfer = NULL; - ch->buffer_next = NULL; - INIT_LIST_HEAD(&ch->buffers_pending); - - cl->channel = ch; - - channel_enable(ch); - - return 0; -} -EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_register); - -void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *cl) -{ - struct m2p_channel *ch = cl->channel; - - channel_disable(ch); - free_irq(ch->irq, ch); - ch->client = NULL; -} -EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_unregister); - -void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *cl, - struct ep93xx_dma_buffer *buf) -{ - struct m2p_channel *ch = cl->channel; - unsigned long flags; - u32 v; - - spin_lock_irqsave(&ch->lock, flags); - v = readl(ch->base + M2P_CONTROL); - if (ch->buffer_xfer == NULL) { - ch->buffer_xfer = buf; - feed_buf(ch, buf); - cl->buffer_started(cl->cookie, buf); - - v |= M2P_CONTROL_STALL_IRQ_EN; - m2p_set_control(ch, v); - - } else if (ch->buffer_next == NULL) { - ch->buffer_next = buf; - feed_buf(ch, buf); - - v |= M2P_CONTROL_NFB_IRQ_EN; - m2p_set_control(ch, v); - } else { - list_add_tail(&buf->list, &ch->buffers_pending); - } - spin_unlock_irqrestore(&ch->lock, flags); -} -EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit); - -void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *cl, - struct ep93xx_dma_buffer *buf) -{ - struct m2p_channel *ch = cl->channel; - - list_add_tail(&buf->list, &ch->buffers_pending); -} -EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit_recursive); - -void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *cl) -{ - struct m2p_channel *ch = cl->channel; - - channel_disable(ch); - ch->next_slot = 0; - ch->buffer_xfer = NULL; - ch->buffer_next = NULL; - INIT_LIST_HEAD(&ch->buffers_pending); - channel_enable(ch); -} -EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_flush); - -static int init_channel(struct m2p_channel *ch) -{ - ch->clk = clk_get(NULL, ch->name); - if (IS_ERR(ch->clk)) - return PTR_ERR(ch->clk); - - spin_lock_init(&ch->lock); - ch->client = NULL; - - return 0; -} - -static int __init ep93xx_dma_m2p_init(void) -{ - int i; - int ret; - - for (i = 0; m2p_rx[i].base; i++) { - ret = init_channel(m2p_rx + i); - if (ret) - return ret; - } - - for (i = 0; m2p_tx[i].base; i++) { - ret = init_channel(m2p_tx + i); - if (ret) - return ret; - } - - pr_info("M2P DMA subsystem initialized\n"); - return 0; -} -arch_initcall(ep93xx_dma_m2p_init); diff --git a/arch/arm/mach-ep93xx/dma.c b/arch/arm/mach-ep93xx/dma.c new file mode 100644 index 00000000000..5a257088125 --- /dev/null +++ b/arch/arm/mach-ep93xx/dma.c @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-ep93xx/dma.c + * + * Platform support code for the EP93xx dmaengine driver. + * + * Copyright (C) 2011 Mika Westerberg + * + * This work is based on the original dma-m2p implementation with + * following copyrights: + * + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> + * Copyright (C) 2006 Applied Data Systems + * Copyright (C) 2009 Ryan Mallon <rmallon@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include <linux/dmaengine.h> +#include <linux/dma-mapping.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> |