diff -urN -X ../dontdiff linux-2.6.11-rc5/arch/arm/mach-s3c2410/Kconfig linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/Kconfig
--- linux-2.6.11-rc5/arch/arm/mach-s3c2410/Kconfig	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/Kconfig	2005-03-03 15:03:21.000000000 +0000
@@ -5,6 +5,7 @@
 config ARCH_BAST
 	bool "Simtec Electronics BAST (EB2410ITX)"
 	select CPU_S3C2410
+	select SIMTEC_AUDIO
 	help
 	  Say Y here if you are using the Simtec Electronics EB2410ITX
 	  development board (also known as BAST)
@@ -29,6 +30,7 @@
 config MACH_VR1000
 	bool "Thorcom VR1000"
 	select CPU_S3C2410
+	select SIMTEC_AUDIO
 	help
 	  Say Y here if you are using the Thorcom VR1000 board.
 
@@ -46,6 +48,12 @@
 
 endmenu
 
+config SIMTEC_AUDIO
+	bool "Simtec Audio support"
+	depends on ARCH_BAST || MACH_VR1000
+	help
+	  Say y here for the base Simtec audio support.
+
 config CPU_S3C2410
 	bool
 	depends on ARCH_S3C2410
@@ -69,6 +77,12 @@
 	  use the S3C2410's DMA system to move data to and from the
 	  peripheral blocks.
 
+config S3C2410_DMA_SYSFS
+	bool "S3C2410 DMA sysfs export"
+	depends on S3C2410_DMA
+	help
+	  Export DMA channel state via the sysfs interface.
+
 config S3C2410_DMA_DEBUG
 	bool "S3C2410 DMA support debug"
 	depends on ARCH_S3C2410 && S3C2410_DMA
diff -urN -X ../dontdiff linux-2.6.11-rc5/arch/arm/mach-s3c2410/Makefile linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/Makefile
--- linux-2.6.11-rc5/arch/arm/mach-s3c2410/Makefile	2005-01-04 10:57:48.000000000 +0000
+++ linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/Makefile	2005-03-03 15:03:44.000000000 +0000
@@ -14,6 +14,7 @@
 
 obj-$(CONFIG_CPU_S3C2410)  += s3c2410.o
 obj-$(CONFIG_S3C2410_DMA)  += dma.o
+obj-$(CONFIG_S3C2410_DMA_SYSFS)  += dma-sysfs.o
 
 # Power Management support
 
@@ -30,3 +31,5 @@
 obj-$(CONFIG_ARCH_SMDK2410)	+= mach-smdk2410.o
 obj-$(CONFIG_MACH_VR1000)	+= mach-vr1000.o usb-simtec.o
 obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
