159de3cf1SG, Manjunath Kondaiah /* 259de3cf1SG, Manjunath Kondaiah * OMAP2+ DMA driver 359de3cf1SG, Manjunath Kondaiah * 459de3cf1SG, Manjunath Kondaiah * Copyright (C) 2003 - 2008 Nokia Corporation 559de3cf1SG, Manjunath Kondaiah * Author: Juha Yrjölä <juha.yrjola@nokia.com> 659de3cf1SG, Manjunath Kondaiah * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> 759de3cf1SG, Manjunath Kondaiah * Graphics DMA and LCD DMA graphics tranformations 859de3cf1SG, Manjunath Kondaiah * by Imre Deak <imre.deak@nokia.com> 959de3cf1SG, Manjunath Kondaiah * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. 1059de3cf1SG, Manjunath Kondaiah * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 1159de3cf1SG, Manjunath Kondaiah * 1259de3cf1SG, Manjunath Kondaiah * Copyright (C) 2009 Texas Instruments 1359de3cf1SG, Manjunath Kondaiah * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 1459de3cf1SG, Manjunath Kondaiah * 1559de3cf1SG, Manjunath Kondaiah * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 1659de3cf1SG, Manjunath Kondaiah * Converted DMA library into platform driver 1759de3cf1SG, Manjunath Kondaiah * - G, Manjunath Kondaiah <manjugk@ti.com> 1859de3cf1SG, Manjunath Kondaiah * 1959de3cf1SG, Manjunath Kondaiah * This program is free software; you can redistribute it and/or modify 2059de3cf1SG, Manjunath Kondaiah * it under the terms of the GNU General Public License version 2 as 2159de3cf1SG, Manjunath Kondaiah * published by the Free Software Foundation. 2259de3cf1SG, Manjunath Kondaiah */ 2359de3cf1SG, Manjunath Kondaiah 2459de3cf1SG, Manjunath Kondaiah #include <linux/err.h> 2559de3cf1SG, Manjunath Kondaiah #include <linux/io.h> 2659de3cf1SG, Manjunath Kondaiah #include <linux/slab.h> 2759de3cf1SG, Manjunath Kondaiah #include <linux/module.h> 2859de3cf1SG, Manjunath Kondaiah #include <linux/init.h> 2959de3cf1SG, Manjunath Kondaiah #include <linux/device.h> 30be1f9481STony Lindgren #include <linux/dma-mapping.h> 318d30662aSJon Hunter #include <linux/of.h> 3245c3eb7dSTony Lindgren #include <linux/omap-dma.h> 3359de3cf1SG, Manjunath Kondaiah 34e4c060dbSTony Lindgren #include "soc.h" 352a296c8fSTony Lindgren #include "omap_hwmod.h" 3625c7d49eSTony Lindgren #include "omap_device.h" 3725c7d49eSTony Lindgren 38f31cc962SG, Manjunath Kondaiah #define OMAP2_DMA_STRIDE 0x60 39f31cc962SG, Manjunath Kondaiah 40f31cc962SG, Manjunath Kondaiah static u32 errata; 41f31cc962SG, Manjunath Kondaiah static u8 dma_stride; 42f31cc962SG, Manjunath Kondaiah 43f31cc962SG, Manjunath Kondaiah static struct omap_dma_dev_attr *d; 44f31cc962SG, Manjunath Kondaiah 45f31cc962SG, Manjunath Kondaiah static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end; 46f31cc962SG, Manjunath Kondaiah 47f31cc962SG, Manjunath Kondaiah static u16 reg_map[] = { 48f31cc962SG, Manjunath Kondaiah [REVISION] = 0x00, 49f31cc962SG, Manjunath Kondaiah [GCR] = 0x78, 50f31cc962SG, Manjunath Kondaiah [IRQSTATUS_L0] = 0x08, 51f31cc962SG, Manjunath Kondaiah [IRQSTATUS_L1] = 0x0c, 52f31cc962SG, Manjunath Kondaiah [IRQSTATUS_L2] = 0x10, 53f31cc962SG, Manjunath Kondaiah [IRQSTATUS_L3] = 0x14, 54f31cc962SG, Manjunath Kondaiah [IRQENABLE_L0] = 0x18, 55f31cc962SG, Manjunath Kondaiah [IRQENABLE_L1] = 0x1c, 56f31cc962SG, Manjunath Kondaiah [IRQENABLE_L2] = 0x20, 57f31cc962SG, Manjunath Kondaiah [IRQENABLE_L3] = 0x24, 58f31cc962SG, Manjunath Kondaiah [SYSSTATUS] = 0x28, 59f31cc962SG, Manjunath Kondaiah [OCP_SYSCONFIG] = 0x2c, 60f31cc962SG, Manjunath Kondaiah [CAPS_0] = 0x64, 61f31cc962SG, Manjunath Kondaiah [CAPS_2] = 0x6c, 62f31cc962SG, Manjunath Kondaiah [CAPS_3] = 0x70, 63f31cc962SG, Manjunath Kondaiah [CAPS_4] = 0x74, 64f31cc962SG, Manjunath Kondaiah 65f31cc962SG, Manjunath Kondaiah /* Common register offsets */ 66f31cc962SG, Manjunath Kondaiah [CCR] = 0x80, 67f31cc962SG, Manjunath Kondaiah [CLNK_CTRL] = 0x84, 68f31cc962SG, Manjunath Kondaiah [CICR] = 0x88, 69f31cc962SG, Manjunath Kondaiah [CSR] = 0x8c, 70f31cc962SG, Manjunath Kondaiah [CSDP] = 0x90, 71f31cc962SG, Manjunath Kondaiah [CEN] = 0x94, 72f31cc962SG, Manjunath Kondaiah [CFN] = 0x98, 73f31cc962SG, Manjunath Kondaiah [CSEI] = 0xa4, 74f31cc962SG, Manjunath Kondaiah [CSFI] = 0xa8, 75f31cc962SG, Manjunath Kondaiah [CDEI] = 0xac, 76f31cc962SG, Manjunath Kondaiah [CDFI] = 0xb0, 77f31cc962SG, Manjunath Kondaiah [CSAC] = 0xb4, 78f31cc962SG, Manjunath Kondaiah [CDAC] = 0xb8, 79f31cc962SG, Manjunath Kondaiah 80f31cc962SG, Manjunath Kondaiah /* Channel specific register offsets */ 81f31cc962SG, Manjunath Kondaiah [CSSA] = 0x9c, 82f31cc962SG, Manjunath Kondaiah [CDSA] = 0xa0, 83f31cc962SG, Manjunath Kondaiah [CCEN] = 0xbc, 84f31cc962SG, Manjunath Kondaiah [CCFN] = 0xc0, 85f31cc962SG, Manjunath Kondaiah [COLOR] = 0xc4, 86f31cc962SG, Manjunath Kondaiah 87f31cc962SG, Manjunath Kondaiah /* OMAP4 specific registers */ 88f31cc962SG, Manjunath Kondaiah [CDP] = 0xd0, 89f31cc962SG, Manjunath Kondaiah [CNDP] = 0xd4, 90f31cc962SG, Manjunath Kondaiah [CCDN] = 0xd8, 91f31cc962SG, Manjunath Kondaiah }; 92f31cc962SG, Manjunath Kondaiah 93f31cc962SG, Manjunath Kondaiah static void __iomem *dma_base; 94f31cc962SG, Manjunath Kondaiah static inline void dma_write(u32 val, int reg, int lch) 95f31cc962SG, Manjunath Kondaiah { 96f31cc962SG, Manjunath Kondaiah u8 stride; 97f31cc962SG, Manjunath Kondaiah u32 offset; 98f31cc962SG, Manjunath Kondaiah 99f31cc962SG, Manjunath Kondaiah stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 100f31cc962SG, Manjunath Kondaiah offset = reg_map[reg] + (stride * lch); 101f31cc962SG, Manjunath Kondaiah __raw_writel(val, dma_base + offset); 102f31cc962SG, Manjunath Kondaiah } 103f31cc962SG, Manjunath Kondaiah 104f31cc962SG, Manjunath Kondaiah static inline u32 dma_read(int reg, int lch) 105f31cc962SG, Manjunath Kondaiah { 106f31cc962SG, Manjunath Kondaiah u8 stride; 107f31cc962SG, Manjunath Kondaiah u32 offset, val; 108f31cc962SG, Manjunath Kondaiah 109f31cc962SG, Manjunath Kondaiah stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 110f31cc962SG, Manjunath Kondaiah offset = reg_map[reg] + (stride * lch); 111f31cc962SG, Manjunath Kondaiah val = __raw_readl(dma_base + offset); 112f31cc962SG, Manjunath Kondaiah return val; 113f31cc962SG, Manjunath Kondaiah } 114f31cc962SG, Manjunath Kondaiah 115f31cc962SG, Manjunath Kondaiah static inline void omap2_disable_irq_lch(int lch) 116f31cc962SG, Manjunath Kondaiah { 117f31cc962SG, Manjunath Kondaiah u32 val; 118f31cc962SG, Manjunath Kondaiah 119f31cc962SG, Manjunath Kondaiah val = dma_read(IRQENABLE_L0, lch); 120f31cc962SG, Manjunath Kondaiah val &= ~(1 << lch); 121f31cc962SG, Manjunath Kondaiah dma_write(val, IRQENABLE_L0, lch); 122f31cc962SG, Manjunath Kondaiah } 123f31cc962SG, Manjunath Kondaiah 124f31cc962SG, Manjunath Kondaiah static void omap2_clear_dma(int lch) 125f31cc962SG, Manjunath Kondaiah { 126f31cc962SG, Manjunath Kondaiah int i = dma_common_ch_start; 127f31cc962SG, Manjunath Kondaiah 128f31cc962SG, Manjunath Kondaiah for (; i <= dma_common_ch_end; i += 1) 129f31cc962SG, Manjunath Kondaiah dma_write(0, i, lch); 130f31cc962SG, Manjunath Kondaiah } 131f31cc962SG, Manjunath Kondaiah 132f31cc962SG, Manjunath Kondaiah static void omap2_show_dma_caps(void) 133f31cc962SG, Manjunath Kondaiah { 134f31cc962SG, Manjunath Kondaiah u8 revision = dma_read(REVISION, 0) & 0xff; 135f31cc962SG, Manjunath Kondaiah printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", 136f31cc962SG, Manjunath Kondaiah revision >> 4, revision & 0xf); 137f31cc962SG, Manjunath Kondaiah return; 138f31cc962SG, Manjunath Kondaiah } 139f31cc962SG, Manjunath Kondaiah 140f31cc962SG, Manjunath Kondaiah static u32 configure_dma_errata(void) 141f31cc962SG, Manjunath Kondaiah { 142f31cc962SG, Manjunath Kondaiah 143f31cc962SG, Manjunath Kondaiah /* 144f31cc962SG, Manjunath Kondaiah * Errata applicable for OMAP2430ES1.0 and all omap2420 145f31cc962SG, Manjunath Kondaiah * 146f31cc962SG, Manjunath Kondaiah * I. 147f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 148f31cc962SG, Manjunath Kondaiah * Inter Frame DMA buffering issue DMA will wrongly 149f31cc962SG, Manjunath Kondaiah * buffer elements if packing and bursting is enabled. This might 150f31cc962SG, Manjunath Kondaiah * result in data gets stalled in FIFO at the end of the block. 151f31cc962SG, Manjunath Kondaiah * Workaround: DMA channels must have BUFFERING_DISABLED bit set to 152f31cc962SG, Manjunath Kondaiah * guarantee no data will stay in the DMA FIFO in case inter frame 153f31cc962SG, Manjunath Kondaiah * buffering occurs 154f31cc962SG, Manjunath Kondaiah * 155f31cc962SG, Manjunath Kondaiah * II. 156f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 157f31cc962SG, Manjunath Kondaiah * DMA may hang when several channels are used in parallel 158f31cc962SG, Manjunath Kondaiah * In the following configuration, DMA channel hanging can occur: 159f31cc962SG, Manjunath Kondaiah * a. Channel i, hardware synchronized, is enabled 160f31cc962SG, Manjunath Kondaiah * b. Another channel (Channel x), software synchronized, is enabled. 161f31cc962SG, Manjunath Kondaiah * c. Channel i is disabled before end of transfer 162f31cc962SG, Manjunath Kondaiah * d. Channel i is reenabled. 163f31cc962SG, Manjunath Kondaiah * e. Steps 1 to 4 are repeated a certain number of times. 164f31cc962SG, Manjunath Kondaiah * f. A third channel (Channel y), software synchronized, is enabled. 165f31cc962SG, Manjunath Kondaiah * Channel x and Channel y may hang immediately after step 'f'. 166f31cc962SG, Manjunath Kondaiah * Workaround: 167f31cc962SG, Manjunath Kondaiah * For any channel used - make sure NextLCH_ID is set to the value j. 168f31cc962SG, Manjunath Kondaiah */ 169f31cc962SG, Manjunath Kondaiah if (cpu_is_omap2420() || (cpu_is_omap2430() && 170f31cc962SG, Manjunath Kondaiah (omap_type() == OMAP2430_REV_ES1_0))) { 171f31cc962SG, Manjunath Kondaiah 172f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING); 173f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS); 174f31cc962SG, Manjunath Kondaiah } 175f31cc962SG, Manjunath Kondaiah 176f31cc962SG, Manjunath Kondaiah /* 177f31cc962SG, Manjunath Kondaiah * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled 178f31cc962SG, Manjunath Kondaiah * after a transaction error. 179f31cc962SG, Manjunath Kondaiah * Workaround: SW should explicitely disable the channel. 180f31cc962SG, Manjunath Kondaiah */ 181f31cc962SG, Manjunath Kondaiah if (cpu_class_is_omap2()) 182f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i378); 183f31cc962SG, Manjunath Kondaiah 184f31cc962SG, Manjunath Kondaiah /* 185f31cc962SG, Manjunath Kondaiah * Erratum ID: i541: sDMA FIFO draining does not finish 186f31cc962SG, Manjunath Kondaiah * If sDMA channel is disabled on the fly, sDMA enters standby even 187f31cc962SG, Manjunath Kondaiah * through FIFO Drain is still in progress 188f31cc962SG, Manjunath Kondaiah * Workaround: Put sDMA in NoStandby more before a logical channel is 189f31cc962SG, Manjunath Kondaiah * disabled, then put it back to SmartStandby right after the channel 190f31cc962SG, Manjunath Kondaiah * finishes FIFO draining. 191f31cc962SG, Manjunath Kondaiah */ 192f31cc962SG, Manjunath Kondaiah if (cpu_is_omap34xx()) 193f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i541); 194f31cc962SG, Manjunath Kondaiah 195f31cc962SG, Manjunath Kondaiah /* 196f31cc962SG, Manjunath Kondaiah * Erratum ID: i88 : Special programming model needed to disable DMA 197f31cc962SG, Manjunath Kondaiah * before end of block. 198f31cc962SG, Manjunath Kondaiah * Workaround: software must ensure that the DMA is configured in No 199f31cc962SG, Manjunath Kondaiah * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01") 200f31cc962SG, Manjunath Kondaiah */ 201f31cc962SG, Manjunath Kondaiah if (omap_type() == OMAP3430_REV_ES1_0) 202f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i88); 203f31cc962SG, Manjunath Kondaiah 204f31cc962SG, Manjunath Kondaiah /* 205f31cc962SG, Manjunath Kondaiah * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is 206f31cc962SG, Manjunath Kondaiah * read before the DMA controller finished disabling the channel. 207f31cc962SG, Manjunath Kondaiah */ 208f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_3_3); 209f31cc962SG, Manjunath Kondaiah 210f31cc962SG, Manjunath Kondaiah /* 211f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 212f31cc962SG, Manjunath Kondaiah * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared 213f31cc962SG, Manjunath Kondaiah * after secure sram context save and restore. 214f31cc962SG, Manjunath Kondaiah * Work around: Hence we need to manually clear those IRQs to avoid 215f31cc962SG, Manjunath Kondaiah * spurious interrupts. This affects only secure devices. 216f31cc962SG, Manjunath Kondaiah */ 217f31cc962SG, Manjunath Kondaiah if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 218f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ROMCODE_BUG); 219f31cc962SG, Manjunath Kondaiah 220f31cc962SG, Manjunath Kondaiah return errata; 221f31cc962SG, Manjunath Kondaiah } 222f31cc962SG, Manjunath Kondaiah 22359de3cf1SG, Manjunath Kondaiah /* One time initializations */ 22459de3cf1SG, Manjunath Kondaiah static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) 22559de3cf1SG, Manjunath Kondaiah { 2263528c58eSKevin Hilman struct platform_device *pdev; 22759de3cf1SG, Manjunath Kondaiah struct omap_system_dma_plat_info *p; 228f31cc962SG, Manjunath Kondaiah struct resource *mem; 22959de3cf1SG, Manjunath Kondaiah char *name = "omap_dma_system"; 23059de3cf1SG, Manjunath Kondaiah 231f31cc962SG, Manjunath Kondaiah dma_stride = OMAP2_DMA_STRIDE; 232f31cc962SG, Manjunath Kondaiah dma_common_ch_start = CSDP; 233f31cc962SG, Manjunath Kondaiah 23459de3cf1SG, Manjunath Kondaiah p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL); 23559de3cf1SG, Manjunath Kondaiah if (!p) { 23659de3cf1SG, Manjunath Kondaiah pr_err("%s: Unable to allocate pdata for %s:%s\n", 23759de3cf1SG, Manjunath Kondaiah __func__, name, oh->name); 23859de3cf1SG, Manjunath Kondaiah return -ENOMEM; 23959de3cf1SG, Manjunath Kondaiah } 24059de3cf1SG, Manjunath Kondaiah 241f31cc962SG, Manjunath Kondaiah p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; 242f31cc962SG, Manjunath Kondaiah p->disable_irq_lch = omap2_disable_irq_lch; 243f31cc962SG, Manjunath Kondaiah p->show_dma_caps = omap2_show_dma_caps; 244f31cc962SG, Manjunath Kondaiah p->clear_dma = omap2_clear_dma; 245f31cc962SG, Manjunath Kondaiah p->dma_write = dma_write; 246f31cc962SG, Manjunath Kondaiah p->dma_read = dma_read; 247f31cc962SG, Manjunath Kondaiah 248f31cc962SG, Manjunath Kondaiah p->clear_lch_regs = NULL; 249f31cc962SG, Manjunath Kondaiah 250f31cc962SG, Manjunath Kondaiah p->errata = configure_dma_errata(); 251f31cc962SG, Manjunath Kondaiah 252c1d1cd59SPaul Walmsley pdev = omap_device_build(name, 0, oh, p, sizeof(*p)); 25359de3cf1SG, Manjunath Kondaiah kfree(p); 2543528c58eSKevin Hilman if (IS_ERR(pdev)) { 25525985edcSLucas De Marchi pr_err("%s: Can't build omap_device for %s:%s.\n", 25659de3cf1SG, Manjunath Kondaiah __func__, name, oh->name); 2573528c58eSKevin Hilman return PTR_ERR(pdev); 25859de3cf1SG, Manjunath Kondaiah } 25959de3cf1SG, Manjunath Kondaiah 2603528c58eSKevin Hilman mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 261f31cc962SG, Manjunath Kondaiah if (!mem) { 2623528c58eSKevin Hilman dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 263f31cc962SG, Manjunath Kondaiah return -EINVAL; 264f31cc962SG, Manjunath Kondaiah } 265f31cc962SG, Manjunath Kondaiah dma_base = ioremap(mem->start, resource_size(mem)); 266f31cc962SG, Manjunath Kondaiah if (!dma_base) { 2673528c58eSKevin Hilman dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 268f31cc962SG, Manjunath Kondaiah return -ENOMEM; 269f31cc962SG, Manjunath Kondaiah } 270f31cc962SG, Manjunath Kondaiah 271f31cc962SG, Manjunath Kondaiah d = oh->dev_attr; 272f31cc962SG, Manjunath Kondaiah d->chan = kzalloc(sizeof(struct omap_dma_lch) * 273f31cc962SG, Manjunath Kondaiah (d->lch_count), GFP_KERNEL); 274f31cc962SG, Manjunath Kondaiah 275f31cc962SG, Manjunath Kondaiah if (!d->chan) { 2763528c58eSKevin Hilman dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__); 277f31cc962SG, Manjunath Kondaiah return -ENOMEM; 278f31cc962SG, Manjunath Kondaiah } 279f6d5e079SR Sricharan 28082809601STony Lindgren if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 28182809601STony Lindgren d->dev_caps |= HS_CHANNELS_RESERVED; 28282809601STony Lindgren 283f6d5e079SR Sricharan /* Check the capabilities register for descriptor loading feature */ 284f6d5e079SR Sricharan if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS) 285f6d5e079SR Sricharan dma_common_ch_end = CCDN; 286f6d5e079SR Sricharan else 287f6d5e079SR Sricharan dma_common_ch_end = CCFN; 288f6d5e079SR Sricharan 28959de3cf1SG, Manjunath Kondaiah return 0; 29059de3cf1SG, Manjunath Kondaiah } 29159de3cf1SG, Manjunath Kondaiah 292be1f9481STony Lindgren static const struct platform_device_info omap_dma_dev_info = { 293be1f9481STony Lindgren .name = "omap-dma-engine", 294be1f9481STony Lindgren .id = -1, 295be1f9481STony Lindgren .dma_mask = DMA_BIT_MASK(32), 296be1f9481STony Lindgren }; 297be1f9481STony Lindgren 29859de3cf1SG, Manjunath Kondaiah static int __init omap2_system_dma_init(void) 29959de3cf1SG, Manjunath Kondaiah { 300be1f9481STony Lindgren struct platform_device *pdev; 301be1f9481STony Lindgren int res; 302be1f9481STony Lindgren 303be1f9481STony Lindgren res = omap_hwmod_for_each_by_class("dma", 30459de3cf1SG, Manjunath Kondaiah omap2_system_dma_init_dev, NULL); 305be1f9481STony Lindgren if (res) 306be1f9481STony Lindgren return res; 307be1f9481STony Lindgren 3088d30662aSJon Hunter if (of_have_populated_dt()) 3098d30662aSJon Hunter return res; 3108d30662aSJon Hunter 311be1f9481STony Lindgren pdev = platform_device_register_full(&omap_dma_dev_info); 312be1f9481STony Lindgren if (IS_ERR(pdev)) 313be1f9481STony Lindgren return PTR_ERR(pdev); 314be1f9481STony Lindgren 315be1f9481STony Lindgren return res; 31659de3cf1SG, Manjunath Kondaiah } 317b76c8b19STony Lindgren omap_arch_initcall(omap2_system_dma_init); 318