new file mode 100644
@@ -0,0 +1,200 @@
+/*
+ * dma.c - OMAP2 specific DMA code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Author:
+ * Manjunatha GK <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <mach/dma.h>
+
+#include <plat/irqs.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/dma.h>
+
+struct omap_device_pm_latency omap2_dma_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+struct omap_dma_reg_offset dma_reg_offset[] = {
+ {
+ .lch_base = OMAP_DMA4_CH_BASE,
+ .gcr = OMAP_DMA4_GCR,
+ .ocp_sysconfig = OMAP_DMA4_OCP_SYSCONFIG,
+ .rev = OMAP_DMA4_REVISION,
+ .common_ch = {
+ .csdp = OMAP_DMA4_CSDP,
+ .ccr = OMAP_DMA4_CCR,
+ .cicr = OMAP_DMA4_CICR,
+ .csr = OMAP_DMA4_CSR,
+ .csfi = OMAP_DMA4_CSFI,
+ .csei = OMAP_DMA4_CSEI,
+ .cdac = OMAP_DMA4_CDAC,
+ .cdei = OMAP_DMA4_CDEI,
+ .cdfi = OMAP_DMA4_CDFI,
+ .clnk_ctrl = OMAP_DMA4_CLNK_CTRL,
+ .cen = OMAP_DMA4_CEN,
+ .cfn = OMAP_DMA4_CFN,
+ },
+ .ch_specific = {
+ .cssa = OMAP_DMA4_CSSA,
+ .cdsa = OMAP_DMA4_CDSA,
+ },
+ .irqreg = {
+ .irq_status_l0 = OMAP_DMA4_IRQSTATUS_L0,
+ .irq_enable_l0 = OMAP_DMA4_IRQENABLE_L0,
+ },
+
+ .reg_caps = {
+ .caps_0 = OMAP_DMA4_CAPS_0,
+ },
+ },
+};
+struct omap_dma_reg_offset *r = (struct omap_dma_reg_offset *)&dma_reg_offset;
+
+struct omap_dma_dev_attr *d;
+
+static struct omap_system_dma_plat_info *omap2_pdata;
+static void __iomem *dma_base;
+static struct dma_link_info *dma_linked_lch;
+static u32 dma_chan_count;
+
+/* One time initializations */
+static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *user)
+{
+ struct omap_device *od;
+ struct omap_system_dma_plat_info *pdata;
+ struct resource *mem;
+ char *name = "dma";
+
+ pdata = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: Unable to allocate pdata for %s:%s\n",
+ __func__, name, oh->name);
+ return -ENOMEM;
+ }
+
+
+ pdata->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+
+ pdata->dma_reg_offset = r;
+
+ pdata->disable_irq_lch = disable_irq_lch;
+ pdata->enable_irq_lch = enable_irq_lch;
+ pdata->dma_handle_ch = omap2_dma_handle_ch;
+ pdata->clear_lch_regs = NULL;
+ pdata->dma_running = dma_running;
+ pdata->set_prio_lch = set_prio_lch;
+ pdata->dma_irq_register = dma_irq_register;
+ pdata->enable_lnk = omap_enable_lnk;
+ pdata->disable_lnk = omap_disable_lnk;
+ pdata->enable_channel_irq = omap_enable_channel_irq;
+ pdata->disable_channel_irq = omap_disable_channel_irq;
+ pdata->clear_ccr_csr = NULL;
+ pdata->sync_device_set = NULL;
+
+ /* Handling Errata's for all OMAP2PLUS processors */
+ pdata->errata = 0;
+
+ if (cpu_is_omap242x() ||
+ (cpu_is_omap243x() && omap_type() <= OMAP2430_REV_ES1_0))
+ pdata->errata = DMA_CHAINING_ERRATA;
+
+ /*
+ * Errata: On ES2.0 BUFFERING disable must be set.
+ * This will always fail on ES1.0
+ */
+ if (cpu_is_omap24xx())
+ pdata->errata |= DMA_BUFF_DISABLE_ERRATA;
+
+ /*
+ * Errata: OMAP2: sDMA Channel is not disabled
+ * after a transaction error. So we explicitely
+ * disable the channel
+ */
+ if (cpu_class_is_omap2())
+ pdata->errata |= DMA_CH_DISABLE_ERRATA;
+
+ /* Errata: OMAP3 :
+ * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
+ * after secure sram context save and restore. Hence we need to
+ * manually clear those IRQs to avoid spurious interrupts. This
+ * affects only secure devices.
+ */
+ if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ pdata->errata |= DMA_IRQ_STATUS_ERRATA;
+
+ /* Errata3.3: Applicable for all omap2 plus */
+ pdata->errata |= OMAP3_3_ERRATUM;
+
+ od = omap_device_build(name, 0, oh, pdata, sizeof(*pdata),
+ omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
+
+ if (IS_ERR(od)) {
+ pr_err("%s: Cant build omap_device for %s:%s.\n",
+ __func__, name, oh->name);
+ kfree(pdata);
+ return 0;
+ }
+
+ mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&od->pdev.dev, "%s: no mem resource\n", __func__);
+ return -EINVAL;
+ }
+
+ dma_base = ioremap(mem->start, resource_size(mem));
+ if (!dma_base) {
+ dev_err(&od->pdev.dev, "%s: ioremap fail\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Get DMA device attributes from hwmod data base */
+ d = (struct omap_dma_dev_attr *)oh->dev_attr;
+
+ dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
+ d->dma_lch_count, GFP_KERNEL);
+ if (!dma_linked_lch) {
+ int ret;
+ ret = -ENOMEM;
+ kfree(pdata);
+ return ret;
+ }
+ omap2_pdata = pdata;
+
+ pm_runtime_enable(&(od->pdev.dev));
+ return 0;
+}
+
+static int __init omap2_system_dma_init(void)
+{
+ int ret;
+
+ ret = omap_hwmod_for_each_by_class("dma",
+ omap2_system_dma_init_dev, NULL);
+
+ return ret;
+}
+arch_initcall(omap2_system_dma_init);
new file mode 100644
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-omap2/include/mach/dma.h
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Author: Manjunatha GK <manjugk@ti.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_OMAP2_DMA_H
+#define __ASM_ARCH_OMAP2_DMA_H
+#include <plat/dma.h>
+
+/* OMAP2 Plus register offset's */
+#define OMAP_DMA4_REVISION 0x00
+#define OMAP_DMA4_GCR 0x78
+#define OMAP_DMA4_IRQSTATUS_L0 0x08
+#define OMAP_DMA4_IRQSTATUS_L1 0x0c
+#define OMAP_DMA4_IRQSTATUS_L2 0x10
+#define OMAP_DMA4_IRQSTATUS_L3 0x14
+#define OMAP_DMA4_IRQENABLE_L0 0x18
+#define OMAP_DMA4_IRQENABLE_L1 0x1c
+#define OMAP_DMA4_IRQENABLE_L2 0x20
+#define OMAP_DMA4_IRQENABLE_L3 0x24
+#define OMAP_DMA4_SYSSTATUS 0x28
+#define OMAP_DMA4_OCP_SYSCONFIG 0x2c
+#define OMAP_DMA4_CAPS_0 0x64
+#define OMAP_DMA4_CAPS_2 0x6c
+#define OMAP_DMA4_CAPS_3 0x70
+#define OMAP_DMA4_CAPS_4 0x74
+
+/* Should be part of hwmod data base ? */
+#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
+
+/* Common channel specific registers for omap2 */
+#define OMAP_DMA4_CH_BASE (0x60)
+
+#define OMAP_DMA4_CCR (0x80)
+#define OMAP_DMA4_CLNK_CTRL (0x84)
+#define OMAP_DMA4_CICR (0x88)
+#define OMAP_DMA4_CSR (0x8c)
+#define OMAP_DMA4_CSDP (0x90)
+#define OMAP_DMA4_CEN (0x94)
+#define OMAP_DMA4_CFN (0x98)
+#define OMAP_DMA4_CSEI (0xa4)
+#define OMAP_DMA4_CSFI (0xa8)
+#define OMAP_DMA4_CDEI (0xac)
+#define OMAP_DMA4_CDFI (0xb0)
+#define OMAP_DMA4_CSAC (0xb4)
+#define OMAP_DMA4_CDAC (0xb8)
+
+/* Channel specific registers only on omap2 */
+#define OMAP_DMA4_CSSA (0x9c)
+#define OMAP_DMA4_CDSA (0xa0)
+#define OMAP_DMA4_CCEN (0xbc)
+#define OMAP_DMA4_CCFN (0xc0)
+#define OMAP_DMA4_COLOR (0xc4)
+
+/* Additional registers available on OMAP4 */
+#define OMAP_DMA4_CDP (0xd0)
+#define OMAP_DMA4_CNDP (0xd4)
+#define OMAP_DMA4_CCDN (0xd8)
+
+#endif /* __ASM_ARCH_OMAP2_DMA_H */