+
+obj-$(CONFIG_SIMTEC_AUDIO)	+= audio-simtec.o
\ No newline at end of file
diff -urN -X ../dontdiff linux-2.6.11-rc5/arch/arm/mach-s3c2410/audio-simtec.c linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/audio-simtec.c
--- linux-2.6.11-rc5/arch/arm/mach-s3c2410/audio-simtec.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/audio-simtec.c	2005-03-15 11:28:48.000000000 +0000
@@ -0,0 +1,138 @@
+/* linux/arch/arm/mach-s3c2410/audio-simtec.c
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/bast-map.h>
+#include <asm/arch/bast-irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/hardware/clock.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/audio.h>
+
+#include "devs.h"
+#include "pm.h"
+
+/* platform ops for audio */
+
+static int simtec_audio_startup(struct s3c24xx_iis_ops *ops)
+{
+	unsigned int tmp;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+        tmp = __raw_readb(BAST_VA_CTRL1);
+        tmp &= ~BAST_CPLD_CTRL1_LRMASK;
+        tmp |= BAST_CPLD_CTRL1_LRCDAC;
+        __raw_writeb(tmp, BAST_VA_CTRL1);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void simtec_audio_shutdown(struct s3c24xx_iis_ops *ops)
+{
+	unsigned int tmp;
+	unsigned long flags;
+
+	/* switch off LR clock routing */
+
+	local_irq_save(flags);
+
+	tmp = __raw_readb(BAST_VA_CTRL1);
+	tmp &= ~BAST_CPLD_CTRL1_LRMASK;
+	tmp |= BAST_CPLD_CTRL1_LRCOFF;
+	__raw_writeb(tmp, BAST_VA_CTRL1);
+
+	local_irq_restore(flags);
+}
+
+static int simtec_audio_matchdev(struct device *dev)
+{
+	printk(KERN_INFO "%s: dev=%p\n", __FUNCTION__, dev);
+
+	if (dev->parent == NULL || dev->parent->parent == NULL)
+		return 0;
+
+	printk("%s: parent %s\n", __FUNCTION__, dev->parent->bus_id);
+	printk("%s: parent2 %s\n", __FUNCTION__, dev->parent->parent->bus_id);
+
+	if (strncmp(dev->parent->bus_id, "i2c", strlen("i2c")) != 0)
+		return 0;
+
+	if (strncmp(dev->parent->parent->bus_id, "s3c24",
+		    strlen("s3c24")) == 0)
+		return 1;
+
+	return 0;
+}
+
+/* device registration info */
+
+static struct s3c24xx_iis_ops simtec_audio_ops = {
+	.startup	= simtec_audio_startup,
+	.shutdown	= simtec_audio_shutdown,
+};
+
+static struct s3c24xx_platdata_iis simtec_audio_platdata = {
+	.ops		= &simtec_audio_ops,
+	.codec_clk	= "clkout0",
+	.match_dev	= simtec_audio_matchdev,
+};
+
+static struct platform_device audio_dev = {
+	.name	= "s3c24xx-tlv320aic23",
+	.dev	= {
+		.parent		= &s3c_device_iis.dev,
+		.platform_data	= &simtec_audio_platdata,
+	},
+};
+
+static int __init simtec_audio_init(void)
+{
+	if (!machine_is_bast() && !machine_is_vr1000()) 
+		return 0;
+
+	printk(KERN_INFO "Simtec TLV320AIC23 Audio platform driver\n");
+
+	simtec_audio_shutdown(NULL);
+
+	platform_device_register(&s3c_device_iis);
+	return platform_device_register(&audio_dev);
+}
+
+device_initcall(simtec_audio_init);
diff -urN -X ../dontdiff linux-2.6.11-rc5/arch/arm/mach-s3c2410/dma-sysfs.c linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/dma-sysfs.c
--- linux-2.6.11-rc5/arch/arm/mach-s3c2410/dma-sysfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/dma-sysfs.c	2005-03-03 16:05:50.000000000 +0000
@@ -0,0 +1,276 @@
+/* linux/arch/arm/mach-bast/dma-sysfs.c
+ *
+ * (c) 2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA core sysfs interface
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/config.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <asm/mach/dma.h>
+#include <asm/arch/map.h>
+
+
+extern struct sysdev_class dma_sysclass;
+extern s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
+
+
+static const char *s3c2410_dma_decode_state(s3c2410_dma_state_t state)
+{
+	switch (state) {
+	case S3C2410_DMA_IDLE:
+		return "Idle";
+	case S3C2410_DMA_RUNNING:
+		return "Running";
+	case S3C2410_DMA_PAUSED:
+		return "Paused";
+	default:
+		return "Invalid";
+	}
+
+	return NULL;
+}
+
+static const char *s3c2410_dma_decode_loadstate(s3c2410_dma_loadst_t state)
+{
+	switch (state) {
+	case S3C2410_DMALOAD_NONE:
+		return "Nothing Loaded";
+	case S3C2410_DMALOAD_1LOADED:
+		return "1 Loaded";
+	case S3C2410_DMALOAD_1RUNNING:
+		return "1 Running";
+	case S3C2410_DMALOAD_1LOADED_1RUNNING:
+		return "1 Loaded, 1 Running";
+	default:
+		return "Invalid Load State";
+	}
+
+	return NULL;
+}
+
+static const char *s3c2410_dma_decode_source(s3c2410_dmasrc_t source)
+{
+	switch (source) {
+	case S3C2410_DMASRC_HW:
+		return "Hardware";
+	case S3C2410_DMASRC_MEM:
+		return "Memory";
+	default:
+		return "Unknown Source";
+	}
+
+	return NULL;
+}
+
+
+struct outbuff {
+	char		*buff;
+	int		 offset;
+	int		 size;
+};
+
+static inline void outbuf_init(struct outbuff *ob, char *buf, int size)
+{
+	ob->buff   = buf;
+	ob->offset = 0;
+	ob->size   = size;
+}
+
+static void outbuf_pf(struct outbuff *ob, const char *fmt, ...)
+{
+	va_list va;
+
+	va_start(va, fmt);
+
+	ob->offset += vsnprintf(ob->buff + ob->offset,
+				ob->size - ob->offset,
+				fmt, va);
+	va_end(va);
+}
+
+static void dma_sysfs_showregs(s3c2410_dma_chan_t *chan, struct outbuff *buf)
+{
+	outbuf_pf(buf, "Hardware Registers:\n\n");
+
+	outbuf_pf(buf, "  DISRC \t\t\t%08lx\n",  readl(chan->regs + 0x00));
+	outbuf_pf(buf, "  DISRCC\t\t\t%08lx\n", readl(chan->regs + 0x04));
+	outbuf_pf(buf, "  DIDST \t\t\t%08lx\n",  readl(chan->regs + 0x08));
+	outbuf_pf(buf, "  DIDSTC\t\t\t%08lx\n", readl(chan->regs + 0x0C));
+	outbuf_pf(buf, "  DCON  \t\t\t%08lx\n", readl(chan->regs + 0x10));
+	outbuf_pf(buf, "  DSTAT \t\t\t%08lx\n", readl(chan->regs + 0x14));
+	outbuf_pf(buf, "  DCSRC \t\t\t%08lx\n", readl(chan->regs + 0x18));
+	outbuf_pf(buf, "  DCDST \t\t\t%08lx\n", readl(chan->regs + 0x1c));
+	outbuf_pf(buf, "  DMTRG \t\t\t%08lx\n", readl(chan->regs + 0x20));
+}
+
+static void dma_sysfs_showbuf(s3c2410_dma_chan_t *chan,
+			      struct outbuff *buf,
+			      s3c2410_dma_buf_t *ptr)
+{
+	if (ptr == NULL)
+		return;
+
+	outbuf_pf(buf, "  buff %p: data=%08x, size=%08x, id=%08x\n",
+		  ptr, ptr->data, ptr->size, ptr->id);
+}
+
+static void dma_sysfs_showbuffers(s3c2410_dma_chan_t *chan, struct outbuff *buf)
+{
+	s3c2410_dma_buf_t *ptr = chan->next;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	outbuf_pf(buf, "Current Buffer:\n");
+	dma_sysfs_showbuf(chan, buf, chan->curr);
+
+	outbuf_pf(buf, "\nBuffer Queue: %p -> %p\n", chan->next, chan->end);
+
+	for (; ptr != NULL; ptr = ptr->next)
+		dma_sysfs_showbuf(chan, buf, ptr);
+
+	local_irq_restore(flags);
+}
+
+static void dma_sysfs_showstate(s3c2410_dma_chan_t *chan, struct outbuff *buf)
+{
+	outbuf_pf(buf, "IRQ:\t\t\t\t%d\n", chan->irq);
+	outbuf_pf(buf, "Register Base:\t\t\t0x%08x\n", chan->regs);
+	outbuf_pf(buf, "Address Register:\t\t0x%08lx\n", chan->addr_reg);
+	outbuf_pf(buf, "Hardware Register:\t\t0x%08lx\n", chan->dev_addr);
+	outbuf_pf(buf, "Load Timeout:\t\t\t0x%08x\n", chan->load_timeout);
+	outbuf_pf(buf, "Data Source:\t\t\t%s\n", 
+		     s3c2410_dma_decode_source(chan->source));
+
+	outbuf_pf(buf, "Channel State:\t\t\t%s (%d)\n",
+		     s3c2410_dma_decode_state(chan->state), chan->state);
+	outbuf_pf(buf, "Load State:\t\t\t%s (%d)\n", 
+		     s3c2410_dma_decode_loadstate(chan->load_state), 
+		     chan->load_state);
+
+	if (chan->client != NULL) {
+		outbuf_pf(buf, "Claimed by:\t\t\t%s\n",
+			     chan->client->name);
+	} else {
+		outbuf_pf(buf, "Claimed by:\t\t\tNo-one\n");
+	}
+}
+
+static inline s3c2410_dma_chan_t *dev_to_chan(struct sys_device *dev)
+{
+	return &s3c2410_chans[dev->id];
+}
+
+static ssize_t dma_sysfs_show_regs(struct sys_device *dev, char *buf)
+{
+	s3c2410_dma_chan_t *cp = dev_to_chan(dev);
+	struct outbuff buff;
+	
+	outbuf_init(&buff, buf, PAGE_SIZE);
+	dma_sysfs_showregs(cp, &buff);	
+
+	return buff.offset;
+}
+
+static ssize_t dma_sysfs_show_state(struct sys_device *dev, char *buf)
+{
+	s3c2410_dma_chan_t *cp = dev_to_chan(dev);
+	struct outbuff buff;
+	
+	outbuf_init(&buff, buf, PAGE_SIZE);
+	dma_sysfs_showstate(cp, &buff);
+
+	return buff.offset;
+}
+
+static ssize_t dma_sysfs_show_buffers(struct sys_device *dev, char *buf)
+{
+	s3c2410_dma_chan_t *cp = dev_to_chan(dev);
+	struct outbuff buff;
+	
+	outbuf_init(&buff, buf, PAGE_SIZE);
+	dma_sysfs_showbuffers(cp, &buff);
+
+	return buff.offset;
+}
+
+static ssize_t dma_sysfs_show_all(struct sys_device *dev, char *buf)
+{
+	s3c2410_dma_chan_t *cp = dev_to_chan(dev);
+	struct outbuff buff;
+
+	outbuf_init(&buff, buf, PAGE_SIZE);
+
+	dma_sysfs_showstate(cp, &buff);
+	dma_sysfs_showregs(cp, &buff);	
+	dma_sysfs_showbuffers(cp, &buff);
+
+	return buff.offset;
+}
+
+static SYSDEV_ATTR(all, S_IRUGO, dma_sysfs_show_all, NULL);
+static SYSDEV_ATTR(regs, S_IRUGO, dma_sysfs_show_regs, NULL);
+static SYSDEV_ATTR(state, S_IRUGO, dma_sysfs_show_state, NULL);
+static SYSDEV_ATTR(buffers, S_IRUGO, dma_sysfs_show_buffers, NULL);
+
+static struct sysdev_attribute *attrs[] = {
+	&attr_all,
+	&attr_regs,
+	&attr_state,
+	&attr_buffers,
+};
+
+static int dma_sysfs_attach(struct sys_device *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(attrs); i++)
+		sysdev_create_file(dev, attrs[i]);
+	
+	return 0;
+}
+
+static int dma_sysfs_remove(struct sys_device *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(attrs); i++)
+		sysdev_create_file(dev, attrs[i]);
+	
+	return 0;
+}
+
+static struct sysdev_driver dma_sysfs_driver = {
+	.add	= dma_sysfs_attach,
+	.remove	= dma_sysfs_remove,
+};
+
+static int __init s3c2410_init_dma_sysfs(void)
+{
+	printk("S3C24XX DMA sysfs support, (c) 2005 Simtec Electronics\n");
+
+	return sysdev_driver_register(&dma_sysclass, &dma_sysfs_driver);
+}
+
+__initcall(s3c2410_init_dma_sysfs);
diff -urN -X ../dontdiff linux-2.6.11-rc5/arch/arm/mach-s3c2410/dma.c linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/dma.c
--- linux-2.6.11-rc5/arch/arm/mach-s3c2410/dma.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/dma.c	2005-03-08 17:23:46.000000000 +0000
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-bast/dma.c
  *
- * (c) 2003,2004 Simtec Electronics
+ * (c) 2003-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 DMA core
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  *
  * Changelog:
+ *  27-Feb-2005 BJD  Added kmem cache for dma descriptors
  *  18-Nov-2004 BJD  Removed error for loading onto stopped channel
  *  10-Nov-2004 BJD  Ensure all external symbols exported for modules
  *  10-Nov-2004 BJD  Use sys_device and sysdev_class for power management
@@ -57,6 +58,7 @@
 
 /* io map for dma */
 static void __iomem *dma_base;
+static kmem_cache_t *dma_kmem;
 
 /* dma channel state information */
 s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS];
