[PATCH] CRIS update: new subarchitecture v32

New CRIS sub architecture named v32.

From: Dave Jones <davej@redhat.com>

	Fix swapped kmalloc args

Signed-off-by: Mikael Starvik <starvik@axis.com>
Signed-off-by: Dave Jones <davej@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/cris/arch-v32/kernel/dma.c b/arch/cris/arch-v32/kernel/dma.c
new file mode 100644
index 0000000..b92e857
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/dma.c
@@ -0,0 +1,224 @@
+/* Wrapper for DMA channel allocator that starts clocks etc */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <asm/dma.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/marb_defs.h>
+#include <asm/arch/hwregs/config_defs.h>
+#include <asm/arch/hwregs/strmux_defs.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <asm/arch/arbiter.h>
+
+static char used_dma_channels[MAX_DMA_CHANNELS];
+static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
+
+static DEFINE_SPINLOCK(dma_lock);
+
+int crisv32_request_dma(unsigned int dmanr, const char * device_id,
+                        unsigned options, unsigned int bandwidth,
+			enum dma_owner owner)
+{
+	unsigned long flags;
+	reg_config_rw_clk_ctrl clk_ctrl;
+	reg_strmux_rw_cfg strmux_cfg;
+
+        if (crisv32_arbiter_allocate_bandwith(dmanr,
+                                              options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
+                                              bandwidth))
+          return -ENOMEM;
+
+	spin_lock_irqsave(&dma_lock, flags);
+
+	if (used_dma_channels[dmanr]) {
+		spin_unlock_irqrestore(&dma_lock, flags);
+		if (options & DMA_VERBOSE_ON_ERROR) {
+			printk("Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]);
+		}
+		if (options & DMA_PANIC_ON_ERROR)
+			panic("request_dma error!");
+		return -EBUSY;
+	}
+	clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
+	strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
+
+	switch(dmanr)
+	{
+	case 0:
+	case 1:
+		clk_ctrl.dma01_eth0 = 1;
+		break;
+	case 2:
+	case 3:
+		clk_ctrl.dma23 = 1;
+		break;
+	case 4:
+	case 5:
+		clk_ctrl.dma45 = 1;
+		break;
+	case 6:
+	case 7:
+		clk_ctrl.dma67 = 1;
+		break;
+	case 8:
+	case 9:
+		clk_ctrl.dma89_strcop = 1;
+		break;
+#if MAX_DMA_CHANNELS-1 != 9
+#error Check dma.c
+#endif
+	default:
+		spin_unlock_irqrestore(&dma_lock, flags);
+		if (options & DMA_VERBOSE_ON_ERROR) {
+			printk("Failed to request DMA %i for %s, only 0-%i valid)\n", dmanr, device_id, MAX_DMA_CHANNELS-1);
+		}
+
+		if (options & DMA_PANIC_ON_ERROR)
+			panic("request_dma error!");
+		return -EINVAL;
+	}
+
+	switch(owner)
+	{
+	case dma_eth0:
+		if (dmanr == 0)
+			strmux_cfg.dma0 = regk_strmux_eth0;
+		else if (dmanr == 1)
+			strmux_cfg.dma1 = regk_strmux_eth0;
+		else
+			panic("Invalid DMA channel for eth0\n");
+		break;
+	case dma_eth1:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_eth1;
+		else if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_eth1;
+		else
+			panic("Invalid DMA channel for eth1\n");
+		break;
+	case dma_iop0:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_iop0;
+		else if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_iop0;
+		else
+			panic("Invalid DMA channel for iop0\n");
+		break;
+	case dma_iop1:
+		if (dmanr == 4)
+			strmux_cfg.dma4 = regk_strmux_iop1;
+		else if (dmanr == 5)
+			strmux_cfg.dma5 = regk_strmux_iop1;
+		else
+			panic("Invalid DMA channel for iop1\n");
+		break;
+	case dma_ser0:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_ser0;
+		else if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_ser0;
+		else
+			panic("Invalid DMA channel for ser0\n");
+		break;
+	case dma_ser1:
+		if (dmanr == 4)
+			strmux_cfg.dma4 = regk_strmux_ser1;
+		else if (dmanr == 5)
+			strmux_cfg.dma5 = regk_strmux_ser1;
+		else
+			panic("Invalid DMA channel for ser1\n");
+		break;
+	case dma_ser2:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_ser2;
+		else if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_ser2;
+		else
+			panic("Invalid DMA channel for ser2\n");
+		break;
+	case dma_ser3:
+		if (dmanr == 8)
+			strmux_cfg.dma8 = regk_strmux_ser3;
+		else if (dmanr == 9)
+			strmux_cfg.dma9 = regk_strmux_ser3;
+		else
+			panic("Invalid DMA channel for ser3\n");
+		break;
+	case dma_sser0:
+		if (dmanr == 4)
+			strmux_cfg.dma4 = regk_strmux_sser0;
+		else if (dmanr == 5)
+			strmux_cfg.dma5 = regk_strmux_sser0;
+		else
+			panic("Invalid DMA channel for sser0\n");
+		break;
+	case dma_sser1:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_sser1;
+		else if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_sser1;
+		else
+			panic("Invalid DMA channel for sser1\n");
+		break;
+	case dma_ata:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_ata;
+		else if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_ata;
+		else
+			panic("Invalid DMA channel for ata\n");
+		break;
+	case dma_strp:
+		if (dmanr == 8)
+			strmux_cfg.dma8 = regk_strmux_strcop;
+		else if (dmanr == 9)
+			strmux_cfg.dma9 = regk_strmux_strcop;
+		else
+			panic("Invalid DMA channel for strp\n");
+		break;
+	case dma_ext0:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_ext0;
+		else
+			panic("Invalid DMA channel for ext0\n");
+		break;
+	case dma_ext1:
+		if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_ext1;
+		else
+			panic("Invalid DMA channel for ext1\n");
+		break;
+	case dma_ext2:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_ext2;
+		else if (dmanr == 8)
+			strmux_cfg.dma8 = regk_strmux_ext2;
+		else
+			panic("Invalid DMA channel for ext2\n");
+		break;
+	case dma_ext3:
+		if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_ext3;
+		else if (dmanr == 9)
+			strmux_cfg.dma9 = regk_strmux_ext2;
+		else
+			panic("Invalid DMA channel for ext2\n");
+		break;
+	}
+
+	used_dma_channels[dmanr] = 1;
+	used_dma_channels_users[dmanr] = device_id;
+	REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
+	REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
+	spin_unlock_irqrestore(&dma_lock,flags);
+	return 0;
+}
+
+void crisv32_free_dma(unsigned int dmanr)
+{
+	spin_lock(&dma_lock);
+	used_dma_channels[dmanr] = 0;
+	spin_unlock(&dma_lock);
+}