@@ -2024,6 +2024,31 @@ void omap_dma_global_context_restore(void)
/*----------------------------------------------------------------------------*/
+/**
+ * omap_dma_reset() - perform software reset for the DMA controller
+ */
+static void omap_dma_reset(void)
+{
+ u32 v;
+
+ if (cpu_class_is_omap1())
+ return;
+
+ v = dma_read(OCP_SYSCONFIG);
+ v |= 0x2; /* software reset */
+ dma_write(v, OCP_SYSCONFIG);
+
+ /* wait until reset is complete */
+ while ((dma_read(SYSSTATUS) & 0x1) == 0)
+ cpu_relax();
+
+ /* disable per channel interrupts */
+ dma_write(0, IRQENABLE_L0);
+ dma_write(0, IRQENABLE_L1);
+ dma_write(0, IRQENABLE_L2);
+ dma_write(0, IRQENABLE_L3);
+}
+
static int __init omap_init_dma(void)
{
unsigned long base;
@@ -2069,6 +2094,13 @@ static int __init omap_init_dma(void)
}
}
+ /*
+ * Make sure that DMA is in reset state before doing anything else. If
+ * we are coming from softboot (e.g kexec) DMA is probably configured so
+ * we explicitly reset it here to get into known state.
+ */
+ omap_dma_reset();
+
if (cpu_is_omap15xx()) {
printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
dma_chan_count = 9;
@@ -134,6 +134,10 @@
#define OMAP1_DMA_REVISION 0
#define OMAP1_DMA_IRQSTATUS_L0 0
#define OMAP1_DMA_IRQENABLE_L0 0
+#define OMAP1_DMA_IRQENABLE_L1 0
+#define OMAP1_DMA_IRQENABLE_L2 0
+#define OMAP1_DMA_IRQENABLE_L3 0
+#define OMAP1_DMA_SYSSTATUS 0
#define OMAP1_DMA_OCP_SYSCONFIG 0
#define OMAP_DMA4_HW_ID 0
#define OMAP_DMA4_CAPS_0_L 0