@@ -190,6 +192,15 @@
 		if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
 			took = chan->load_timeout - timeout;
 
+			if (0) {
+				unsigned long a = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+				unsigned long b = dma_rdreg(chan, S3C2410_DMA_DISRC);
+
+				if (a != b && (a-b) > 0x0c) {
+					printk(KERN_DEBUG "DCSRC[%lx] != DISRC[%lx]\n", a, b);
+				}
+			}
+
 			s3c2410_dma_stats_timeout(chan->stats, took);
 
 			switch (chan->load_state) {
@@ -364,14 +375,7 @@
 
 	/* start the channel going */
 
-	tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-	tmp &= ~S3C2410_DMASKTRIG_STOP;
-	tmp |= S3C2410_DMASKTRIG_ON;
-	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-	pr_debug("wrote %08lx to DMASKTRIG\n", tmp);
-
-#if 0
+#if 1
 	/* the dma buffer loads should take care of clearing the AUTO
 	 * reloading feature */
 	tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
@@ -379,6 +383,13 @@
 	dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
 #endif
 
+	tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+	tmp &= ~S3C2410_DMASKTRIG_STOP;
+	tmp |= S3C2410_DMASKTRIG_ON;
+	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+	pr_debug("wrote %08lx to DMASKTRIG\n", tmp);
+
 	s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
 
 	dbg_showchan(chan);
@@ -432,10 +443,9 @@
 	pr_debug("%s: id=%p, data=%08x, size=%d\n",
 		 __FUNCTION__, id, (unsigned int)data, size);
 
-	buf = (s3c2410_dma_buf_t *)kmalloc(sizeof(*buf), GFP_ATOMIC);
+	buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
 	if (buf == NULL) {
-		pr_debug("%s: out of memory (%d alloc)\n",
-			 __FUNCTION__, sizeof(*buf));
+		printk(KERN_ERR "dma<%d> no memory for buffer\n", channel);
 		return -ENOMEM;
 	}
 
@@ -494,6 +504,8 @@
 	} else if (chan->state == S3C2410_DMA_IDLE) {
 		if (chan->flags & S3C2410_DMAF_AUTOSTART) {
 			s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
+		} else {
+			printk(KERN_DEBUG "loading onto stopped channel\n");
 		}
 	}
 
@@ -511,7 +523,7 @@
 	buf->magic = -1;
 
 	if (magicok) {
-		kfree(buf);
+		kmem_cache_free(dma_kmem, buf);
 	} else {
 		printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
 	}
@@ -764,7 +776,6 @@
 
 	local_irq_save(flags);
 
-
 	if (chan->client != client) {
 		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
 		       channel, chan->client, client);
@@ -807,7 +818,7 @@
 	tmp |= S3C2410_DMASKTRIG_STOP;
 	dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
 
-#if 0
+#if 1
 	/* should also clear interrupts, according to WinCE BSP */
 	tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
 	tmp |= S3C2410_DCON_NORELOAD;
@@ -822,6 +833,20 @@
 	return 0;
 }
 
+static void s3c2410_dma_showchan(s3c2410_dma_chan_t *chan)
+{
+	printk(KERN_DEBUG "dma[%d]: st %d, lst %d, cli %p, dcon %08lx\n",
+	       chan->number, chan->state,
+	       chan->load_state, chan->client, chan->dcon);
+	printk(KERN_DEBUG "dma[%d]: CSRC=%x, ISRC=%x, STAT=%x, CON=%x, MT=%x\n",
+	       chan->number,
+	       dma_rdreg(chan, S3C2410_DMA_DCSRC),
+	       dma_rdreg(chan, S3C2410_DMA_DISRC),
+	       dma_rdreg(chan, S3C2410_DMA_DSTAT),
+	       dma_rdreg(chan, S3C2410_DMA_DCON),
+	       dma_rdreg(chan, S3C2410_DMA_DMASKTRIG));
+}
+
 /* s3c2410_dma_flush
  *
  * stop the channel, and remove all current and pending transfers
@@ -836,6 +861,8 @@
 
 	local_irq_save(flags);
 
+	s3c2410_dma_showchan(chan);
+
 	if (chan->state != S3C2410_DMA_IDLE) {
 		pr_debug("%s: stopping channel...\n", __FUNCTION__ );
 		s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
@@ -846,7 +873,8 @@
 		buf = chan->next;
 
 	chan->curr = chan->next = chan->end = NULL;
-
+	chan->load_state = S3C2410_DMALOAD_NONE;
+  
 	if (buf != NULL) {
 		for ( ; buf != NULL; buf = next) {
 			next = buf->next;
@@ -859,6 +887,8 @@
 		}
 	}
 
+	s3c2410_dma_showchan(chan);
+
 	local_irq_restore(flags);
 
 	return 0;
@@ -1122,12 +1152,20 @@
 #define s3c2410_dma_resume  NULL
 #endif /* CONFIG_PM */
 
-static struct sysdev_class dma_sysclass = {
+struct sysdev_class dma_sysclass = {
 	set_kset_name("s3c24xx-dma"),
 	.suspend	= s3c2410_dma_suspend,
 	.resume		= s3c2410_dma_resume,
 };
 
+/* kmem cache implementation */
+
+static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
+{
+	memset(p, 0, sizeof(s3c2410_dma_buf_t));
+}
+	
+
 /* initialisation code */
 
 static int __init s3c2410_init_dma(void)
@@ -1150,6 +1188,16 @@
 		goto err;
 	}
 
+	dma_kmem = kmem_cache_create("dma_desc", sizeof(s3c2410_dma_buf_t), 0,
+				     SLAB_HWCACHE_ALIGN,
+				     s3c2410_dma_cache_ctor, NULL);
+
+	if (dma_kmem == NULL) {
+		printk(KERN_ERR "dma failed to make kmem cache\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
 		cp = &s3c2410_chans[channel];
 
@@ -1181,6 +1229,7 @@
 	return 0;
 
  err:
+	kmem_cache_destroy(dma_kmem);
 	iounmap(dma_base);
 	dma_base = NULL;
 	return ret;
diff -urN -X ../dontdiff linux-2.6.11-rc5/arch/arm/mach-s3c2410/mach-bast.c linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/mach-bast.c
--- linux-2.6.11-rc5/arch/arm/mach-s3c2410/mach-bast.c	2005-02-25 11:14:06.000000000 +0000
+++ linux-2.6.11-rc5-audio9/arch/arm/mach-s3c2410/mach-bast.c	2005-03-15 12:49:40.000000000 +0000
@@ -39,6 +39,7 @@
 
 #include <asm/arch/bast-map.h>
 #include <asm/arch/bast-irq.h>
+#include <asm/arch/bast-cpld.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -320,7 +321,6 @@
 	.select_chip	= bast_nand_select,
 };
 
-
 /* Standard BAST devices */
 
 static struct platform_device *bast_devices[] __initdata = {
@@ -328,7 +328,6 @@
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
-	&s3c_device_iis,
  	&s3c_device_rtc,
 	&s3c_device_nand,
 	&bast_device_nor

